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