17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
37c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
47c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
57c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
67c478bd9Sstevel@tonic-gate  *
77c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
87c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
97c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
107c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
137c478bd9Sstevel@tonic-gate  * March 31, 1998.
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
167c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
177c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
187c478bd9Sstevel@tonic-gate  * Rights Reserved.
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * Contributor(s):
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright (c) 1993, 1994 Regents of the University of Michigan.
247c478bd9Sstevel@tonic-gate  * All rights reserved.
257c478bd9Sstevel@tonic-gate  *
267c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
277c478bd9Sstevel@tonic-gate  * provided that this notice is preserved and that due credit is given
287c478bd9Sstevel@tonic-gate  * to the University of Michigan at Ann Arbor. The name of the University
297c478bd9Sstevel@tonic-gate  * may not be used to endorse or promote products derived from this
307c478bd9Sstevel@tonic-gate  * software without specific prior written permission. This software
317c478bd9Sstevel@tonic-gate  * is provided ``as is'' without express or implied warranty.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate /*
34*1da57d55SToomas Soome  * dsparse.c:  parsing routines used by display template and search
357c478bd9Sstevel@tonic-gate  * preference file library routines for LDAP clients.
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #include "ldap-int.h"
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate static int next_line( char **bufp, long *blenp, char **linep );
427c478bd9Sstevel@tonic-gate static char *next_token( char ** sp );
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate int
ldap_next_line_tokens(char ** bufp,long * blenp,char *** toksp)457c478bd9Sstevel@tonic-gate ldap_next_line_tokens( char **bufp, long *blenp, char ***toksp )
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate     char	*p, *line, *token, **toks;
487c478bd9Sstevel@tonic-gate     int		rc, tokcnt;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate     *toksp = NULL;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate     if (( rc = next_line( bufp, blenp, &line )) <= 0 ) {
537c478bd9Sstevel@tonic-gate 	return( rc );
547c478bd9Sstevel@tonic-gate     }
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate     if (( toks = (char **)NSLDAPI_CALLOC( 1, sizeof( char * ))) == NULL ) {
577c478bd9Sstevel@tonic-gate 	NSLDAPI_FREE( line );
587c478bd9Sstevel@tonic-gate 	return( -1 );
597c478bd9Sstevel@tonic-gate     }
607c478bd9Sstevel@tonic-gate     tokcnt = 0;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate     p = line;
637c478bd9Sstevel@tonic-gate     while (( token = next_token( &p )) != NULL ) {
647c478bd9Sstevel@tonic-gate 	if (( toks = (char **)NSLDAPI_REALLOC( toks, ( tokcnt + 2 ) *
657c478bd9Sstevel@tonic-gate 		sizeof( char * ))) == NULL ) {
667c478bd9Sstevel@tonic-gate 	    NSLDAPI_FREE( (char *)toks );
677c478bd9Sstevel@tonic-gate 	    NSLDAPI_FREE( line );
687c478bd9Sstevel@tonic-gate 	    return( -1 );
697c478bd9Sstevel@tonic-gate 	}
707c478bd9Sstevel@tonic-gate 	toks[ tokcnt ] = token;
717c478bd9Sstevel@tonic-gate 	toks[ ++tokcnt ] = NULL;
727c478bd9Sstevel@tonic-gate     }
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate     if ( tokcnt == 1 && strcasecmp( toks[ 0 ], "END" ) == 0 ) {
757c478bd9Sstevel@tonic-gate 	tokcnt = 0;
767c478bd9Sstevel@tonic-gate 	ldap_free_strarray( toks );
777c478bd9Sstevel@tonic-gate 	toks = NULL;
787c478bd9Sstevel@tonic-gate     }
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate     NSLDAPI_FREE( line );
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate     if ( tokcnt == 0 ) {
837c478bd9Sstevel@tonic-gate 	if ( toks != NULL ) {
847c478bd9Sstevel@tonic-gate 	    NSLDAPI_FREE( (char *)toks );
857c478bd9Sstevel@tonic-gate 	}
867c478bd9Sstevel@tonic-gate     } else {
877c478bd9Sstevel@tonic-gate 	*toksp = toks;
887c478bd9Sstevel@tonic-gate     }
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate     return( tokcnt );
917c478bd9Sstevel@tonic-gate }
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate static int
next_line(char ** bufp,long * blenp,char ** linep)957c478bd9Sstevel@tonic-gate next_line( char **bufp, long *blenp, char **linep )
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate     char	*linestart, *line, *p;
987c478bd9Sstevel@tonic-gate     long	plen;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate     linestart = *bufp;
1017c478bd9Sstevel@tonic-gate     p = *bufp;
1027c478bd9Sstevel@tonic-gate     plen = *blenp;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate     do {
1057c478bd9Sstevel@tonic-gate 	for ( linestart = p; plen > 0; ++p, --plen ) {
1067c478bd9Sstevel@tonic-gate 	    if ( *p == '\r' ) {
1077c478bd9Sstevel@tonic-gate 		if ( plen > 1 && *(p+1) == '\n' ) {
1087c478bd9Sstevel@tonic-gate 		    ++p;
1097c478bd9Sstevel@tonic-gate 		    --plen;
1107c478bd9Sstevel@tonic-gate 		}
1117c478bd9Sstevel@tonic-gate 		break;
1127c478bd9Sstevel@tonic-gate 	    }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	    if ( *p == '\n' ) {
1157c478bd9Sstevel@tonic-gate 		if ( plen > 1 && *(p+1) == '\r' ) {
1167c478bd9Sstevel@tonic-gate 		    ++p;
1177c478bd9Sstevel@tonic-gate 		    --plen;
1187c478bd9Sstevel@tonic-gate 		}
1197c478bd9Sstevel@tonic-gate 		break;
1207c478bd9Sstevel@tonic-gate 	    }
1217c478bd9Sstevel@tonic-gate 	}
1227c478bd9Sstevel@tonic-gate 	++p;
1237c478bd9Sstevel@tonic-gate 	--plen;
1247c478bd9Sstevel@tonic-gate     } while ( plen > 0 && ( *linestart == '#' || linestart + 1 == p ));
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate     *bufp = p;
1287c478bd9Sstevel@tonic-gate     *blenp = plen;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate     if ( plen <= 0 ) {
1327c478bd9Sstevel@tonic-gate 	*linep = NULL;
1337c478bd9Sstevel@tonic-gate 	return( 0 );	/* end of file */
1347c478bd9Sstevel@tonic-gate     }
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate     if (( line = NSLDAPI_MALLOC( p - linestart )) == NULL ) {
1377c478bd9Sstevel@tonic-gate 	*linep = NULL;
1387c478bd9Sstevel@tonic-gate 	return( -1 );	/* fatal error */
1397c478bd9Sstevel@tonic-gate     }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate     SAFEMEMCPY( line, linestart, p - linestart );
1427c478bd9Sstevel@tonic-gate     line[ p - linestart - 1 ] = '\0';
1437c478bd9Sstevel@tonic-gate     *linep = line;
1447c478bd9Sstevel@tonic-gate     return( strlen( line ));
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate static char *
next_token(char ** sp)1497c478bd9Sstevel@tonic-gate next_token( char **sp )
1507c478bd9Sstevel@tonic-gate {
1517c478bd9Sstevel@tonic-gate     int		in_quote = 0;
1527c478bd9Sstevel@tonic-gate     char	*p, *tokstart, *t;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate     if ( **sp == '\0' ) {
1557c478bd9Sstevel@tonic-gate 	return( NULL );
1567c478bd9Sstevel@tonic-gate     }
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate     p = *sp;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate     while ( ldap_utf8isspace( p )) {		/* skip leading white space */
1617c478bd9Sstevel@tonic-gate 	++p;
1627c478bd9Sstevel@tonic-gate     }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate     if ( *p == '\0' ) {
1657c478bd9Sstevel@tonic-gate 	return( NULL );
1667c478bd9Sstevel@tonic-gate     }
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate     if ( *p == '\"' ) {
1697c478bd9Sstevel@tonic-gate 	in_quote = 1;
1707c478bd9Sstevel@tonic-gate 	++p;
1717c478bd9Sstevel@tonic-gate     }
1727c478bd9Sstevel@tonic-gate     t = tokstart = p;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate     for ( ;; ) {
1757c478bd9Sstevel@tonic-gate 	if ( *p == '\0' || ( ldap_utf8isspace( p ) && !in_quote )) {
1767c478bd9Sstevel@tonic-gate 	    if ( *p != '\0' ) {
1777c478bd9Sstevel@tonic-gate 		++p;
1787c478bd9Sstevel@tonic-gate 	    }
1797c478bd9Sstevel@tonic-gate 	    *t++ = '\0';		/* end of token */
1807c478bd9Sstevel@tonic-gate 	    break;
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	if ( *p == '\"' ) {
1847c478bd9Sstevel@tonic-gate 	    in_quote = !in_quote;
1857c478bd9Sstevel@tonic-gate 	    ++p;
1867c478bd9Sstevel@tonic-gate 	} else {
1877c478bd9Sstevel@tonic-gate 	    *t++ = *p++;
1887c478bd9Sstevel@tonic-gate 	}
1897c478bd9Sstevel@tonic-gate     }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate     *sp = p;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate     if ( t == tokstart ) {
1947c478bd9Sstevel@tonic-gate 	return( NULL );
1957c478bd9Sstevel@tonic-gate     }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate     return( nsldapi_strdup( tokstart ));
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate void
ldap_free_strarray(char ** sap)2027c478bd9Sstevel@tonic-gate ldap_free_strarray( char **sap )
2037c478bd9Sstevel@tonic-gate {
2047c478bd9Sstevel@tonic-gate     int		i;
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate     if ( sap != NULL ) {
2077c478bd9Sstevel@tonic-gate 	for ( i = 0; sap[ i ] != NULL; ++i ) {
2087c478bd9Sstevel@tonic-gate 	    NSLDAPI_FREE( sap[ i ] );
2097c478bd9Sstevel@tonic-gate 	}
2107c478bd9Sstevel@tonic-gate 	NSLDAPI_FREE( (char *)sap );
2117c478bd9Sstevel@tonic-gate     }
2127c478bd9Sstevel@tonic-gate }
213