xref: /onnv-gate/usr/src/lib/krb5/ss/parse.c (revision 8093:d2fc11f7c4e7)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright 1987, 1988 by MIT Student Information Processing Board
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * For copyright info, see copyright.h.
50Sstevel@tonic-gate  */
60Sstevel@tonic-gate 
7*8093SMark.Phalan@Sun.COM /*
8*8093SMark.Phalan@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
9*8093SMark.Phalan@Sun.COM  * Use is subject to license terms.
10*8093SMark.Phalan@Sun.COM  */
11*8093SMark.Phalan@Sun.COM 
120Sstevel@tonic-gate #include "ss_internal.h"
130Sstevel@tonic-gate #include "copyright.h"
142881Smp153739 #include <errno.h>
150Sstevel@tonic-gate 
160Sstevel@tonic-gate enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
170Sstevel@tonic-gate 
18*8093SMark.Phalan@Sun.COM 
19*8093SMark.Phalan@Sun.COM /*
20*8093SMark.Phalan@Sun.COM  * Solaris Kerberos:
21*8093SMark.Phalan@Sun.COM  * ss_parse has been modified slightly from the original in two ways.
22*8093SMark.Phalan@Sun.COM  * 1) A new parameter "quiet" has been added which is used to silence
23*8093SMark.Phalan@Sun.COM  *    error or warning messages.
24*8093SMark.Phalan@Sun.COM  * 2) ss_parse now returns an error status instead of argv - this is to
25*8093SMark.Phalan@Sun.COM  *    allow an error to be distinguished from no tokens when parsing an empty
26*8093SMark.Phalan@Sun.COM  *    string.
27*8093SMark.Phalan@Sun.COM  * Both of these changes allow ss_parse to be used during tab-completion.
28*8093SMark.Phalan@Sun.COM  */
29*8093SMark.Phalan@Sun.COM 
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate  * parse(line_ptr, argc_ptr)
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  * Function:
340Sstevel@tonic-gate  *      Parses line, dividing at whitespace, into tokens, returns
350Sstevel@tonic-gate  *      the "argc" and "argv" values.
360Sstevel@tonic-gate  * Arguments:
370Sstevel@tonic-gate  *      line_ptr (char *)
380Sstevel@tonic-gate  *              Pointer to text string to be parsed.
390Sstevel@tonic-gate  *      argc_ptr (int *)
400Sstevel@tonic-gate  *              Where to put the "argc" (number of tokens) value.
41*8093SMark.Phalan@Sun.COM  *      argv_ptr (char ***)
42*8093SMark.Phalan@Sun.COM  *              Where to put the series of pointers to parsed tokens.
430Sstevel@tonic-gate  * Returns:
44*8093SMark.Phalan@Sun.COM  *      error (0 - success, non-zero on failure)
450Sstevel@tonic-gate  */
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #define NEW_ARGV(old,n) (char **)realloc((char *)old,\
480Sstevel@tonic-gate 					 (unsigned)(n+2)*sizeof(char*))
490Sstevel@tonic-gate 
ss_parse(sci_idx,line_ptr,argc_ptr,argv_ptr,quiet)50*8093SMark.Phalan@Sun.COM int ss_parse (sci_idx, line_ptr, argc_ptr, argv_ptr, quiet)
510Sstevel@tonic-gate     int sci_idx;
520Sstevel@tonic-gate     register char *line_ptr;
530Sstevel@tonic-gate     int *argc_ptr;
54*8093SMark.Phalan@Sun.COM     char ***argv_ptr;
55*8093SMark.Phalan@Sun.COM     int quiet;
560Sstevel@tonic-gate {
570Sstevel@tonic-gate     register char **argv, *cp;
580Sstevel@tonic-gate     register int argc;
590Sstevel@tonic-gate     register enum parse_mode parse_mode;
600Sstevel@tonic-gate 
610Sstevel@tonic-gate     argv = (char **) malloc (sizeof(char *));
620Sstevel@tonic-gate     if (argv == (char **)NULL) {
63*8093SMark.Phalan@Sun.COM 	if (!quiet)
64*8093SMark.Phalan@Sun.COM 	    ss_error(sci_idx, errno, "Can't allocate storage");
650Sstevel@tonic-gate 	*argc_ptr = 0;
66*8093SMark.Phalan@Sun.COM 	*argv_ptr = argv;
67*8093SMark.Phalan@Sun.COM 	return(ENOMEM);
680Sstevel@tonic-gate     }
690Sstevel@tonic-gate     *argv = (char *)NULL;
700Sstevel@tonic-gate 
710Sstevel@tonic-gate     argc = 0;
720Sstevel@tonic-gate 
730Sstevel@tonic-gate     parse_mode = WHITESPACE;	/* flushing whitespace */
740Sstevel@tonic-gate     cp = line_ptr;		/* cp is for output */
750Sstevel@tonic-gate     while (1) {
760Sstevel@tonic-gate #ifdef DEBUG
770Sstevel@tonic-gate 	{
782881Smp153739 	    printf ("character `%c', mode %d\n", *line_ptr, parse_mode);
790Sstevel@tonic-gate 	}
800Sstevel@tonic-gate #endif
810Sstevel@tonic-gate 	while (parse_mode == WHITESPACE) {
820Sstevel@tonic-gate 	    if (*line_ptr == '\0')
830Sstevel@tonic-gate 		goto end_of_line;
840Sstevel@tonic-gate 	    if (*line_ptr == ' ' || *line_ptr == '\t') {
850Sstevel@tonic-gate 		line_ptr++;
860Sstevel@tonic-gate 		continue;
870Sstevel@tonic-gate 	    }
880Sstevel@tonic-gate 	    if (*line_ptr == '"') {
890Sstevel@tonic-gate 		/* go to quoted-string mode */
900Sstevel@tonic-gate 		parse_mode = QUOTED_STRING;
910Sstevel@tonic-gate 		cp = line_ptr++;
920Sstevel@tonic-gate 		argv = NEW_ARGV (argv, argc);
930Sstevel@tonic-gate 		argv[argc++] = cp;
940Sstevel@tonic-gate 		argv[argc] = NULL;
950Sstevel@tonic-gate 	    }
960Sstevel@tonic-gate 	    else {
970Sstevel@tonic-gate 		/* random-token mode */
980Sstevel@tonic-gate 		parse_mode = TOKEN;
990Sstevel@tonic-gate 		cp = line_ptr;
1000Sstevel@tonic-gate 		argv = NEW_ARGV (argv, argc);
1010Sstevel@tonic-gate 		argv[argc++] = line_ptr;
1020Sstevel@tonic-gate 		argv[argc] = NULL;
1030Sstevel@tonic-gate 	    }
1040Sstevel@tonic-gate 	}
1050Sstevel@tonic-gate 	while (parse_mode == TOKEN) {
1060Sstevel@tonic-gate 	    if (*line_ptr == '\0') {
1070Sstevel@tonic-gate 		*cp++ = '\0';
1080Sstevel@tonic-gate 		goto end_of_line;
1090Sstevel@tonic-gate 	    }
1100Sstevel@tonic-gate 	    else if (*line_ptr == ' ' || *line_ptr == '\t') {
1110Sstevel@tonic-gate 		*cp++ = '\0';
1120Sstevel@tonic-gate 		line_ptr++;
1130Sstevel@tonic-gate 		parse_mode = WHITESPACE;
1140Sstevel@tonic-gate 	    }
1150Sstevel@tonic-gate 	    else if (*line_ptr == '"') {
1160Sstevel@tonic-gate 		line_ptr++;
1170Sstevel@tonic-gate 		parse_mode = QUOTED_STRING;
1180Sstevel@tonic-gate 	    }
1190Sstevel@tonic-gate 	    else {
1200Sstevel@tonic-gate 		*cp++ = *line_ptr++;
1210Sstevel@tonic-gate 	    }
1220Sstevel@tonic-gate 	}
1230Sstevel@tonic-gate 	while (parse_mode == QUOTED_STRING) {
1240Sstevel@tonic-gate 	    if (*line_ptr == '\0') {
125*8093SMark.Phalan@Sun.COM 		if (!quiet)
126*8093SMark.Phalan@Sun.COM 		    ss_error (sci_idx, 0,
127*8093SMark.Phalan@Sun.COM 			"Unbalanced quotes in command line");
1280Sstevel@tonic-gate 		free (argv);
1290Sstevel@tonic-gate 		*argc_ptr = 0;
130*8093SMark.Phalan@Sun.COM 		*argv_ptr = NULL;
131*8093SMark.Phalan@Sun.COM 		return (-1);
1320Sstevel@tonic-gate 	    }
1330Sstevel@tonic-gate 	    else if (*line_ptr == '"') {
1340Sstevel@tonic-gate 		if (*++line_ptr == '"') {
1350Sstevel@tonic-gate 		    *cp++ = '"';
1360Sstevel@tonic-gate 		    line_ptr++;
1370Sstevel@tonic-gate 		}
1380Sstevel@tonic-gate 		else {
1390Sstevel@tonic-gate 		    parse_mode = TOKEN;
1400Sstevel@tonic-gate 		}
1410Sstevel@tonic-gate 	    }
1420Sstevel@tonic-gate 	    else {
1430Sstevel@tonic-gate 		*cp++ = *line_ptr++;
1440Sstevel@tonic-gate 	    }
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate     }
1470Sstevel@tonic-gate end_of_line:
1480Sstevel@tonic-gate     *argc_ptr = argc;
1490Sstevel@tonic-gate #ifdef DEBUG
1502881Smp153739     {
1512881Smp153739 	int i;
1522881Smp153739 	printf ("argc = %d\n", argc);
1532881Smp153739 	for (i = 0; i <= argc; i++)
1542881Smp153739 	    printf ("\targv[%2d] = `%s'\n", i,
1552881Smp153739 		    argv[i] ? argv[i] : "<NULL>");
1562881Smp153739     }
1570Sstevel@tonic-gate #endif
158*8093SMark.Phalan@Sun.COM     *argv_ptr = argv;
159*8093SMark.Phalan@Sun.COM     return(0);
1600Sstevel@tonic-gate }
161