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