home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************\
- * Copyright (C) 1992 by Michael K. Johnson, johnsonm@nigel.vnet.net *
- * *
- * This file is placed under the conditions of the GNU public *
- * license, version 2, or any later version. See file COPYING *
- * for information on distribution conditions. *
- \****************************************************************************/
-
- /* tunelp.c,v 1.1.1.1 1995/02/22 19:09:12 faith Exp
- * tunelp.c,v
- * Revision 1.1.1.1 1995/02/22 19:09:12 faith
- * Imported sources
- *
- * 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
- *
- *
- */
-
- #include<unistd.h>
- #include<stdio.h>
- #include<fcntl.h>
- #include<linux/lp.h>
- #include<linux/fs.h>
- #include<sys/ioctl.h>
- #include<sys/stat.h>
- #include<sys/types.h>
- #include<malloc.h>
- #include<string.h>
- #include<errno.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", progname);
- exit (1);
- }
-
-
-
-
-
- void *mylloc(long size) {
- void *ptr;
- if(!(ptr = (void*)malloc(size))) {
- perror("malloc error");
- exit(2);
- }
- return ptr;
- }
-
-
-
- long get_val(char *val) {
- long ret;
- if (!(sscanf(val, "%d", &ret) == 1)) {
- perror("sscanf error");
- exit(3);
- }
- return ret;
- }
-
-
- long get_onoff(char *val) {
- if (!strncasecmp("on", val, 2))
- return 1;
- return 0;
- }
-
-
-
- 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);
-
- filename = strdup(argv[1]);
- 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(argv[1]);
- return -1;
- }
-
- fstat(fd, &statbuf);
-
- if((!S_ISCHR(statbuf.st_mode)) || (MAJOR(statbuf.st_rdev) != 6 )
- || (MINOR(statbuf.st_rdev) > 3)) {
- printf("%s: %s not an lp device.\n", argv[0], argv[1]);
- print_usage(progname);
- }
-
- cmdst = cmds = mylloc(sizeof(struct command));
- cmds->next = 0;
-
- show_irq = 1;
- while ((c = getopt(argc, argv, "t:c:w:a:i:ho:C:sq:r")) != 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
- default: print_usage(progname);
- }
- }
-
- /* Allow for binaries compiled under a new kernel to work on the old ones */
- if (LPGETIRQ >= 0x0600 && ioctl(fd, LPGETIRQ) < 0 && errno == EINVAL)
- offset = 0x0600; /* We don't understand the new ioctls */
-
- 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 (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);
- }
-
- close(fd);
-
- return 0;
- }
-