]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - sys-utils/tunelp.c
docs: update year in libs docs
[thirdparty/util-linux.git] / sys-utils / tunelp.c
index dfb30aa67a88bb5afde1edc13708eb3eba6de32f..b1e7f75df5655f73890d0fd95a2de4028eafe1ef 100644 (file)
@@ -1,12 +1,21 @@
-/****************************************************************************\
-*      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.                          *
-\****************************************************************************/
+/*
+ * 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.
+ */
 
-/* $Id: tunelp.c,v 1.9 1998/06/08 19:37:11 janl Exp $
+/*
  * $Log: tunelp.c,v $
  * Revision 1.9  1998/06/08 19:37:11  janl
  * Thus compiles tunelp with 2.1.103 kernels
  * 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@misiek.eu.org>
+ * 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 <unistd.h>
-#include <stdio.h>
+#include <errno.h>
 #include <fcntl.h>
-/* #include <linux/fs.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 <malloc.h>
-#include <string.h>
-#include <errno.h>
-#include "lp.h"
-#include "nls.h"
-#include "../version.h"
-
-struct command {
-  long op;
-  long val;
-  struct command *next;
-};
-
-
-
-
-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);
-}
+#include <unistd.h>
 
+#include <linux/lp.h>
 
-void print_version(char *progname) {
-  printf("%s %s\n", progname, UTIL_LINUX_VERSION);
-}
+#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
 
-void *mylloc(long size) {
-  void *ptr;
-  if(!(ptr = (void*)malloc(size))) {
-    perror(_("malloc error"));
-    exit(2);
-  }
-  return ptr;
-}
+#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);
 
-long get_val(char *val) {
-  long ret;
-  if (!(sscanf(val, "%ld", &ret) == 1)) {
-    perror(_("sscanf error"));
-    exit(3);
-  }
-  return ret;
-}
+       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)"));
 
-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;
+       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);
+       close_stdout_atexit();
 
-int main (int argc, char ** argv) {
-  int c, fd, irq, status, show_irq, offset = 0, retval;
-  char *progname;
-  char *filename;
-  struct stat statbuf;
-  struct command *cmds, *cmdst;
-
-  progname = argv[0];
-  if (argc < 2) print_usage(progname);
+       strutils_set_exitcode(EXIT_LP_BADVAL);
 
-  cmdst = cmds = mylloc(sizeof(struct command));
-  cmds->next = 0;
+       if (argc < 2) {
+               warnx(_("not enough arguments"));
+               errtryhelp(EXIT_FAILURE);
+       }
 
-  show_irq = 1;
-  while ((c = getopt(argc, argv, "t:c:w:a:i:ho:C:sq:rT:vV")) != EOF) {
-    switch (c) {
-    case 'h':
-      print_usage(progname);
-      break;
-    case 'i':
-      cmds->op = LPSETIRQ;
-      cmds->val = get_val(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 't':
-      cmds->op = LPTIME;
-      cmds->val = get_val(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 'c':
-      cmds->op = LPCHAR;
-      cmds->val = get_val(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 'w':
-      cmds->op = LPWAIT;
-      cmds->val = get_val(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 'a':
-      cmds->op = LPABORT;
-      cmds->val = get_onoff(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 'q':
-      if (get_onoff(optarg)) {
-        show_irq=1;
-      } else {
-        show_irq=0;
-      }
-#ifdef LPGETSTATUS
-    case 'o':
-      cmds->op = LPABORTOPEN;
-      cmds->val = get_onoff(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 'C':
-      cmds->op = LPCAREFUL;
-      cmds->val = get_onoff(optarg);
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-    case 's':
-      show_irq = 0;
-      cmds->op = LPGETSTATUS;
-      cmds->val = 0;
-      cmds->next = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-#endif
-#ifdef LPRESET
-    case 'r':
-      cmds->op = LPRESET;
-      cmds->val = 0;
-      cmds->next = mylloc(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 = mylloc(sizeof(struct command));
-      cmds = cmds->next; cmds->next = 0;
-      break;
-#endif
-    case 'v':
-    case 'V':
-      print_version(progname);
-      exit(0);
-    default:
-      print_usage(progname);
-    }
-  }
+       cmdst = cmds = xmalloc(sizeof(struct command));
+       cmds->next = NULL;
 
-  if (optind != argc-1)
-    print_usage(progname);
+       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 '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;
 
-  filename = strdup(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;
-  }
+               case 'h':
+                       usage();
+               case 'v':
+               case 'V':
+                       print_version(EXIT_SUCCESS);
+               default:
+                       errtryhelp(EXIT_FAILURE);
+               }
+       }
 
-  fstat(fd, &statbuf);
+       if (optind != argc - 1) {
+               warnx(_("no device specified"));
+               errtryhelp(EXIT_FAILURE);
+       }
 
-  if(!S_ISCHR(statbuf.st_mode)) {
-    printf(_("%s: %s not an lp device.\n"), argv[0], filename);
-    print_usage(progname);
-  }
+       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);
 
-  /* 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)
-    offset = 0x0600;   /* We don't understand the new ioctls */
+       if (fstat(fd, &statbuf))
+               err(EXIT_FAILURE, "%s: stat() failed", filename);
 
-  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");
-      else {
-        if (status == 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
-#endif /* LPGETSTATUS */
-    if (ioctl(fd, cmds->op - offset, cmds->val) < 0) {
-      perror("tunelp: ioctl");
-    }
-    cmdst = cmds;
-    cmds = cmds->next;
-    free(cmdst);
-  }
+       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;
 
-  if (show_irq) {
-    irq = 0xdeadbeef;
-    retval = ioctl(fd, LPGETIRQ - offset, &irq);
-    if (retval == -1) {
-      perror(_("LPGETIRQ error"));
-      exit(4);
-    }
-    if (irq == 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);
-  }
+       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);
+       }
 
-  close(fd);
+       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 0;
+       return EXIT_SUCCESS;
 }