diff options
Diffstat (limited to '')
-rw-r--r-- | sys-utils/tunelp.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/sys-utils/tunelp.c b/sys-utils/tunelp.c new file mode 100644 index 0000000..fe261f3 --- /dev/null +++ b/sys-utils/tunelp.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 1992-1997 Michael K. Johnson, johnsonm@redhat.com + * + * This file is licensed under the terms of the GNU General Public + * License, version 2, or any later version. See file COPYING for + * information on distribution conditions. + */ + +/* + * This command is deprecated. The utility is in maintenance mode, + * meaning we keep them in source tree for backward compatibility + * only. Do not waste time making this command better, unless the + * fix is about security or other very critical issue. + * + * See Documentation/deprecated.txt for more information. + */ + +/* + * $Log: tunelp.c,v $ + * Revision 1.9 1998/06/08 19:37:11 janl + * Thus compiles tunelp with 2.1.103 kernels + * + * Revision 1.8 1997/07/06 00:14:06 aebr + * Fixes to silence -Wall. + * + * Revision 1.7 1997/06/20 16:10:38 janl + * tunelp refreshed from authors archive. + * + * Revision 1.9 1997/06/20 12:56:43 johnsonm + * Finished fixing license terms. + * + * Revision 1.8 1997/06/20 12:34:59 johnsonm + * Fixed copyright and license. + * + * Revision 1.7 1995/03/29 11:16:23 johnsonm + * TYPO fixed... + * + * Revision 1.6 1995/03/29 11:12:15 johnsonm + * Added third argument to ioctl needed with new kernels + * + * Revision 1.5 1995/01/13 10:33:43 johnsonm + * Chris's changes for new ioctl numbers and backwards compatibility + * and the reset ioctl. + * + * Revision 1.4 1995/01/03 17:42:14 johnsonm + * -s isn't supposed to take an argument; removed : after s in getopt... + * + * Revision 1.3 1995/01/03 07:36:49 johnsonm + * Fixed typo + * + * Revision 1.2 1995/01/03 07:33:44 johnsonm + * revisions for lp driver updates in Linux 1.1.76 + * + * 1999-02-22 Arkadiusz MiĆkiewicz <misiek@pld.ORG.PL> + * - added Native Language Support + * + * 1999-05-07 Merged LPTRUSTIRQ patch by Andrea Arcangeli (1998/11/29), aeb + * + */ + +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <linux/lp.h> + +#include "nls.h" +#include "closestream.h" +#include "strutils.h" + +#define EXIT_LP_MALLOC 2 +#define EXIT_LP_BADVAL 3 +#define EXIT_LP_IO_ERR 4 + +#define XALLOC_EXIT_CODE EXIT_LP_MALLOC +#include "xalloc.h" + +struct command { + long op; + long val; + struct command *next; +}; + +static void __attribute__((__noreturn__)) usage(void) +{ + FILE *out = stdout; + fputs(USAGE_HEADER, out); + fprintf(out, _(" %s [options] <device>\n"), program_invocation_short_name); + + fputs(USAGE_SEPARATOR, out); + fputs(_("Set various parameters for the line printer.\n"), out); + + fputs(USAGE_OPTIONS, out); + fputs(_(" -i, --irq <num> specify parallel port irq\n"), out); + fputs(_(" -t, --time <ms> driver wait time in milliseconds\n"), out); + fputs(_(" -c, --chars <num> number of output characters before sleep\n"), out); + fputs(_(" -w, --wait <us> strobe wait in micro seconds\n"), out); + /* TRANSLATORS: do not translate <on|off> arguments. The + argument reader does not recognize locale, unless `on' is + exactly that very same string. */ + fputs(_(" -a, --abort <on|off> abort on error\n"), out); + fputs(_(" -o, --check-status <on|off> check printer status before printing\n"), out); + fputs(_(" -C, --careful <on|off> extra checking to status check\n"), out); + fputs(_(" -s, --status query printer status\n"), out); + fputs(_(" -r, --reset reset the port\n"), out); + fputs(_(" -q, --print-irq <on|off> display current irq setting\n"), out); + fputs(USAGE_SEPARATOR, out); + printf(USAGE_HELP_OPTIONS(30)); + printf(USAGE_MAN_TAIL("tunelp(8)")); + + exit(EXIT_SUCCESS); +} + +int main(int argc, char **argv) +{ + int c, fd, irq, status, show_irq, offset = 0, retval; + char *filename; + struct stat statbuf; + struct command *cmds, *cmdst; + static const struct option longopts[] = { + {"irq", required_argument, NULL, 'i'}, + {"time", required_argument, NULL, 't'}, + {"chars", required_argument, NULL, 'c'}, + {"wait", required_argument, NULL, 'w'}, + {"abort", required_argument, NULL, 'a'}, + {"check-status", required_argument, NULL, 'o'}, + {"careful", required_argument, NULL, 'C'}, + {"status", no_argument, NULL, 's'}, + {"trust-irq", required_argument, NULL, 'T'}, + {"reset", no_argument, NULL, 'r'}, + {"print-irq", required_argument, NULL, 'q'}, + {"version", no_argument, NULL, 'V'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + atexit(close_stdout); + + strutils_set_exitcode(EXIT_LP_BADVAL); + + if (argc < 2) { + warnx(_("not enough arguments")); + errtryhelp(EXIT_FAILURE); + } + + cmdst = cmds = xmalloc(sizeof(struct command)); + cmds->next = NULL; + + show_irq = 1; + while ((c = getopt_long(argc, argv, "t:c:w:a:i:ho:C:sq:rT:vV", longopts, NULL)) != -1) { + switch (c) { + case 'h': + usage(); + break; + case 'i': + cmds->op = LPSETIRQ; + cmds->val = strtol_or_err(optarg, _("argument error")); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 't': + cmds->op = LPTIME; + cmds->val = strtol_or_err(optarg, _("argument error")); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'c': + cmds->op = LPCHAR; + cmds->val = strtol_or_err(optarg, _("argument error")); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'w': + cmds->op = LPWAIT; + cmds->val = strtol_or_err(optarg, _("argument error")); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'a': + cmds->op = LPABORT; + cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'q': + show_irq = parse_switch(optarg, _("argument error"), "on", "off", NULL); + break; + case 'o': + cmds->op = LPABORTOPEN; + cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'C': + cmds->op = LPCAREFUL; + cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL); + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 's': + show_irq = 0; + cmds->op = LPGETSTATUS; + cmds->val = 0; + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'r': + cmds->op = LPRESET; + cmds->val = 0; + cmds->next = xmalloc(sizeof(struct command)); + cmds = cmds->next; + cmds->next = NULL; + break; + case 'v': + case 'V': + printf(UTIL_LINUX_VERSION); + return EXIT_SUCCESS; + default: + errtryhelp(EXIT_FAILURE); + } + } + + if (optind != argc - 1) { + warnx(_("no device specified")); + errtryhelp(EXIT_FAILURE); + } + + filename = xstrdup(argv[optind]); + fd = open(filename, O_WRONLY | O_NONBLOCK, 0); + /* Need to open O_NONBLOCK in case ABORTOPEN is already set + * and printer is off or off-line or in an error condition. + * Otherwise we would abort... + */ + if (fd < 0) + err(EXIT_FAILURE, "%s", filename); + + if (fstat(fd, &statbuf)) + err(EXIT_FAILURE, "%s: stat() failed", filename); + + if (!S_ISCHR(statbuf.st_mode)) { + warnx(_("%s not an lp device"), filename); + errtryhelp(EXIT_FAILURE); + } + /* Allow for binaries compiled under a new kernel to work on + * the old ones The irq argument to ioctl isn't touched by + * the old kernels, but we don't want to cause the kernel to + * complain if we are using a new kernel + */ + if (LPGETIRQ >= 0x0600 && ioctl(fd, LPGETIRQ, &irq) < 0 + && errno == EINVAL) + /* We don't understand the new ioctls */ + offset = 0x0600; + + cmds = cmdst; + while (cmds->next) { + if (cmds->op == LPGETSTATUS) { + status = 0xdeadbeef; + retval = ioctl(fd, LPGETSTATUS - offset, &status); + if (retval < 0) + warnx(_("LPGETSTATUS error")); + else { + if (status == (int)0xdeadbeef) + /* a few 1.1.7x kernels will do this */ + status = retval; + printf(_("%s status is %d"), filename, status); + if (!(status & LP_PBUSY)) + printf(_(", busy")); + if (!(status & LP_PACK)) + printf(_(", ready")); + if ((status & LP_POUTPA)) + printf(_(", out of paper")); + if ((status & LP_PSELECD)) + printf(_(", on-line")); + if (!(status & LP_PERRORP)) + printf(_(", error")); + printf("\n"); + } + } else + if (ioctl(fd, cmds->op - offset, cmds->val) < 0) + warn(_("ioctl failed")); + cmdst = cmds; + cmds = cmds->next; + free(cmdst); + } + + if (show_irq) { + irq = 0xdeadbeef; + retval = ioctl(fd, LPGETIRQ - offset, &irq); + if (retval == -1) + err(EXIT_LP_IO_ERR, _("LPGETIRQ error")); + if (irq == (int)0xdeadbeef) + /* up to 1.1.77 will do this */ + irq = retval; + if (irq) + printf(_("%s using IRQ %d\n"), filename, irq); + else + printf(_("%s using polling\n"), filename); + } + free(filename); + close(fd); + + return EXIT_SUCCESS; +} |