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 * 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 * 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 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