xref: /illumos-gate/usr/src/cmd/bnu/getprm.c (revision defc4c8acfa01dba1ef3c13ca0cafccfcede51c0)
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 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include "uucp.h"
34 
35 #define LQUOTE	'('
36 #define RQUOTE ')'
37 
38 static char *bal();
39 
40 /*
41  * get next parameter from s
42  *	s	-> string to scan
43  *	whsp	-> pointer to use to return leading whitespace
44  *	prm	-> pointer to use to return token
45  * return:
46  *	 s	-> pointer to next character
47  *		NULL at end
48  */
49 char *
50 getprm(s, whsp, prm)
51 char *s, *whsp, *prm;
52 {
53 	char *c;
54 	char rightq;		/* the right quote character */
55 	char *beginning;
56 	wchar_t	ch;
57 	int	width;
58 
59 	beginning = prm;
60 
61 	while ((width = mbtowc(&ch, s, MB_CUR_MAX)) &&
62 	    iswspace(ch) || (ch == '\n')) {
63 		if (whsp != (char *) NULL)
64 			while (width--)
65 				*whsp++ = *s++;
66 		else
67 			s += width;
68 	}
69 
70 	if ( whsp != (char *) NULL )
71 		*whsp = '\0';
72 
73 	while ((width = mbtowc(&ch, s, MB_CUR_MAX)) && ch) {
74 		if (iswspace(ch) || ch == '\n' || ch == '\0') {
75 			*prm = '\0';
76 			return(prm == beginning ? NULL : s);
77 		}
78 		switch (ch) {
79 		case '>':
80 			if ((prm == beginning + 1) && (*beginning == '2'))
81 				*prm++ = *s++;
82 			if ((prm == beginning + 1) && (*beginning == '1'))
83 				*beginning = *s++;
84 			if (prm == beginning) {
85 				width = mbtowc(&ch, s+1, MB_CUR_MAX);
86 				if ((ch == '>') || (ch == '&'))
87 					*prm++ = *s++;
88 				*prm++ = *s++;
89 			}
90 			*prm = '\0';
91 			return(s);
92 			/* NOTREACHED */
93 			break;
94 		case '<':
95 			if ((prm == beginning + 1) && (*beginning == '0'))
96 				*beginning = *s++;
97 			if (prm == beginning) {
98 				width = mbtowc(&ch, s+1, MB_CUR_MAX);
99 				if (ch == '<') {
100 					*prm++ = *s++;
101 					*prm++ = *s++;
102 					*prm = '\0';
103 					return (s);
104 				}
105 				*prm++ = *s++;
106 			}
107 			/* FALLTHRU */
108 		case '|':
109 		case ';':
110 		case '&':
111 		case '^':
112 		case '\\':
113 			if (prm == beginning)
114 				*prm++ = *s++;
115 			*prm = '\0';
116 			return(s);
117 			/* NOTREACHED */
118 			break;
119 		case '\'':
120 		case '(':
121 		case '`':
122 		case '"':
123 			if (prm == beginning) {
124 				rightq = ( *s == '(' ? ')' : *s );
125 				c = bal(s, rightq);
126 				(void) strncpy(prm, s, c-s+1);
127 				prm += c - s + 1;
128 				if ( *(s=c) == rightq)
129 					s++;
130 			}
131 			*prm = '\0';
132 			return(s);
133 			/* NOTREACHED */
134 			break;
135 		default:
136 			while (width--)
137 				*prm++ = *s++;
138 		}
139 	}
140 
141 	*prm = '\0';
142 	return(prm == beginning ? NULL : s);
143 }
144 
145 /*
146  * bal - get balanced quoted string
147  *
148  * s - input string
149  * r - right quote
150  * Note: *s is the left quote
151  * return:
152  *  pointer to the end of the quoted string
153  * Note:
154  *	If the string is not balanced, it returns a pointer to the
155  *	end of the string.
156  */
157 
158 static char *
159 bal(s, r)
160 char *s;
161 char r;
162 {
163 	int	width;
164 	wchar_t	ch;
165 	short count = 1;
166 	char l;		/* left quote character */
167 
168 	for (l = *s++; *s; s+=width) {
169 	    width = mbtowc(&ch, s, MB_CUR_MAX);
170 	    if (*s == r) {
171 		if (--count == 0)
172 		    break;	/* this is the balanced end */
173 	    }
174 	    else if (*s == l)
175 		count++;
176 	}
177 	return(s);
178 }
179 
180 /*
181  * split - split the name into parts:
182  *	arg  - original string
183  *	sys  - leading system name
184  *	fwd  - intermediate destinations, if not NULL, otherwise
185  *		only split into two parts.
186  *	file - filename part
187  */
188 
189 int
190 split(arg, sys, fwd, file)
191 char *arg, *sys, *fwd, *file;
192 {
193     wchar_t *cl, *cr, *n;
194     int retval = 0;
195     wchar_t	wcbuf[MAXFULLNAME];
196     wchar_t	tmpbuf[MAXFULLNAME];
197     wchar_t	myname[MAXFULLNAME];
198 
199     *sys = *file = NULLCHAR;
200     if ( fwd != (char *) NULL )
201 	*fwd = NULLCHAR;
202 
203     /* uux can use parentheses for output file names */
204     /* we'll check here until  we can move it to uux */
205     if (EQUALS(Progname,"uux") && (*arg == LQUOTE)) {
206 	char *c;
207 	c = bal(arg++, RQUOTE);
208 	(void) strncpy(file, arg, c-arg);
209 	file[c-arg] = NULLCHAR;
210 	return(retval);
211 	}
212 
213 
214     mbstowcs(myname, Myname, MAXFULLNAME);
215     mbstowcs(wcbuf, arg, MAXFULLNAME);
216     for (n=wcbuf ;; n=cl+1) {
217 	cl = wcschr(n, (wchar_t)'!');
218 	if (cl == NULL) {
219 	    /* no ! in n */
220 	    (void) wcstombs(file, n, MAXFULLNAME);
221 	    return(retval);
222 	}
223 
224 	retval = 1;
225 	if (cl == n)	/* leading ! */
226 	    continue;
227 	if (WEQUALSN(myname, n, cl - n) && myname[cl - n] == NULLCHAR)
228 	    continue;
229 
230 	(void) wcsncpy(tmpbuf, n, cl-n);
231 	tmpbuf[cl-n] = NULLCHAR;
232 	(void) wcstombs(sys, tmpbuf, MAXFULLNAME);
233 
234 	if (fwd != (char *) NULL) {
235 	    if (cl != (cr = wcsrchr(n, (wchar_t)'!'))) {
236 		/*  more than one ! */
237 		wcsncpy(tmpbuf, cl+1, cr-cl-1);
238 		tmpbuf[cr-cl-1] = NULL;
239 		(void) wcstombs(fwd, tmpbuf, MAXFULLNAME);
240 	    }
241 	} else {
242 	    cr = cl;
243 	}
244 
245 	(void) wcstombs(file, cr+1, MAXFULLNAME);
246 	return(retval);
247     }
248     /*NOTREACHED*/
249 }
250 
251