xref: /illumos-gate/usr/src/cmd/lp/cmd/lpadmin/options.c (revision 34e48580)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include "ctype.h"
33 #include "stdio.h"
34 #include "string.h"
35 #include "stdlib.h"
36 #include <libintl.h>
37 
38 #include "lp.h"
39 #include "printers.h"
40 
41 #define	WHO_AM_I	I_AM_LPADMIN
42 #include "oam.h"
43 
44 #include "lpadmin.h"
45 
46 #ifdef LP_USE_PAPI_ATTR
47 #if	defined(CAN_DO_MODULES)
48 #define	OPT_LIST "A:ac:d:D:e:f:F:H:hi:I:lm:Mn:o:p:Q:r:S:s:T:u:U:v:W:x:t:P:"
49 #else
50 #define	OPT_LIST "A:ac:d:D:e:f:F:hi:I:lm:Mn:o:p:Q:r:S:s:T:u:U:v:W:x:t:P:"
51 #endif
52 
53 #else
54 #if	defined(CAN_DO_MODULES)
55 #define	OPT_LIST	"A:ac:d:D:e:f:F:H:hi:I:lm:Mo:p:Q:r:S:s:T:u:U:v:W:x:t:P:"
56 #else
57 #define	OPT_LIST	"A:ac:d:D:e:f:F:hi:I:lm:Mo:p:Q:r:S:s:T:u:U:v:W:x:t:P:"
58 #endif
59 #endif
60 
61 #define	MALLOC(pointer) \
62 	if (!(pointer = strdup(optarg))) { \
63 		LP_ERRMSG (ERROR, E_LP_MALLOC); \
64 		done (1); \
65 	} else
66 
67 #define	REALLOC(pointer) \
68 	if (!(pointer = realloc(pointer, (unsigned) (strlen(pointer) + 1 + strlen(optarg) + 1)))) { \
69 		LP_ERRMSG (ERROR, E_LP_MALLOC); \
70 		done (1); \
71 	} else if (strcat(pointer, " ")) \
72 		(void)strcat (pointer, optarg); \
73 	else
74 
75 extern char		*optarg;
76 
77 extern int		optind,
78 			opterr,
79 			optopt;
80 
81 extern double		strtod();
82 
83 extern long		strtol();
84 
85 int			a	= 0,	/* alignment needed for mount */
86 			banner	= -1,	/* allow/don't-allow nobanner */
87 #if	defined(DIRECT_ACCESS)
88 			C	= 0,	/* direct a.o.t. normal access */
89 #endif
90 		filebreak	= 0,
91 		h	= 0,	/* hardwired terminal */
92 		j	= 0,	/* do -F just for current job */
93 		l	= 0,	/* login terminal */
94 		M	= 0,	/* do mount */
95 		t	= 0,	/* tray number*/
96 		o	= 0,	/* some -o options given */
97 		Q	= -1,	/* queue threshold for alert */
98 		W	= -1;	/* alert interval */
99 
100 char		*A	= 0,	/* alert type */
101 		*c	= 0,	/* class name */
102 		*cpi	= 0,	/* string value of -o cpi= */
103 		*d	= 0,	/* default destination */
104 		*D	= 0,	/* description */
105 		*e	= 0,	/* copy existing interface */
106 		*f	= 0,	/* forms list - allow/deny */
107 		*P	= 0,	/* paper list  */
108 		*F	= 0,	/* fault recovery */
109 		**H	= 0,	/* list of modules to push */
110 		*i	= 0,	/* interface pathname */
111 		**I	= 0,	/* content-type-list */
112 		*length	= 0,	/* string value of -o length= */
113 		*lpi	= 0,	/* string value of -o lpi= */
114 		*m	= 0,	/* model name */
115 		modifications[128], /* list of mods to make */
116 #ifdef LP_USE_PAPI_ATTR
117 		*n_opt	= NULL,	/* PPD file name */
118 #endif
119 		*p	= 0,	/* printer name */
120 		*r	= 0,	/* class to remove printer from */
121 		*s	= 0,	/* system printer is on */
122 		*stty_opt= 0,	/* string value of -o stty= */
123 		**o_options = 0,/* undefined lpadmin -o options */
124 		**S	= 0,	/* -set/print-wheel list */
125 		**T	= 0,	/* terminfo names */
126 		*u	= 0,	/* user allow/deny list */
127 		*U	= 0,	/* dialer_info */
128 		*v	= 0,	/* device pathname */
129 		*width	= 0,	/* string value of -o width= */
130 		*x	= 0;	/* destination to be deleted */
131 
132 SCALED		cpi_sdn = { 0, 0 },
133 		length_sdn = { 0, 0 },
134 		lpi_sdn = { 0, 0 },
135 		width_sdn = { 0, 0 };
136 
137 static char	*modp	= modifications;
138 
139 static void	oparse();
140 
141 static char *	empty_list[] = { 0 };
142 
143 /**
144  ** options() - PARSE COMMAND LINE ARGUMENTS INTO OPTIONS
145  **/
146 
147 void			options (argc, argv)
148 	int			argc;
149 	char			*argv[];
150 {
151 	int		optsw,
152 			ac,
153 			Aflag = 0;
154 
155 	char		*cp,
156 			*rest,
157 			**av;
158 	char stroptsw[3] = "-X";
159 
160 #if	defined(__STDC__)
161 	typedef char * const *	stupid;	/* dumb-ass ANSI C */
162 #else
163 	typedef char **		stupid;
164 #endif
165 
166 
167 	/*
168 	 * Add a fake value to the end of the "argv" list, to
169 	 * catch the case that a valued-option comes last.
170 	 */
171 	av = malloc((argc + 2) * sizeof(char *));
172 	for (ac = 0; ac < argc; ac++)
173 		av[ac] = argv[ac];
174 	av[ac++] = "--";
175 
176 	opterr = 0;
177 	while ((optsw = getopt(ac, (stupid)av, OPT_LIST)) != EOF) {
178 
179 		switch (optsw) {
180 
181 		/*
182 		 * These options MAY take a value. Check the value;
183 		 * if it begins with a '-', assume it's really the next
184 		 * option.
185 		 */
186 		case 'd':
187 		case 'p':	/* MR bl87-27863 */
188 		case 'I':
189 #if	defined(CAN_DO_MODULES)
190 		case 'H':
191 #endif
192 			if (*optarg == '-') {
193 				/*
194 				 * This will work if we were given
195 				 *
196 				 *	-x -foo
197 				 *
198 				 * but would fail if we were given
199 				 *
200 				 *	-x-foo
201 				 */
202 				optind--;
203 				switch (optsw) {
204 				case 'd':
205 #if	defined(CAN_DO_MODULES)
206 				case 'H':
207 #endif
208 					optarg = NAME_NONE;
209 					break;
210 				case 'p':
211 					optarg = NAME_ALL;
212 					break;
213 				case 'I':
214 					optarg = 0;
215 					break;
216 				}
217 			}
218 			break;
219 
220 		/*
221 		 * These options MUST have a value. Check the value;
222 		 * if it begins with a dash or is null, complain.
223 		 */
224 		case 'Q':
225 		case 'W':
226 		case 't':
227 			/*
228 			 * These options take numeric values, which might
229 			 * be negative. Negative values are handled later,
230 			 * but here we just screen them.
231 			 */
232 			(void)strtol(optarg, &rest, 10);
233 			if (!rest || !*rest)
234 				break;
235 			/*FALLTHROUGH*/
236 		case 'A':
237 		case 'c':
238 		case 'e':
239 		case 'f':
240 		case 'P':
241 		case 'F':
242 		case 'i':
243 		case 'm':
244 #ifdef LP_USE_PAPI_ATTR
245 		case 'n':
246 #endif
247 		case 'o':
248 /*		case 'p': */	/* MR bl87-27863 */
249 		case 'r':
250 		case 'S':
251 		case 's':
252 		case 'T':
253 		case 'u':
254 		case 'U':
255 		case 'v':
256 		case 'x':
257 			/*
258 			 * These options also must have non-null args.
259 			 */
260 			if (!*optarg) {
261 				stroptsw[1] = optsw;
262 				cp = stroptsw;
263 				LP_ERRMSG1 (ERROR, E_LP_NULLARG, cp);
264 				done (1);
265 			}
266 			if (*optarg == '-') {
267 				stroptsw[1] = optsw;
268 				cp = stroptsw;
269 				LP_ERRMSG1 (ERROR, E_LP_OPTARG, cp);
270 				done (1);
271 			}
272 			if (optsw == 'A')
273 				Aflag++;
274 			break;
275 		case 'D':
276 			/*
277 			 * These options can have a null arg.
278 			 */
279 			if (*optarg == '-') {
280 				stroptsw[1] = optsw;
281 				cp = stroptsw;
282 				LP_ERRMSG1 (ERROR, E_LP_OPTARG, cp);
283 				done (1);
284 			}
285 			break;
286 		}
287 
288 		switch (optsw) {
289 
290 		case 'a':	/* alignment pattern needed for mount */
291 			a = 1;
292 			break;
293 
294 		case 'A':	/* alert type */
295 			if (A)
296 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'A');
297 			MALLOC(A);
298 			Aflag++;
299 			if (!STREQU(A, NAME_QUIET) && !STREQU(A, NAME_LIST))
300 				*modp++ = 'A';
301 			break;
302 
303 		case 'c':	/* class to insert printer p */
304 			if (c)
305 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'c');
306 			MALLOC(c);
307 		break;
308 
309 #if	defined(DIRECT_ACCESS)
310 		case 'C':
311 			C = 1;
312 			break;
313 #endif
314 
315 		case 'd':	/* system default destination */
316 			if (d)
317 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'd');
318 			MALLOC(d);
319 			break;
320 
321 		case 'D':	/* description */
322 			if (D)
323 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'D');
324 			MALLOC(D);
325 			*modp++ = 'D';
326 			break;
327 
328 		case 'e':	/* existing printer interface */
329 			if (e)
330 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'e');
331 			MALLOC(e);
332 			*modp++ = 'e';
333 			break;
334 
335 		case 'f':	/* set up forms allow/deny */
336 			if (f)
337 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'f');
338 			MALLOC(f);
339 			break;
340 
341 		case 'P':	/* set up forms allow/deny */
342 			if (P)
343 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'P');
344 			MALLOC(P);
345 			break;
346 
347 		case 'F':	/* fault recovery */
348 			if (F)
349 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'F');
350 			MALLOC(F);
351 			*modp++ = 'F';
352 			break;
353 
354 #if	defined(CAN_DO_MODULES)
355 		case 'H':
356 			if (H)
357 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'H');
358 			if (!optarg || !*optarg || STREQU(NAME_NONE, optarg))
359 				H = empty_list;
360 			if (!(H = getlist(optarg, LP_WS, LP_SEP))) {
361 				LP_ERRMSG (ERROR, E_LP_MALLOC);
362 				done(1);
363 			}
364 			*modp++ = 'H';
365 			break;
366 #endif
367 
368 		case 'h':	/* hardwired terminal */
369 			h = 1;
370 			*modp++ = 'h';
371 			break;
372 
373 		case 'i':	/* interface pathname */
374 			if (i)
375 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'i');
376 			MALLOC(i);
377 			*modp++ = 'i';
378 			break;
379 
380 		case 'I':	/* content-type-list */
381 			if (I)
382 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'I');
383 			if (!optarg || !*optarg || STREQU(NAME_NONE, optarg))
384 				I = empty_list;
385 			else if (!(I = getlist(optarg, LP_WS, LP_SEP))) {
386 				LP_ERRMSG (ERROR, E_LP_MALLOC);
387 				done (1);
388 			}
389 			*modp++ = 'I';
390 			break;
391 
392 #if	defined(J_OPTION)
393 		case 'j':	/* fault recovery just for current job */
394 			j = 1;
395 (void) printf (gettext("Sorry, the -j option is currently broken\n"));
396 			break;
397 #endif
398 
399 		case 'l':	/* login terminal */
400 			l = 1;
401 			*modp++ = 'l';
402 			break;
403 
404 		case 'm':	/* model interface */
405 			if (m)
406 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'm');
407 			MALLOC(m);
408 			*modp++ = 'm';
409 			break;
410 
411 #ifdef LP_USE_PAPI_ATTR
412 		case 'n':	/* PPD file */
413 			if (n_opt)
414 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'n');
415 			MALLOC(n_opt);
416 			*modp++ = 'n';
417 			break;
418 #endif
419 
420 		case 'M':	/* a mount request */
421 			M = 1;
422 			break;
423 
424 		case 'o':	/* several different options */
425 			oparse (optarg);
426 			o = 1;
427 			break;
428 
429 		case 'p':	/* printer name */
430 			if (p)
431 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'p');
432 			MALLOC(p);
433 			break;
434 
435 		case 'Q':
436 			if (Q != -1)
437 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'Q');
438 			if (STREQU(NAME_ANY, optarg))
439 				Q = 1;
440 			else {
441 				Q = strtol(optarg, &rest, 10);
442 				if (Q < 0) {
443 					LP_ERRMSG1 (ERROR, E_LP_NEGARG, 'Q');
444 					done (1);
445 				}
446 				if (rest && *rest) {
447 					LP_ERRMSG1 (ERROR, E_LP_GARBNMB, 'Q');
448 					done (1);
449 				}
450 				if (Q == 0) {
451 					LP_ERRMSG1 (ERROR, E_ADM_ZEROARG, 'Q');
452 					done (1);
453 				}
454 			}
455 			*modp++ = 'Q';
456 			break;
457 
458 		case 'r':	/* class to remove p from */
459 			if (r)
460 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'r');
461 			MALLOC(r);
462 			break;
463 
464 		case 'S':	/* char_set/print-wheels */
465 			if (S)
466 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'S');
467 			if (!(S = getlist(optarg, LP_WS, LP_SEP))) {
468 				LP_ERRMSG (ERROR, E_LP_MALLOC);
469 				done (1);
470 			}
471 			*modp++ = 'S';
472 			break;
473 
474 		case 's':
475 			if (s)
476 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 's');
477 
478 			if ((cp = strchr(optarg, '!')))
479 				*cp = '\0';
480 
481 			if (STREQU(optarg, NAME_NONE))
482 				s = Local_System;
483 			else if (STREQU(optarg, Local_System)) {
484 				if (cp) {
485 					LP_ERRMSG (ERROR, E_ADM_NAMEONLOCAL);
486 					done(1);
487 				} else
488 					s = Local_System;
489 			} else {
490 				if (cp)
491 				    *cp = '!';
492 
493 				MALLOC(s);
494 			}
495 
496 			/* 's' already used for stty 'R' for remote? */
497 			*modp++ = 'R';
498 			break;
499 
500 		case 't':	/* tray number*/
501 			if (t != 0) LP_ERRMSG1 (WARNING, E_LP_2MANY, 't');
502 			t = strtol(optarg, &rest, 10);
503 			if (t <= 0) {
504 				LP_ERRMSG1 (ERROR, E_LP_NEGARG, 't');
505 				done (1);
506 			}
507 			if (rest && *rest) {
508 				LP_ERRMSG1 (ERROR, E_LP_GARBNMB, 't');
509 				done (1);
510 			}
511 			break;
512 
513 		case 'T':	/* terminfo names for p */
514 			if (T)
515 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'T');
516 			if (!(T = getlist(optarg, LP_WS, LP_SEP))) {
517 				LP_ERRMSG (ERROR, E_LP_MALLOC);
518 				done (1);
519 			}
520 			*modp++ = 'T';
521 			break;
522 
523 		case 'u':	/* user allow/deny list */
524 			if (u)
525 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'u');
526 			MALLOC(u);
527 			break;
528 
529 		case 'U':	/* dialer_info */
530 			if (U)
531 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'U');
532 			MALLOC(U);
533 			*modp++ = 'U';
534 			break;
535 
536 		case 'v':	/* device pathname */
537 			if (v)
538 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'v');
539 			MALLOC(v);
540 			*modp++ = 'v';
541 			break;
542 
543 		case 'W':	/* alert interval */
544 			if (W != -1)
545 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'W');
546 			if (STREQU(NAME_ONCE, optarg))
547 				W = 0;
548 			else {
549 				W = strtol(optarg, &rest, 10);
550 				if (W < 0) {
551 					LP_ERRMSG1 (ERROR, E_LP_NEGARG, 'W');
552 					done (1);
553 				}
554 				if (rest && *rest) {
555 					LP_ERRMSG1 (ERROR, E_LP_GARBNMB, 'W');
556 					done (1);
557 				}
558 			}
559 			*modp++ = 'W';
560 			break;
561 
562 		case 'x':	/* destination to be deleted */
563 			if (x)
564 				LP_ERRMSG1 (WARNING, E_LP_2MANY, 'x');
565 			MALLOC(x);
566 			break;
567 
568 		default:
569 			if (optopt == '?') {
570 				usage ();
571 				done (0);
572 
573 			} else {
574 				stroptsw[1] = optsw;
575 				cp = stroptsw;
576 
577 				if (strchr(OPT_LIST, optopt))
578 					LP_ERRMSG1 (ERROR, E_LP_OPTARG, cp);
579 				else
580 					LP_ERRMSG1 (ERROR, E_LP_OPTION, cp);
581 				done (1);
582 			}
583 		}
584 	}
585 
586 	if (optind < argc)
587 		LP_ERRMSG1 (WARNING, E_LP_EXTRA, argv[optind]);
588 
589 	if ((v) && (!Aflag)) {
590 		if (!(A = strdup("write"))) {
591 			LP_ERRMSG (ERROR, E_LP_MALLOC);
592 			done (1);
593 		}
594 		*modp++ = 'A';
595 	}
596 
597 	return;
598 }
599 
600 /**
601  ** oparse() - PARSE -o OPTION
602  **/
603 
604 static void		oparse (optarg)
605 	char			*optarg;
606 {
607 	register char		**list	= dashos(optarg);
608 
609 
610 	if (!list)
611 		return;
612 
613 	for ( ; (optarg = *list); list++)
614 
615 		if (STREQU(optarg, "banner")) {
616 			if (banner != -1)
617 				LP_ERRMSG1 (
618 					WARNING,
619 					E_ADM_2MANY,
620 					"banner/nobanner"
621 				);
622 			banner = BAN_ALWAYS;
623 			*modp++ = 'b';
624 
625 		} else if (STREQU(optarg, "nobanner")) {
626 			if (banner != -1)
627 				LP_ERRMSG1 (
628 					WARNING,
629 					E_ADM_2MANY,
630 					"banner/nobanner"
631 				);
632 			banner = BAN_OPTIONAL;
633 			*modp++ = 'b';
634 
635 		/* handle banner=(always|optional|never) */
636 		} else if (STRNEQU(optarg, "banner=", 7)) {
637 			char *ptr;
638 
639 			ptr = (optarg += 7);
640 			if (banner != -1)
641 				LP_ERRMSG1 ( WARNING, E_ADM_2MANY,
642 				"banner/nobanner/banner=(always|optional|never)"
643 				);
644 
645 			/* like "banner", always print a banner */
646 			if (strcasecmp(ptr, "always") == 0)
647 				banner = BAN_ALWAYS;
648 			/* like "nobanner", print a banner unless requested */
649 			if (strcasecmp(ptr, "optional") == 0)
650 				banner = BAN_OPTIONAL;
651 			/* never print a banner */
652 			if (strcasecmp(ptr, "never") == 0)
653 				banner = BAN_NEVER;
654 			*modp++ = 'b';
655 
656 		} else if (STRNEQU(optarg, "length=", 7)) {
657 			if (length)
658 				LP_ERRMSG1 (
659 					WARNING,
660 					E_ADM_2MANY,
661 					"length="
662 				);
663 			length = (optarg += 7);
664 
665 			if (!*optarg) {
666 				length_sdn.val = 0;
667 				length_sdn.sc = 0;
668 
669 			} else {
670 				length_sdn = _getsdn(optarg, &optarg, 0);
671 				if (errno == EINVAL) {
672 					LP_ERRMSG (ERROR, E_LP_BADSCALE);
673 					done (1);
674 				}
675 			}
676 			*modp++ = 'L';
677 
678 		} else if (STRNEQU(optarg, "width=", 6)) {
679 			if (width)
680 				LP_ERRMSG1 (
681 					WARNING,
682 					E_ADM_2MANY,
683 					"width="
684 				);
685 			width = (optarg += 6);
686 
687 			if (!*optarg) {
688 				width_sdn.val = 0;
689 				width_sdn.sc = 0;
690 
691 			} else {
692 				width_sdn = _getsdn(optarg, &optarg, 0);
693 				if (errno == EINVAL) {
694 					LP_ERRMSG (ERROR, E_LP_BADSCALE);
695 					done (1);
696 				}
697 			}
698 			*modp++ = 'w';
699 
700 		} else if (STRNEQU(optarg, "cpi=", 4)) {
701 			if (cpi)
702 				LP_ERRMSG1 (WARNING, E_ADM_2MANY, "cpi=");
703 
704 			cpi = (optarg += 4);
705 
706 			if (!*optarg) {
707 				cpi_sdn.val = 0;
708 				cpi_sdn.sc = 0;
709 
710 			} else {
711 				cpi_sdn = _getsdn(optarg, &optarg, 1);
712 				if (errno == EINVAL) {
713 					LP_ERRMSG (ERROR, E_LP_BADSCALE);
714 					done (1);
715 				}
716 			}
717 			*modp++ = 'c';
718 
719 		} else if (STRNEQU(optarg, "lpi=", 4)) {
720 			if (lpi)
721 				LP_ERRMSG1 (WARNING, E_ADM_2MANY, "lpi=");
722 			lpi = (optarg += 4);
723 
724 			if (!*optarg) {
725 				lpi_sdn.val = 0;
726 				lpi_sdn.sc = 0;
727 
728 			} else {
729 				lpi_sdn = _getsdn(optarg, &optarg, 0);
730 				if (errno == EINVAL) {
731 					LP_ERRMSG (ERROR, E_LP_BADSCALE);
732 					done (1);
733 				}
734 			}
735 			*modp++ = 'M';
736 
737 		} else if (STRNEQU(optarg, "stty=", 5)) {
738 
739 			optarg += 5;
740 			if (!*optarg)
741 				stty_opt = 0;
742 
743 			else {
744 				if (strchr(LP_QUOTES, *optarg)) {
745 					register int		len
746 							= strlen(optarg);
747 
748 					if (optarg[len - 1] == *optarg)
749 						optarg[len - 1] = 0;
750 					optarg++;
751 				}
752 				if (stty_opt)
753 					REALLOC (stty_opt);
754 				else
755 					MALLOC (stty_opt);
756 			}
757 			*modp++ = 's';
758 
759 		} else if (STREQU(optarg, "filebreak")) {
760 			filebreak = 1;
761 
762 		} else if (STREQU(optarg, "nofilebreak")) {
763 			filebreak = 0;
764 
765 		/* added support for using -o to pass any key=value pair */
766 		} else if (*optarg) {
767 
768 			if ((addlist(&o_options, optarg)) != 0) {
769 				fprintf(stderr, gettext("System Error %d\n"), errno);
770 			}
771 
772 			*modp++ = 'o';
773 			optarg++;
774 		}
775 
776 	return;
777 }
778