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