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] = L'\0'; 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