]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/tunelp.c
wdctl: rename watch dog info struct
[thirdparty/util-linux.git] / sys-utils / tunelp.c
CommitLineData
61319c6e
SK
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 Public
5 * License, version 2, or any later version. See file COPYING for
6 * information on distribution conditions.
7 */
6dbe3af9 8
7d2600e2
SK
9/*
10 * This command is deprecated. The utility is in maintenance mode,
11 * meaning we keep them in source tree for backward compatibility
12 * only. Do not waste time making this command better, unless the
13 * fix is about security or other very critical issue.
14 *
15 * See Documentation/deprecated.txt for more information.
16 */
17
d3e8f659 18/*
726f69e2 19 * $Log: tunelp.c,v $
2b6fc908
KZ
20 * Revision 1.9 1998/06/08 19:37:11 janl
21 * Thus compiles tunelp with 2.1.103 kernels
22 *
fd6b7a7f
KZ
23 * Revision 1.8 1997/07/06 00:14:06 aebr
24 * Fixes to silence -Wall.
726f69e2 25 *
fd6b7a7f
KZ
26 * Revision 1.7 1997/06/20 16:10:38 janl
27 * tunelp refreshed from authors archive.
28 *
29 * Revision 1.9 1997/06/20 12:56:43 johnsonm
30 * Finished fixing license terms.
31 *
32 * Revision 1.8 1997/06/20 12:34:59 johnsonm
33 * Fixed copyright and license.
34 *
35 * Revision 1.7 1995/03/29 11:16:23 johnsonm
36 * TYPO fixed...
37 *
38 * Revision 1.6 1995/03/29 11:12:15 johnsonm
39 * Added third argument to ioctl needed with new kernels
6dbe3af9
KZ
40 *
41 * Revision 1.5 1995/01/13 10:33:43 johnsonm
42 * Chris's changes for new ioctl numbers and backwards compatibility
43 * and the reset ioctl.
44 *
45 * Revision 1.4 1995/01/03 17:42:14 johnsonm
46 * -s isn't supposed to take an argument; removed : after s in getopt...
47 *
48 * Revision 1.3 1995/01/03 07:36:49 johnsonm
49 * Fixed typo
50 *
51 * Revision 1.2 1995/01/03 07:33:44 johnsonm
52 * revisions for lp driver updates in Linux 1.1.76
53 *
b50945d4 54 * 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
7eda085c
KZ
55 * - added Native Language Support
56 *
57 * 1999-05-07 Merged LPTRUSTIRQ patch by Andrea Arcangeli (1998/11/29), aeb
6dbe3af9
KZ
58 *
59 */
60
61319c6e 61#include <errno.h>
7eda085c 62#include <fcntl.h>
a21108ba 63#include <getopt.h>
61319c6e 64#include <stdio.h>
66ee8158 65#include <stdlib.h>
7eda085c 66#include <string.h>
61319c6e
SK
67#include <sys/ioctl.h>
68#include <sys/stat.h>
69#include <sys/types.h>
70#include <unistd.h>
2ab428f6 71
d52eb4bd
SK
72#include <linux/lp.h>
73
7eda085c 74#include "nls.h"
efb8854f 75#include "closestream.h"
9c8b9fba 76#include "strutils.h"
6dbe3af9 77
05691d9e 78#define EXIT_LP_MALLOC 2
9c8b9fba 79#define EXIT_LP_BADVAL 3
7e3c80a7
SK
80#define EXIT_LP_IO_ERR 4
81
05691d9e
RM
82#define XALLOC_EXIT_CODE EXIT_LP_MALLOC
83#include "xalloc.h"
84
6dbe3af9 85struct command {
61319c6e
SK
86 long op;
87 long val;
88 struct command *next;
6dbe3af9
KZ
89};
90
6e1eda6f 91static void __attribute__((__noreturn__)) usage(void)
61319c6e 92{
6e1eda6f 93 FILE *out = stdout;
a21108ba
SK
94 fputs(USAGE_HEADER, out);
95 fprintf(out, _(" %s [options] <device>\n"), program_invocation_short_name);
6dbe3af9 96
451dbcfa
BS
97 fputs(USAGE_SEPARATOR, out);
98 fputs(_("Set various parameters for the line printer.\n"), out);
99
a21108ba
SK
100 fputs(USAGE_OPTIONS, out);
101 fputs(_(" -i, --irq <num> specify parallel port irq\n"), out);
102 fputs(_(" -t, --time <ms> driver wait time in milliseconds\n"), out);
103 fputs(_(" -c, --chars <num> number of output characters before sleep\n"), out);
104 fputs(_(" -w, --wait <us> strobe wait in micro seconds\n"), out);
105 /* TRANSLATORS: do not translate <on|off> arguments. The
106 argument reader does not recognize locale, unless `on' is
107 exactly that very same string. */
108 fputs(_(" -a, --abort <on|off> abort on error\n"), out);
109 fputs(_(" -o, --check-status <on|off> check printer status before printing\n"), out);
110 fputs(_(" -C, --careful <on|off> extra checking to status check\n"), out);
111 fputs(_(" -s, --status query printer status\n"), out);
a21108ba
SK
112 fputs(_(" -r, --reset reset the port\n"), out);
113 fputs(_(" -q, --print-irq <on|off> display current irq setting\n"), out);
114 fputs(USAGE_SEPARATOR, out);
f45f3ec3
RM
115 printf(USAGE_HELP_OPTIONS(30));
116 printf(USAGE_MAN_TAIL("tunelp(8)"));
a21108ba 117
6e1eda6f 118 exit(EXIT_SUCCESS);
7eda085c 119}
6dbe3af9 120
61319c6e
SK
121int main(int argc, char **argv)
122{
123 int c, fd, irq, status, show_irq, offset = 0, retval;
915b4bac 124 char *filename;
61319c6e
SK
125 struct stat statbuf;
126 struct command *cmds, *cmdst;
a21108ba
SK
127 static const struct option longopts[] = {
128 {"irq", required_argument, NULL, 'i'},
129 {"time", required_argument, NULL, 't'},
130 {"chars", required_argument, NULL, 'c'},
131 {"wait", required_argument, NULL, 'w'},
132 {"abort", required_argument, NULL, 'a'},
133 {"check-status", required_argument, NULL, 'o'},
134 {"careful", required_argument, NULL, 'C'},
135 {"status", no_argument, NULL, 's'},
136 {"trust-irq", required_argument, NULL, 'T'},
137 {"reset", no_argument, NULL, 'r'},
138 {"print-irq", required_argument, NULL, 'q'},
139 {"version", no_argument, NULL, 'V'},
140 {"help", no_argument, NULL, 'h'},
141 {NULL, 0, NULL, 0}
142 };
6dbe3af9 143
61319c6e
SK
144 setlocale(LC_ALL, "");
145 bindtextdomain(PACKAGE, LOCALEDIR);
146 textdomain(PACKAGE);
2c308875 147 close_stdout_atexit();
eb63b9b8 148
9c8b9fba
RM
149 strutils_set_exitcode(EXIT_LP_BADVAL);
150
6e1eda6f
RM
151 if (argc < 2) {
152 warnx(_("not enough arguments"));
153 errtryhelp(EXIT_FAILURE);
154 }
6dbe3af9 155
61319c6e 156 cmdst = cmds = xmalloc(sizeof(struct command));
87918040 157 cmds->next = NULL;
6dbe3af9 158
61319c6e 159 show_irq = 1;
a21108ba 160 while ((c = getopt_long(argc, argv, "t:c:w:a:i:ho:C:sq:rT:vV", longopts, NULL)) != -1) {
61319c6e 161 switch (c) {
61319c6e
SK
162 case 'i':
163 cmds->op = LPSETIRQ;
7e3c80a7 164 cmds->val = strtol_or_err(optarg, _("argument error"));
61319c6e
SK
165 cmds->next = xmalloc(sizeof(struct command));
166 cmds = cmds->next;
87918040 167 cmds->next = NULL;
61319c6e
SK
168 break;
169 case 't':
170 cmds->op = LPTIME;
7e3c80a7 171 cmds->val = strtol_or_err(optarg, _("argument error"));
61319c6e
SK
172 cmds->next = xmalloc(sizeof(struct command));
173 cmds = cmds->next;
87918040 174 cmds->next = NULL;
61319c6e
SK
175 break;
176 case 'c':
177 cmds->op = LPCHAR;
7e3c80a7 178 cmds->val = strtol_or_err(optarg, _("argument error"));
61319c6e
SK
179 cmds->next = xmalloc(sizeof(struct command));
180 cmds = cmds->next;
87918040 181 cmds->next = NULL;
61319c6e
SK
182 break;
183 case 'w':
184 cmds->op = LPWAIT;
7e3c80a7 185 cmds->val = strtol_or_err(optarg, _("argument error"));
61319c6e
SK
186 cmds->next = xmalloc(sizeof(struct command));
187 cmds = cmds->next;
87918040 188 cmds->next = NULL;
61319c6e
SK
189 break;
190 case 'a':
191 cmds->op = LPABORT;
7e5dd0e5 192 cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL);
61319c6e
SK
193 cmds->next = xmalloc(sizeof(struct command));
194 cmds = cmds->next;
87918040 195 cmds->next = NULL;
61319c6e
SK
196 break;
197 case 'q':
7e5dd0e5 198 show_irq = parse_switch(optarg, _("argument error"), "on", "off", NULL);
a291c7ff 199 break;
61319c6e
SK
200 case 'o':
201 cmds->op = LPABORTOPEN;
7e5dd0e5 202 cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL);
61319c6e
SK
203 cmds->next = xmalloc(sizeof(struct command));
204 cmds = cmds->next;
87918040 205 cmds->next = NULL;
61319c6e
SK
206 break;
207 case 'C':
208 cmds->op = LPCAREFUL;
7e5dd0e5 209 cmds->val = parse_switch(optarg, _("argument error"), "on", "off", NULL);
61319c6e
SK
210 cmds->next = xmalloc(sizeof(struct command));
211 cmds = cmds->next;
87918040 212 cmds->next = NULL;
61319c6e
SK
213 break;
214 case 's':
215 show_irq = 0;
216 cmds->op = LPGETSTATUS;
217 cmds->val = 0;
218 cmds->next = xmalloc(sizeof(struct command));
219 cmds = cmds->next;
87918040 220 cmds->next = NULL;
61319c6e 221 break;
61319c6e
SK
222 case 'r':
223 cmds->op = LPRESET;
224 cmds->val = 0;
225 cmds->next = xmalloc(sizeof(struct command));
226 cmds = cmds->next;
87918040 227 cmds->next = NULL;
61319c6e 228 break;
2c308875
KZ
229
230 case 'h':
231 usage();
61319c6e
SK
232 case 'v':
233 case 'V':
2c308875 234 print_version(EXIT_SUCCESS);
61319c6e 235 default:
677ec86c 236 errtryhelp(EXIT_FAILURE);
61319c6e
SK
237 }
238 }
7eda085c 239
6e1eda6f
RM
240 if (optind != argc - 1) {
241 warnx(_("no device specified"));
242 errtryhelp(EXIT_FAILURE);
243 }
7eda085c 244
0b077eab 245 filename = xstrdup(argv[optind]);
61319c6e
SK
246 fd = open(filename, O_WRONLY | O_NONBLOCK, 0);
247 /* Need to open O_NONBLOCK in case ABORTOPEN is already set
248 * and printer is off or off-line or in an error condition.
249 * Otherwise we would abort...
250 */
915b4bac
SK
251 if (fd < 0)
252 err(EXIT_FAILURE, "%s", filename);
7eda085c 253
97209c2b
KZ
254 if (fstat(fd, &statbuf))
255 err(EXIT_FAILURE, "%s: stat() failed", filename);
7eda085c 256
61319c6e 257 if (!S_ISCHR(statbuf.st_mode)) {
915b4bac 258 warnx(_("%s not an lp device"), filename);
6e1eda6f 259 errtryhelp(EXIT_FAILURE);
61319c6e
SK
260 }
261 /* Allow for binaries compiled under a new kernel to work on
262 * the old ones The irq argument to ioctl isn't touched by
263 * the old kernels, but we don't want to cause the kernel to
264 * complain if we are using a new kernel
265 */
266 if (LPGETIRQ >= 0x0600 && ioctl(fd, LPGETIRQ, &irq) < 0
267 && errno == EINVAL)
268 /* We don't understand the new ioctls */
269 offset = 0x0600;
6dbe3af9 270
61319c6e
SK
271 cmds = cmdst;
272 while (cmds->next) {
61319c6e
SK
273 if (cmds->op == LPGETSTATUS) {
274 status = 0xdeadbeef;
275 retval = ioctl(fd, LPGETSTATUS - offset, &status);
276 if (retval < 0)
915b4bac 277 warnx(_("LPGETSTATUS error"));
61319c6e
SK
278 else {
279 if (status == (int)0xdeadbeef)
280 /* a few 1.1.7x kernels will do this */
281 status = retval;
282 printf(_("%s status is %d"), filename, status);
283 if (!(status & LP_PBUSY))
284 printf(_(", busy"));
285 if (!(status & LP_PACK))
286 printf(_(", ready"));
287 if ((status & LP_POUTPA))
288 printf(_(", out of paper"));
289 if ((status & LP_PSELECD))
290 printf(_(", on-line"));
291 if (!(status & LP_PERRORP))
292 printf(_(", error"));
293 printf("\n");
294 }
295 } else
915b4bac
SK
296 if (ioctl(fd, cmds->op - offset, cmds->val) < 0)
297 warn(_("ioctl failed"));
61319c6e
SK
298 cmdst = cmds;
299 cmds = cmds->next;
300 free(cmdst);
301 }
6dbe3af9 302
61319c6e
SK
303 if (show_irq) {
304 irq = 0xdeadbeef;
305 retval = ioctl(fd, LPGETIRQ - offset, &irq);
915b4bac
SK
306 if (retval == -1)
307 err(EXIT_LP_IO_ERR, _("LPGETIRQ error"));
61319c6e
SK
308 if (irq == (int)0xdeadbeef)
309 /* up to 1.1.77 will do this */
310 irq = retval;
311 if (irq)
312 printf(_("%s using IRQ %d\n"), filename, irq);
313 else
314 printf(_("%s using polling\n"), filename);
315 }
0b077eab 316 free(filename);
61319c6e 317 close(fd);
6dbe3af9 318
130314aa 319 return EXIT_SUCCESS;
6dbe3af9 320}