Upload Tizen:Base source
[framework/base/util-linux-ng.git] / sys-utils / tunelp.c
1 /****************************************************************************\
2 *       Copyright (C) 1992-1997 Michael K. Johnson, johnsonm@redhat.com      *
3 *                                                                            *
4 *       This file is licensed under the terms of the GNU General             *
5 *       Public License, version 2, or any later version.  See file COPYING   *
6 *       for information on distribution conditions.                          *
7 \****************************************************************************/
8
9 /*
10  * $Log: tunelp.c,v $
11  * Revision 1.9  1998/06/08 19:37:11  janl
12  * Thus compiles tunelp with 2.1.103 kernels
13  *
14  * Revision 1.8  1997/07/06 00:14:06  aebr
15  * Fixes to silence -Wall.
16  *
17  * Revision 1.7  1997/06/20 16:10:38  janl
18  * tunelp refreshed from authors archive.
19  *
20  * Revision 1.9  1997/06/20 12:56:43  johnsonm
21  * Finished fixing license terms.
22  *
23  * Revision 1.8  1997/06/20 12:34:59  johnsonm
24  * Fixed copyright and license.
25  *
26  * Revision 1.7  1995/03/29 11:16:23  johnsonm
27  * TYPO fixed...
28  *
29  * Revision 1.6  1995/03/29  11:12:15  johnsonm
30  * Added third argument to ioctl needed with new kernels
31  *
32  * Revision 1.5  1995/01/13  10:33:43  johnsonm
33  * Chris's changes for new ioctl numbers and backwards compatibility
34  * and the reset ioctl.
35  *
36  * Revision 1.4  1995/01/03  17:42:14  johnsonm
37  * -s isn't supposed to take an argument; removed : after s in getopt...
38  *
39  * Revision 1.3  1995/01/03  07:36:49  johnsonm
40  * Fixed typo
41  *
42  * Revision 1.2  1995/01/03  07:33:44  johnsonm
43  * revisions for lp driver updates in Linux 1.1.76
44  *
45  * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
46  * - added Native Language Support
47  *
48  * 1999-05-07 Merged LPTRUSTIRQ patch by Andrea Arcangeli (1998/11/29), aeb
49  *
50  */
51
52 #include <unistd.h>
53 #include <stdio.h>
54 #include <fcntl.h>
55 /* #include <linux/fs.h> */
56 #include <sys/ioctl.h>
57 #include <sys/stat.h>
58 #include <sys/types.h>
59 #include <malloc.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <errno.h>
63 #include "lp.h"
64 #include "nls.h"
65
66 struct command {
67   long op;
68   long val;
69   struct command *next;
70 };
71
72
73 static void
74 print_usage(char *progname) {
75   printf(_("Usage: %s <device> [ -i <IRQ> | -t <TIME> | -c <CHARS> | -w <WAIT> | \n"
76            "          -a [on|off] | -o [on|off] | -C [on|off] | -q [on|off] | -s | \n"
77            "          -T [on|off] ]\n"),
78          progname);
79   exit (1);
80 }
81
82 static void
83 print_version(char *progname) {
84   printf("%s (%s)\n", progname, PACKAGE_STRING);
85 }
86
87 static void *
88 mylloc(long size) {
89   void *ptr;
90   if(!(ptr = (void*)malloc(size))) {
91     perror(_("malloc error"));
92     exit(2);
93   }
94   return ptr;
95 }
96
97 static char *progname;
98
99 static long
100 get_val(char *val) {
101   long ret;
102   if (!(sscanf(val, "%ld", &ret) == 1)) {
103     fprintf(stderr, _("%s: bad value\n"), progname);
104     exit(3);
105   }
106   return ret;
107 }
108
109
110 static long
111 get_onoff(char *val) {
112   if (!strncasecmp("on", val, 2))
113     return 1;
114   return 0;
115 }
116
117 int
118 main (int argc, char ** argv) {
119   int c, fd, irq, status, show_irq, offset = 0, retval;
120   char *filename, *p;
121   struct stat statbuf;
122   struct command *cmds, *cmdst;
123
124   progname = argv[0];
125   if ((p = strrchr(progname, '/')) != NULL)
126           progname = p+1;
127
128   setlocale(LC_ALL, "");
129   bindtextdomain(PACKAGE, LOCALEDIR);
130   textdomain(PACKAGE);
131
132   if (argc < 2) print_usage(progname);
133
134   cmdst = cmds = mylloc(sizeof(struct command));
135   cmds->next = 0;
136
137   show_irq = 1;
138   while ((c = getopt(argc, argv, "t:c:w:a:i:ho:C:sq:rT:vV")) != -1) {
139     switch (c) {
140     case 'h':
141       print_usage(progname);
142       break;
143     case 'i':
144       cmds->op = LPSETIRQ;
145       cmds->val = get_val(optarg);
146       cmds->next = mylloc(sizeof(struct command));
147       cmds = cmds->next; cmds->next = 0;
148       break;
149     case 't':
150       cmds->op = LPTIME;
151       cmds->val = get_val(optarg);
152       cmds->next = mylloc(sizeof(struct command));
153       cmds = cmds->next; cmds->next = 0;
154       break;
155     case 'c':
156       cmds->op = LPCHAR;
157       cmds->val = get_val(optarg);
158       cmds->next = mylloc(sizeof(struct command));
159       cmds = cmds->next; cmds->next = 0;
160       break;
161     case 'w':
162       cmds->op = LPWAIT;
163       cmds->val = get_val(optarg);
164       cmds->next = mylloc(sizeof(struct command));
165       cmds = cmds->next; cmds->next = 0;
166       break;
167     case 'a':
168       cmds->op = LPABORT;
169       cmds->val = get_onoff(optarg);
170       cmds->next = mylloc(sizeof(struct command));
171       cmds = cmds->next; cmds->next = 0;
172       break;
173     case 'q':
174       if (get_onoff(optarg)) {
175         show_irq=1;
176       } else {
177         show_irq=0;
178       }
179 #ifdef LPGETSTATUS
180     case 'o':
181       cmds->op = LPABORTOPEN;
182       cmds->val = get_onoff(optarg);
183       cmds->next = mylloc(sizeof(struct command));
184       cmds = cmds->next; cmds->next = 0;
185       break;
186     case 'C':
187       cmds->op = LPCAREFUL;
188       cmds->val = get_onoff(optarg);
189       cmds->next = mylloc(sizeof(struct command));
190       cmds = cmds->next; cmds->next = 0;
191       break;
192     case 's':
193       show_irq = 0;
194       cmds->op = LPGETSTATUS;
195       cmds->val = 0;
196       cmds->next = mylloc(sizeof(struct command));
197       cmds = cmds->next; cmds->next = 0;
198       break;
199 #endif
200 #ifdef LPRESET
201     case 'r':
202       cmds->op = LPRESET;
203       cmds->val = 0;
204       cmds->next = mylloc(sizeof(struct command));
205       cmds = cmds->next; cmds->next = 0;
206       break;
207 #endif
208 #ifdef LPTRUSTIRQ
209     case 'T':
210       /* Note: this will do the wrong thing on 2.0.36 when compiled under 2.2.x */
211       cmds->op = LPTRUSTIRQ;
212       cmds->val = get_onoff(optarg);
213       cmds->next = mylloc(sizeof(struct command));
214       cmds = cmds->next; cmds->next = 0;
215       break;
216 #endif
217     case 'v':
218     case 'V':
219       print_version(progname);
220       exit(0);
221     default:
222       print_usage(progname);
223     }
224   }
225
226   if (optind != argc-1)
227     print_usage(progname);
228
229   filename = strdup(argv[optind]);
230   fd = open(filename, O_WRONLY|O_NONBLOCK, 0);
231   /* Need to open O_NONBLOCK in case ABORTOPEN is already set and
232      printer is off or off-line or in an error condition.  Otherwise
233      we would abort... */
234   if (fd < 0) {
235     perror(filename);
236     return -1;
237   }
238
239   fstat(fd, &statbuf);
240
241   if(!S_ISCHR(statbuf.st_mode)) {
242     printf(_("%s: %s not an lp device.\n"), argv[0], filename);
243     print_usage(progname);
244   }
245
246   /* Allow for binaries compiled under a new kernel to work on the old ones */
247   /* The irq argument to ioctl isn't touched by the old kernels, but we don't */
248   /*  want to cause the kernel to complain if we are using a new kernel */
249   if (LPGETIRQ >= 0x0600 && ioctl(fd, LPGETIRQ, &irq) < 0 && errno == EINVAL)
250     offset = 0x0600;    /* We don't understand the new ioctls */
251
252   cmds = cmdst;
253   while (cmds->next) {
254 #ifdef LPGETSTATUS
255     if (cmds->op == LPGETSTATUS) {
256       status = 0xdeadbeef;
257       retval = ioctl(fd, LPGETSTATUS - offset, &status);
258       if (retval < 0)
259         perror("LPGETSTATUS error");
260       else {
261         if (status == 0xdeadbeef)       /* a few 1.1.7x kernels will do this */
262           status = retval;
263         printf(_("%s status is %d"), filename, status);
264         if (!(status & LP_PBUSY)) printf(_(", busy"));
265         if (!(status & LP_PACK)) printf(_(", ready"));
266         if ((status & LP_POUTPA)) printf(_(", out of paper"));
267         if ((status & LP_PSELECD)) printf(_(", on-line"));
268         if (!(status & LP_PERRORP)) printf(_(", error"));
269         printf("\n");
270       }
271     } else
272 #endif /* LPGETSTATUS */
273     if (ioctl(fd, cmds->op - offset, cmds->val) < 0) {
274       perror("tunelp: ioctl");
275     }
276     cmdst = cmds;
277     cmds = cmds->next;
278     free(cmdst);
279   }
280
281   if (show_irq) {
282     irq = 0xdeadbeef;
283     retval = ioctl(fd, LPGETIRQ - offset, &irq);
284     if (retval == -1) {
285       perror(_("LPGETIRQ error"));
286       exit(4);
287     }
288     if (irq == 0xdeadbeef)              /* up to 1.1.77 will do this */
289       irq = retval;
290     if (irq)
291       printf(_("%s using IRQ %d\n"), filename, irq);
292     else
293       printf(_("%s using polling\n"), filename);
294   }
295
296   close(fd);
297
298   return 0;
299 }