xref: /illumos-gate/usr/src/cmd/ttymon/tmparse.c (revision 3bb2c1567625e7b11f8c2a5335125224717af64a)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
237c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #include <stdio.h>
267c478bd9Sstevel@tonic-gate #include <ctype.h>
277c478bd9Sstevel@tonic-gate 
28*3bb2c156SToomas Soome char quoted(char *, int *);
29*3bb2c156SToomas Soome 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  *	getword	- extract one token from the string
32*3bb2c156SToomas Soome  *	char *ptr;	pointer to the string to be scanned
33*3bb2c156SToomas Soome  *	int *size;	*size = number of characters scanned
34*3bb2c156SToomas Soome  *	int getall;	if TRUE, get all char until ':' or '\0'
357c478bd9Sstevel@tonic-gate  *		- token delimiter is white space if getall is FALSE
367c478bd9Sstevel@tonic-gate  *		- token delimiter is ':' or '\0' if getall is TRUE
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate char *
getword(char * ptr,int * size,int getall)39*3bb2c156SToomas Soome getword(char *ptr, int *size, int getall)
407c478bd9Sstevel@tonic-gate {
41*3bb2c156SToomas Soome 	char *optr, c;
427c478bd9Sstevel@tonic-gate 	static char word[BUFSIZ];
437c478bd9Sstevel@tonic-gate 	int qsize;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate 	*size = 0;
467c478bd9Sstevel@tonic-gate 	if (!getall) {
477c478bd9Sstevel@tonic-gate 		/* Skip all white spaces */
487c478bd9Sstevel@tonic-gate 		while (isspace(*ptr)) {
497c478bd9Sstevel@tonic-gate 			(*size)++;
507c478bd9Sstevel@tonic-gate 			ptr++;
517c478bd9Sstevel@tonic-gate 		}
527c478bd9Sstevel@tonic-gate 	}
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate 	/* Put all characters from here to next white space or ':' or '\0' */
557c478bd9Sstevel@tonic-gate 	/* into the word, up to the size of the word. */
567c478bd9Sstevel@tonic-gate 	for (optr = word, *optr = '\0';
577c478bd9Sstevel@tonic-gate 	    *ptr != '\0' && *ptr != ':'; ptr++, (*size)++) {
587c478bd9Sstevel@tonic-gate 		if (!getall) {
597c478bd9Sstevel@tonic-gate 			if (isspace(*ptr))
607c478bd9Sstevel@tonic-gate 				break;
617c478bd9Sstevel@tonic-gate 		}
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate 		/* If the character is quoted, analyze it. */
647c478bd9Sstevel@tonic-gate 		if (*ptr == '\\') {
657c478bd9Sstevel@tonic-gate 			c = quoted(ptr, &qsize);
667c478bd9Sstevel@tonic-gate 			(*size) += qsize;
677c478bd9Sstevel@tonic-gate 			ptr += qsize;
687c478bd9Sstevel@tonic-gate 		} else c = *ptr;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 		/* If there is room, add this character to the word. */
71*3bb2c156SToomas Soome 		if (optr < &word[BUFSIZ])
72*3bb2c156SToomas Soome 			*optr++ = c;
737c478bd9Sstevel@tonic-gate 	}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	/* skip trailing blanks if any */
767c478bd9Sstevel@tonic-gate 	while (isspace(*ptr)) {
777c478bd9Sstevel@tonic-gate 		(*size)++;
787c478bd9Sstevel@tonic-gate 		ptr++;
797c478bd9Sstevel@tonic-gate 	}
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	/* Make sure the line is null terminated. */
827c478bd9Sstevel@tonic-gate 	*optr++ = '\0';
837c478bd9Sstevel@tonic-gate 	return (word);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /*	"quoted" takes a quoted character, starting at the quote	*/
877c478bd9Sstevel@tonic-gate /*	character, and returns a single character plus the size of	*/
887c478bd9Sstevel@tonic-gate /*	the quote string.  "quoted" recognizes the following as		*/
897c478bd9Sstevel@tonic-gate /*	special, \n,\r,\v,\t,\b,\f as well as the \nnn notation.	*/
907c478bd9Sstevel@tonic-gate char
quoted(char * ptr,int * qsize)91*3bb2c156SToomas Soome quoted(char *ptr, int *qsize)
927c478bd9Sstevel@tonic-gate {
93*3bb2c156SToomas Soome 	char c, *rptr;
94*3bb2c156SToomas Soome 	int i;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	rptr = ptr;
977c478bd9Sstevel@tonic-gate 	switch (*++rptr) {
987c478bd9Sstevel@tonic-gate 	case 'n':
997c478bd9Sstevel@tonic-gate 		c = '\n';
1007c478bd9Sstevel@tonic-gate 		break;
1017c478bd9Sstevel@tonic-gate 	case 'r':
1027c478bd9Sstevel@tonic-gate 		c = '\r';
1037c478bd9Sstevel@tonic-gate 		break;
1047c478bd9Sstevel@tonic-gate 	case 'v':
1057c478bd9Sstevel@tonic-gate 		c = '\013';
1067c478bd9Sstevel@tonic-gate 		break;
1077c478bd9Sstevel@tonic-gate 	case 'b':
1087c478bd9Sstevel@tonic-gate 		c = '\b';
1097c478bd9Sstevel@tonic-gate 		break;
1107c478bd9Sstevel@tonic-gate 	case 't':
1117c478bd9Sstevel@tonic-gate 		c = '\t';
1127c478bd9Sstevel@tonic-gate 		break;
1137c478bd9Sstevel@tonic-gate 	case 'f':
1147c478bd9Sstevel@tonic-gate 		c = '\f';
1157c478bd9Sstevel@tonic-gate 		break;
1167c478bd9Sstevel@tonic-gate 	case ':':
1177c478bd9Sstevel@tonic-gate 		c = ':';
1187c478bd9Sstevel@tonic-gate 		break;
1197c478bd9Sstevel@tonic-gate 	default:
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate /* If this is a numeric string, take up to three characters of */
1227c478bd9Sstevel@tonic-gate /* it as the value of the quoted character. */
1237c478bd9Sstevel@tonic-gate 		if (*rptr >= '0' && *rptr <= '7') {
1247c478bd9Sstevel@tonic-gate 			for (i = 0, c = 0; i < 3; i++) {
1257c478bd9Sstevel@tonic-gate 				c = c * 8 + (*rptr - '0');
126*3bb2c156SToomas Soome 				if (*++rptr < '0' || *rptr > '7')
127*3bb2c156SToomas Soome 					break;
1287c478bd9Sstevel@tonic-gate 			}
1297c478bd9Sstevel@tonic-gate 			rptr--;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate /* If the character following the '\\' is a NULL, back up the */
1327c478bd9Sstevel@tonic-gate /* ptr so that the NULL won't be missed.  The sequence */
1337c478bd9Sstevel@tonic-gate /* backslash null is essentually illegal. */
1347c478bd9Sstevel@tonic-gate 		} else if (*rptr == '\0') {
1357c478bd9Sstevel@tonic-gate 			c = '\0';
1367c478bd9Sstevel@tonic-gate 			rptr--;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 		/* In all other cases the quoting does nothing. */
139*3bb2c156SToomas Soome 		} else {
140*3bb2c156SToomas Soome 			c = *rptr;
141*3bb2c156SToomas Soome 		}
1427c478bd9Sstevel@tonic-gate 		break;
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	/* Compute the size of the quoted character. */
1467c478bd9Sstevel@tonic-gate 	(*qsize) = rptr - ptr;
1477c478bd9Sstevel@tonic-gate 	return (c);
1487c478bd9Sstevel@tonic-gate }
149