* 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
* 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>
+ * 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 <malloc.h>
+#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
-#include "lp.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 {
struct command *next;
};
-static void print_usage(char *progname)
-{
- printf(_
- ("Usage: %s <device> [ -i <IRQ> | -t <TIME> | -c <CHARS> | -w <WAIT> | \n"
- " -a [on|off] | -o [on|off] | -C [on|off] | -q [on|off] | -s | \n"
- " -T [on|off] ]\n"), progname);
- exit(1);
-}
-
-static void print_version(char *progname)
+static void __attribute__((__noreturn__)) usage(void)
{
- printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
-}
+ FILE *out = stdout;
+ fputs(USAGE_HEADER, out);
+ fprintf(out, _(" %s [options] <device>\n"), program_invocation_short_name);
-static char *progname;
+ fputs(USAGE_SEPARATOR, out);
+ fputs(_("Set various parameters for the line printer.\n"), out);
-static long get_val(char *val)
-{
- long ret;
- if (!(sscanf(val, "%ld", &ret) == 1)) {
- fprintf(stderr, _("%s: bad value\n"), progname);
- exit(3);
- }
- return ret;
-}
+ 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)"));
-static long get_onoff(char *val)
-{
- if (!strncasecmp("on", val, 2))
- return 1;
- return 0;
+ exit(EXIT_SUCCESS);
}
int main(int argc, char **argv)
{
int c, fd, irq, status, show_irq, offset = 0, retval;
- char *filename, *p;
+ char *filename;
struct stat statbuf;
struct command *cmds, *cmdst;
-
- progname = argv[0];
- if ((p = strrchr(progname, '/')) != NULL)
- progname = p + 1;
+ 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);
+ close_stdout_atexit();
- if (argc < 2)
- print_usage(progname);
+ strutils_set_exitcode(EXIT_LP_BADVAL);
+
+ if (argc < 2) {
+ warnx(_("not enough arguments"));
+ errtryhelp(EXIT_FAILURE);
+ }
cmdst = cmds = xmalloc(sizeof(struct command));
- cmds->next = 0;
+ cmds->next = NULL;
show_irq = 1;
- while ((c = getopt(argc, argv, "t:c:w:a:i:ho:C:sq:rT:vV")) != -1) {
+ while ((c = getopt_long(argc, argv, "t:c:w:a:i:ho:C:sq:rT:vV", longopts, NULL)) != -1) {
switch (c) {
- case 'h':
- print_usage(progname);
- break;
case 'i':
cmds->op = LPSETIRQ;
- cmds->val = get_val(optarg);
+ cmds->val = strtol_or_err(optarg, _("argument error"));
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 't':
cmds->op = LPTIME;
- cmds->val = get_val(optarg);
+ cmds->val = strtol_or_err(optarg, _("argument error"));
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 'c':
cmds->op = LPCHAR;
- cmds->val = get_val(optarg);
+ cmds->val = strtol_or_err(optarg, _("argument error"));
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 'w':
cmds->op = LPWAIT;
- cmds->val = get_val(optarg);
+ cmds->val = strtol_or_err(optarg, _("argument error"));
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 'a':
cmds->op = LPABORT;
- cmds->val = get_onoff(optarg);
+ cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL);
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 'q':
- if (get_onoff(optarg)) {
- show_irq = 1;
- } else {
- show_irq = 0;
- }
-#ifdef LPGETSTATUS
+ show_irq = parse_switch(optarg, _("argument error"), "on", "off", NULL);
+ break;
case 'o':
cmds->op = LPABORTOPEN;
- cmds->val = get_onoff(optarg);
+ cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL);
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 'C':
cmds->op = LPCAREFUL;
- cmds->val = get_onoff(optarg);
+ cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL);
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
case 's':
show_irq = 0;
cmds->val = 0;
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
-#endif
-#ifdef LPRESET
case 'r':
cmds->op = LPRESET;
cmds->val = 0;
cmds->next = xmalloc(sizeof(struct command));
cmds = cmds->next;
- cmds->next = 0;
- break;
-#endif
-#ifdef LPTRUSTIRQ
- case 'T':
- /* Note: this will do the wrong thing on
- * 2.0.36 when compiled under 2.2.x
- */
- cmds->op = LPTRUSTIRQ;
- cmds->val = get_onoff(optarg);
- cmds->next = xmalloc(sizeof(struct command));
- cmds = cmds->next;
- cmds->next = 0;
+ cmds->next = NULL;
break;
-#endif
+
+ case 'h':
+ usage();
case 'v':
case 'V':
- print_version(progname);
- exit(0);
+ print_version(EXIT_SUCCESS);
default:
- print_usage(progname);
+ errtryhelp(EXIT_FAILURE);
}
}
- if (optind != argc - 1)
- print_usage(progname);
+ if (optind != argc - 1) {
+ warnx(_("no device specified"));
+ errtryhelp(EXIT_FAILURE);
+ }
- filename = strdup(argv[optind]);
+ 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) {
- perror(filename);
- return -1;
- }
+ if (fd < 0)
+ err(EXIT_FAILURE, "%s", filename);
- fstat(fd, &statbuf);
+ if (fstat(fd, &statbuf))
+ err(EXIT_FAILURE, "%s: stat() failed", filename);
if (!S_ISCHR(statbuf.st_mode)) {
- printf(_("%s: %s not an lp device.\n"), argv[0], filename);
- print_usage(progname);
+ 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
cmds = cmdst;
while (cmds->next) {
-#ifdef LPGETSTATUS
if (cmds->op == LPGETSTATUS) {
status = 0xdeadbeef;
retval = ioctl(fd, LPGETSTATUS - offset, &status);
if (retval < 0)
- perror(_("LPGETSTATUS error"));
+ warnx(_("LPGETSTATUS error"));
else {
if (status == (int)0xdeadbeef)
/* a few 1.1.7x kernels will do this */
printf("\n");
}
} else
-#endif /* LPGETSTATUS */
- if (ioctl(fd, cmds->op - offset, cmds->val) < 0) {
- perror(_("tunelp: ioctl failed"));
- }
+ 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) {
- perror(_("LPGETIRQ error"));
- exit(4);
- }
+ if (retval == -1)
+ err(EXIT_LP_IO_ERR, _("LPGETIRQ error"));
if (irq == (int)0xdeadbeef)
/* up to 1.1.77 will do this */
irq = retval;
else
printf(_("%s using polling\n"), filename);
}
-
+ free(filename);
close(fd);
- return 0;
+ return EXIT_SUCCESS;
}