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 *
getprm(s,whsp,prm)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 *
bal(s,r)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
split(arg,sys,fwd,file)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