xref: /onnv-gate/usr/src/lib/libldap4/common/dsparse.c (revision 3857:21b9b714e4ab)
10Sstevel@tonic-gate /*
2*3857Sstevel  * Portions Copyright 1998 Sun Microsystems, Inc.  All rights reserved.
3*3857Sstevel  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
70Sstevel@tonic-gate 
80Sstevel@tonic-gate /*
90Sstevel@tonic-gate  * Copyright (c) 1993, 1994 Regents of the University of Michigan.
100Sstevel@tonic-gate  * All rights reserved.
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
130Sstevel@tonic-gate  * provided that this notice is preserved and that due credit is given
140Sstevel@tonic-gate  * to the University of Michigan at Ann Arbor. The name of the University
150Sstevel@tonic-gate  * may not be used to endorse or promote products derived from this
160Sstevel@tonic-gate  * software without specific prior written permission. This software
170Sstevel@tonic-gate  * is provided ``as is'' without express or implied warranty.
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * dsparse.c:  parsing routines used by display template and search
200Sstevel@tonic-gate  * preference file library routines for LDAP clients.
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  * 7 March 1994 by Mark C Smith
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate #include <stdio.h>
260Sstevel@tonic-gate #include <ctype.h>
270Sstevel@tonic-gate #include <string.h>
280Sstevel@tonic-gate #ifdef MACOS
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include "macos.h"
310Sstevel@tonic-gate #else /* MACOS */
320Sstevel@tonic-gate #ifdef DOS
330Sstevel@tonic-gate #include <malloc.h>
340Sstevel@tonic-gate #include "msdos.h"
350Sstevel@tonic-gate #else /* DOS */
360Sstevel@tonic-gate #include <sys/types.h>
370Sstevel@tonic-gate #include <sys/file.h>
380Sstevel@tonic-gate #include <stdlib.h>
390Sstevel@tonic-gate #endif /* DOS */
400Sstevel@tonic-gate #endif /* MACOS */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include "lber.h"
430Sstevel@tonic-gate #include "ldap.h"
440Sstevel@tonic-gate #include "ldap-private.h"
450Sstevel@tonic-gate #include "ldap-int.h"
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #ifndef NEEDPROTOS
480Sstevel@tonic-gate int next_line_tokens();
490Sstevel@tonic-gate static ssize_t next_line();
500Sstevel@tonic-gate static char *next_token();
510Sstevel@tonic-gate #else /* !NEEDPROTOS */
520Sstevel@tonic-gate int next_line_tokens( char **bufp, ssize_t *blenp, char ***toksp );
530Sstevel@tonic-gate static ssize_t next_line( char **bufp, ssize_t *blenp, char **linep );
540Sstevel@tonic-gate static char *next_token( char ** sp );
550Sstevel@tonic-gate #endif /* !NEEDPROTOS */
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 
580Sstevel@tonic-gate 
590Sstevel@tonic-gate int
next_line_tokens(char ** bufp,ssize_t * blenp,char *** toksp)600Sstevel@tonic-gate next_line_tokens( char **bufp, ssize_t *blenp, char ***toksp )
610Sstevel@tonic-gate {
620Sstevel@tonic-gate     char	*p, *line, *token, **toks;
630Sstevel@tonic-gate     ssize_t rc;
640Sstevel@tonic-gate     int		tokcnt;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate     *toksp = NULL;
670Sstevel@tonic-gate 
680Sstevel@tonic-gate     if (( rc = next_line( bufp, blenp, &line )) <= 0 ) {
690Sstevel@tonic-gate 	return( (int)rc );
700Sstevel@tonic-gate     }
710Sstevel@tonic-gate 
720Sstevel@tonic-gate     if (( toks = (char **)calloc( (size_t) 1, sizeof( char * ))) == NULL ) {
730Sstevel@tonic-gate 	free( line );
740Sstevel@tonic-gate 	return( -1 );
750Sstevel@tonic-gate     }
760Sstevel@tonic-gate     tokcnt = 0;
770Sstevel@tonic-gate 
780Sstevel@tonic-gate     p = line;
790Sstevel@tonic-gate     while (( token = next_token( &p )) != NULL ) {
800Sstevel@tonic-gate 	if (( toks = (char **)realloc( toks, ( tokcnt + 2 ) *
810Sstevel@tonic-gate 		sizeof( char * ))) == NULL ) {
820Sstevel@tonic-gate 	    free( (char *)toks );
830Sstevel@tonic-gate 	    free( line );
840Sstevel@tonic-gate 	    return( -1 );
850Sstevel@tonic-gate 	}
860Sstevel@tonic-gate 	toks[ tokcnt ] = token;
870Sstevel@tonic-gate 	toks[ ++tokcnt ] = NULL;
880Sstevel@tonic-gate     }
890Sstevel@tonic-gate 
900Sstevel@tonic-gate     if ( tokcnt == 1 && strcasecmp( toks[ 0 ], "END" ) == 0 ) {
910Sstevel@tonic-gate 	tokcnt = 0;
920Sstevel@tonic-gate 	free_strarray( toks );
930Sstevel@tonic-gate 	toks = NULL;
940Sstevel@tonic-gate     }
950Sstevel@tonic-gate 
960Sstevel@tonic-gate     free( line );
970Sstevel@tonic-gate 
980Sstevel@tonic-gate     if ( tokcnt == 0 ) {
990Sstevel@tonic-gate 	if ( toks != NULL ) {
1000Sstevel@tonic-gate 	    free( (char *)toks );
1010Sstevel@tonic-gate 	}
1020Sstevel@tonic-gate     } else {
1030Sstevel@tonic-gate 	*toksp = toks;
1040Sstevel@tonic-gate     }
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate     return( tokcnt );
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate static ssize_t
next_line(char ** bufp,ssize_t * blenp,char ** linep)1110Sstevel@tonic-gate next_line( char **bufp, ssize_t *blenp, char **linep )
1120Sstevel@tonic-gate {
1130Sstevel@tonic-gate     char	*linestart, *line, *p;
1140Sstevel@tonic-gate     ssize_t	plen;
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate     linestart = *bufp;
1170Sstevel@tonic-gate     p = *bufp;
1180Sstevel@tonic-gate     plen = *blenp;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate     do {
1210Sstevel@tonic-gate 	for ( linestart = p; plen > 0; ++p, --plen ) {
1220Sstevel@tonic-gate 	    if ( *p == '\r' ) {
1230Sstevel@tonic-gate 		if ( plen > 1 && *(p+1) == '\n' ) {
1240Sstevel@tonic-gate 		    ++p;
1250Sstevel@tonic-gate 		    --plen;
1260Sstevel@tonic-gate 		}
1270Sstevel@tonic-gate 		break;
1280Sstevel@tonic-gate 	    }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	    if ( *p == '\n' ) {
1310Sstevel@tonic-gate 		if ( plen > 1 && *(p+1) == '\r' ) {
1320Sstevel@tonic-gate 		    ++p;
1330Sstevel@tonic-gate 		    --plen;
1340Sstevel@tonic-gate 		}
1350Sstevel@tonic-gate 		break;
1360Sstevel@tonic-gate 	    }
1370Sstevel@tonic-gate 	}
1380Sstevel@tonic-gate 	++p;
1390Sstevel@tonic-gate 	--plen;
1400Sstevel@tonic-gate     } while ( plen > 0 && ( *linestart == '#' || linestart + 1 == p ));
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate     *bufp = p;
1440Sstevel@tonic-gate     *blenp = plen;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate     if ( plen <= 0 ) {
1480Sstevel@tonic-gate 	*linep = NULL;
1490Sstevel@tonic-gate 	return( 0 );	/* end of file */
1500Sstevel@tonic-gate     }
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate     if (( line = malloc( p - linestart )) == NULL ) {
1530Sstevel@tonic-gate 	*linep = NULL;
1540Sstevel@tonic-gate 	return( -1 );	/* fatal error */
1550Sstevel@tonic-gate     }
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate     (void) memcpy( line, linestart, p - linestart );
1580Sstevel@tonic-gate     line[ p - linestart - 1 ] = '\0';
1590Sstevel@tonic-gate     *linep = line;
1600Sstevel@tonic-gate     return( strlen( line ));
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate static char *
next_token(char ** sp)1650Sstevel@tonic-gate next_token( char **sp )
1660Sstevel@tonic-gate {
1670Sstevel@tonic-gate     int		in_quote = 0;
1680Sstevel@tonic-gate     char	*p, *tokstart, *t;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate     if ( **sp == '\0' ) {
1710Sstevel@tonic-gate 	return( NULL );
1720Sstevel@tonic-gate     }
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate     p = *sp;
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate     while ( isspace( *p )) {		/* skip leading white space */
1770Sstevel@tonic-gate 	++p;
1780Sstevel@tonic-gate     }
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate     if ( *p == '\0' ) {
1810Sstevel@tonic-gate 	return( NULL );
1820Sstevel@tonic-gate     }
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate     if ( *p == '\"' ) {
1850Sstevel@tonic-gate 	in_quote = 1;
1860Sstevel@tonic-gate 	++p;
1870Sstevel@tonic-gate     }
1880Sstevel@tonic-gate     t = tokstart = p;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate     for ( ;; ) {
1910Sstevel@tonic-gate 	if ( *p == '\0' || ( isspace( *p ) && !in_quote )) {
1920Sstevel@tonic-gate 	    if ( *p != '\0' ) {
1930Sstevel@tonic-gate 		++p;
1940Sstevel@tonic-gate 	    }
1950Sstevel@tonic-gate 	    *t++ = '\0';		/* end of token */
1960Sstevel@tonic-gate 	    break;
1970Sstevel@tonic-gate 	}
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 	if ( *p == '\"' ) {
2000Sstevel@tonic-gate 	    in_quote = !in_quote;
2010Sstevel@tonic-gate 	    ++p;
2020Sstevel@tonic-gate 	} else {
2030Sstevel@tonic-gate 	    *t++ = *p++;
2040Sstevel@tonic-gate 	}
2050Sstevel@tonic-gate     }
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate     *sp = p;
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate     if ( t == tokstart ) {
2100Sstevel@tonic-gate 	return( NULL );
2110Sstevel@tonic-gate     }
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate     return( strdup( tokstart ));
2140Sstevel@tonic-gate }
215