mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-15 03:01:09 +08:00
73db912500
These functions require their arguments to be in the range of `unsigned char'.
764 lines
19 KiB
C
764 lines
19 KiB
C
#if !defined(lint)
|
|
static char copyright[] = "Copyright 1992 The University of Adelaide";
|
|
#endif
|
|
|
|
/*
|
|
* C O M M A N D
|
|
*
|
|
* Author: Mark R. Prior
|
|
* Communications and Systems Branch
|
|
* Information Technology Division
|
|
* The University of Adelaide
|
|
* E-mail: mrp@itd.adelaide.edu.au
|
|
* Date: October 1992
|
|
* Version: 1.8
|
|
* Description:
|
|
* Interpret the command sent by the client
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted
|
|
* provided that the above copyright notice and this paragraph are
|
|
* duplicated in all such forms and that any documentation,
|
|
* advertising materials, and other materials related to such
|
|
* distribution and use acknowledge that the software was developed
|
|
* by the University of Adelaide. The name of the University may not
|
|
* be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
|
|
#include "whois++.h"
|
|
#include <stdlib.h>
|
|
extern int getdtablesize (void);
|
|
|
|
#define isspecial(c) ( (c) == ',' || (c) == ';' || (c) == ':' || (c) == '=' )
|
|
|
|
static char **component = NULL;
|
|
static int numberOfComponents;
|
|
static int components = 10;
|
|
|
|
static int
|
|
getToken( char *token )
|
|
{
|
|
static char *buffer = NULL;
|
|
static int idx;
|
|
char ch;
|
|
fd_set readfds;
|
|
struct timeval timeout;
|
|
int i, status, tablesize;
|
|
|
|
if ( buffer == NULL ) {
|
|
tablesize = getdtablesize();
|
|
|
|
#ifdef FD_SETSIZE
|
|
if ( tablesize > FD_SETSIZE ) {
|
|
tablesize = FD_SETSIZE;
|
|
}
|
|
#endif /* FD_SETSIZE */
|
|
|
|
timeout.tv_sec = 60;
|
|
timeout.tv_usec = 0;
|
|
FD_ZERO( &readfds );
|
|
FD_SET( fileno( stdin ), &readfds );
|
|
|
|
if ( (status = select( tablesize, &readfds, 0, 0, &timeout )) <= 0 ) {
|
|
if ( status < 0 )
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"select: %s", strerror( errno ) );
|
|
else
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Connection timed out waiting for input." );
|
|
exit( 1 );
|
|
}
|
|
/**/ /*
|
|
* We really should determine how many characters are
|
|
* waiting for us and then malloc that amount rather than
|
|
* just guessing!
|
|
*/
|
|
if ( ( buffer = (char *)malloc(BUFSIZ) ) == NULL
|
|
|| fgets( buffer, BUFSIZ, stdin ) == NULL ) {
|
|
*token = '\0';
|
|
return EOF;
|
|
}
|
|
idx = 0;
|
|
i = strlen( buffer );
|
|
while ( i-- > 0 && ( buffer[i] == '\r' || buffer[i] == '\n' ) )
|
|
buffer[i] = '\0';
|
|
if ( log )
|
|
syslog( LOG_INFO, "Whois++ Query: %s", buffer );
|
|
}
|
|
while ( buffer[idx] != '\0' && isspace( (unsigned char) buffer[idx] ) )
|
|
idx++;
|
|
token[0] = buffer[idx++];
|
|
token[1] = '\0';
|
|
switch ( token[0] ) {
|
|
case '\0':
|
|
strcpy( token, "<end of line>" );
|
|
free( buffer );
|
|
buffer = NULL;
|
|
return EOF;
|
|
|
|
case '^':
|
|
return TEMPLATE;
|
|
|
|
case '!':
|
|
return HANDLE;
|
|
|
|
case '.':
|
|
return ATTRIBUTE;
|
|
|
|
case '#':
|
|
return VALUE;
|
|
|
|
case '*':
|
|
return SEARCH_ALL;
|
|
|
|
case '?':
|
|
return HELP;
|
|
|
|
case ':':
|
|
return COLON;
|
|
|
|
case ';':
|
|
return SEMICOLON;
|
|
|
|
case ',':
|
|
return COMMA;
|
|
|
|
case '=':
|
|
return EQUALS;
|
|
|
|
case '"':
|
|
i = 0;
|
|
do {
|
|
ch = buffer[idx++];
|
|
if ( ch == '\\' && buffer[idx] != '\0' )
|
|
token[i++] = buffer[idx++];
|
|
else
|
|
token[i++] = ch;
|
|
} while ( ch != '\0' && ch != '"' );
|
|
if ( ch == '\0' ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Trailing \" missing" );
|
|
idx--;
|
|
}
|
|
token[--i] = '\0';
|
|
return SEARCH;
|
|
|
|
default:
|
|
i = 1;
|
|
do {
|
|
ch = buffer[idx++];
|
|
if ( ch == '\\' && buffer[idx] != '\0' )
|
|
token[i++] = buffer[idx++];
|
|
else
|
|
token[i++] = ch;
|
|
} while ( ch != '\0' &&
|
|
!isspace( (unsigned char) ch ) && !isspecial( ch ) );
|
|
token[--i] = '\0';
|
|
idx--;
|
|
/**/ /*
|
|
* The following is a brute force lookup, once the names
|
|
* have settled down this should change to a hash table,
|
|
* or something similar.
|
|
*/
|
|
if ( EQ( token, "help" ) )
|
|
return HELP;
|
|
else if ( EQ( token, "list" ) )
|
|
return LIST;
|
|
else if ( EQ( token, "show" ) )
|
|
return SHOW;
|
|
else if ( EQ( token, "constraints" ) )
|
|
return CONSTRAINTS;
|
|
else if ( EQ( token, "describe" ) )
|
|
return DESCRIBE;
|
|
else if ( EQ( token, "version" ) )
|
|
return VERSION;
|
|
else if ( EQ( token, "template" ) )
|
|
return TEMPLATE;
|
|
else if ( EQ( token, "handle" ) )
|
|
return HANDLE;
|
|
else if ( EQ( token, "attribute" ) )
|
|
return ATTRIBUTE;
|
|
else if ( EQ( token, "value" ) )
|
|
return VALUE;
|
|
else if ( EQ( token, "full" ) )
|
|
return FULL;
|
|
else if ( EQ( token, "abridged" ) )
|
|
return ABRIDGED;
|
|
else if ( EQ( token, "summary" ) )
|
|
return SUMMARY;
|
|
else if ( EQ( token, "format" ) )
|
|
return FORMAT;
|
|
else if ( EQ( token, "hold" ) )
|
|
return HOLD;
|
|
else if ( EQ( token, "maxhits" ) )
|
|
return MAXHITS;
|
|
else if ( EQ( token, "match" ) )
|
|
return MATCH;
|
|
else if ( EQ( token, "linelength" ) )
|
|
return LINE_LENGTH;
|
|
else if ( EQ( token, "command" ) )
|
|
return COMMAND;
|
|
else if ( EQ( token, "trace" ) )
|
|
return TRACE;
|
|
else
|
|
return SEARCH;
|
|
}
|
|
}
|
|
|
|
static int
|
|
term(
|
|
int token,
|
|
char *value,
|
|
char *attribute,
|
|
int *specifier,
|
|
int *soundex
|
|
)
|
|
{
|
|
char buffer[BUFSIZ], temp[BUFSIZ];
|
|
int iterations;
|
|
|
|
*soundex = FALSE;
|
|
switch ( token ) {
|
|
case ATTRIBUTE: /* . */
|
|
case VALUE: /* # */
|
|
case HANDLE: /* ! */
|
|
case TEMPLATE: /* ^ */
|
|
case SEARCH_ALL:/* * */
|
|
*specifier = token;
|
|
if ( strlen( value ) > 1 ) {
|
|
/* fullname used, so expect an equals sign */
|
|
if ( getToken( buffer ) != EQUALS ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"\"=\" expected" );
|
|
return ERROR;
|
|
} else
|
|
token = getToken( value );
|
|
} else
|
|
token = getToken( value );
|
|
if ( token != COMMA && token != SEMICOLON && token != EQUALS
|
|
&& token != COLON && token != EOF ) {
|
|
token = getToken( buffer );
|
|
break;
|
|
}
|
|
|
|
case COMMA:
|
|
case SEMICOLON:
|
|
case EQUALS:
|
|
case COLON:
|
|
case EOF:
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Expected search string but got \"%s\"", buffer );
|
|
return ERROR;
|
|
|
|
default:
|
|
*specifier = SEARCH_ALL;
|
|
if ( ( token = getToken( buffer ) ) == EQUALS ) {
|
|
strcpy( attribute, value );
|
|
token = getToken( value );
|
|
if ( token == COMMA || token == SEMICOLON
|
|
|| token == COLON || token == EOF ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Syntax error, string expected." );
|
|
return ERROR;
|
|
}
|
|
token = getToken( buffer );
|
|
}
|
|
}
|
|
|
|
while ( token != COMMA && token != SEMICOLON && token != COLON
|
|
&& token != EOF ) {
|
|
if ( *value != '\0' )
|
|
strcat( value, " " );
|
|
strcat( value, buffer );
|
|
token = getToken( buffer );
|
|
}
|
|
iterations = 2;
|
|
while ( token == COMMA ) {
|
|
token = getToken( buffer );
|
|
switch ( token ) {
|
|
case MATCH:
|
|
iterations = 0;
|
|
if ( ( token = getToken( buffer ) ) != EQUALS ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"\"=\" expected" );
|
|
} else
|
|
token = getToken( buffer );
|
|
if ( EQ( buffer, "exact" ) )
|
|
*soundex = FALSE;
|
|
else if ( EQ( buffer, "fuzzy" ) )
|
|
*soundex = TRUE;
|
|
else
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Unrecognised search type" );
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
default:
|
|
if ( iterations == 0 ) {
|
|
/* obviously an unrecognised constraint */
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Constraint \"%s\" not supported",
|
|
buffer );
|
|
while ( ( token = getToken( buffer ) ) != EOF
|
|
&& token != COMMA && token != COLON
|
|
&& token != SEMICOLON )
|
|
;
|
|
} else {
|
|
strcpy( temp, buffer );
|
|
token = getToken( buffer );
|
|
if ( token == EQUALS ) {
|
|
iterations = 0;
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Constraint \"%s\" not supported",
|
|
buffer );
|
|
}
|
|
while ( token != EOF && token != SEMICOLON
|
|
&& token != COLON && token != COMMA ) {
|
|
if ( iterations > 0 ) {
|
|
strcat( temp, " " );
|
|
strcat( temp, buffer );
|
|
}
|
|
token = getToken( buffer );
|
|
}
|
|
if ( iterations > 0 ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Assuming \"%s\" part of query and not an unrecognised constraint.", temp );
|
|
strcat( value, "," );
|
|
strcat( value, temp );
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
iterations--;
|
|
}
|
|
if ( *value == '\0' ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Value not specified" );
|
|
return ERROR;
|
|
}
|
|
if ( *specifier == NULL )
|
|
*specifier = SEARCH_ALL;
|
|
return token;
|
|
}
|
|
|
|
static int
|
|
processTerm(
|
|
int specifier,
|
|
int soundex,
|
|
char *buffer,
|
|
char *attribute,
|
|
char *value
|
|
)
|
|
{
|
|
char *s, *t;
|
|
char query[BUFSIZ];
|
|
char **reallocResult;
|
|
|
|
switch ( specifier ) {
|
|
case SEARCH_ALL:
|
|
if ( numberOfComponents+3 >= components ) {
|
|
components += 10;
|
|
reallocResult = (char **)realloc(component, sizeof(char **)*components);
|
|
if ( reallocResult == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Realloc failed" );
|
|
return ERROR;
|
|
} else
|
|
component = reallocResult;
|
|
}
|
|
if ( attribute != NULL && *attribute != '\0' ) {
|
|
/* The user obviously knows what they are doing */
|
|
sprintf( query, "(%s%s%s)", attribute,
|
|
(soundex)?"~=":"=", buffer );
|
|
} else {
|
|
if ( ( s = strchr( buffer, ',' ) ) != NULL ) {
|
|
*s++ = '\0';
|
|
while ( *s && isspace( (unsigned char) *s ) )
|
|
s++;
|
|
sprintf( query, "(sn%s%s)",
|
|
(soundex)?"~=":"=", buffer );
|
|
component[numberOfComponents++] = strdup( query );
|
|
/* let's just make sure there is no title */
|
|
if ( ( t = strrchr( s, ',' ) ) != NULL ) {
|
|
*t++ = '\0';
|
|
while ( *t && isspace( (unsigned char) *t ) )
|
|
t++;
|
|
sprintf( query, "(personalTitle%s%s)",
|
|
(soundex)?"~=":"=", t );
|
|
component[numberOfComponents++] = strdup( query );
|
|
}
|
|
sprintf( query, "%s %s", s, buffer );
|
|
strcpy( buffer, query );
|
|
} else if ( strncasecmp( buffer, "first ", 6 ) == 0 ) {
|
|
sprintf( query, "%s *", &buffer[6] );
|
|
strcpy( buffer, query );
|
|
}
|
|
if ( ( s = strchr( buffer, '@' ) ) != NULL ) {
|
|
*s++ = '\0';
|
|
if ( *buffer == '\0' ) /* no username */
|
|
sprintf( query, "(mail=*@%s)", s );
|
|
else if ( *s == '\0' ) /* no host */
|
|
sprintf( query, "(|(mail=%s@*)(userid=%s))",
|
|
buffer, buffer );
|
|
else
|
|
sprintf( query, "(mail=%s@%s)",
|
|
buffer, s );
|
|
if ( soundex )
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Fuzzy matching not supported on e-mail address queries" );
|
|
} else if ( strchr( buffer, ' ' ) == NULL ) {
|
|
sprintf( query,
|
|
"(|(sn%s%s)(userid%s%s)(l%s%s)(ou%s%s)\
|
|
(&(cn%s%s)(!(objectClass=person))))",
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer );
|
|
} else {
|
|
#if defined(UOFA)
|
|
sprintf( query, "(|(l%s%s)(ou%s%s)(preferredName%s%s)",
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer );
|
|
#else
|
|
sprintf( query, "(|(l%s%s)(ou%s%s)",
|
|
(soundex)?"~=":"=", buffer,
|
|
(soundex)?"~=":"=", buffer );
|
|
#endif
|
|
/*
|
|
* If LDAP and/or Quipu didn't strip spaces
|
|
* then this would be different but as it does
|
|
* this is easy :-) but it also means we might
|
|
* get false hits.
|
|
*/
|
|
if ( soundex ) {
|
|
strcat( query, "(cn~=" );
|
|
strcat( query, buffer );
|
|
} else {
|
|
strcat( query, "(cn=*" );
|
|
strcat( query, strtok( buffer, " " ) );
|
|
while ( ( s = strtok( NULL, " " ) ) != NULL ) {
|
|
strcat( query, " * " );
|
|
strcat( query, s );
|
|
}
|
|
}
|
|
strcat( query, "))" );
|
|
}
|
|
}
|
|
component[numberOfComponents++] = strdup( query );
|
|
break;
|
|
|
|
case ATTRIBUTE:
|
|
if ( numberOfComponents+1 >= components ) {
|
|
components += 10;
|
|
reallocResult = (char **)realloc(component, sizeof(char **)*components);
|
|
if ( reallocResult == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Realloc failed" );
|
|
return ERROR;
|
|
} else
|
|
component = reallocResult;
|
|
}
|
|
if ( *value != '\0' ) {
|
|
sprintf( query, "(%s%s%s)", buffer,
|
|
(soundex)?"~=":"=", value );
|
|
component[numberOfComponents++] = strdup( query );
|
|
*value = '\0';
|
|
} else {
|
|
if ( *attribute != '\0' ) {
|
|
sprintf( query, "(%s%s*)", attribute,
|
|
(soundex)?"~=":"=" );
|
|
component[numberOfComponents++] = strdup( query );
|
|
}
|
|
strcpy( attribute, buffer );
|
|
}
|
|
break;
|
|
|
|
case TEMPLATE:
|
|
if ( numberOfComponents+1 >= components ) {
|
|
components += 10;
|
|
reallocResult = (char **)realloc(component, sizeof(char **)*components);
|
|
if ( reallocResult == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Realloc failed" );
|
|
return ERROR;
|
|
} else
|
|
component = reallocResult;
|
|
}
|
|
sprintf( query, "(objectClass%s%s)",
|
|
(soundex)?"~=":"=", templateToObjectClass( buffer ) );
|
|
component[numberOfComponents++] = strdup( query );
|
|
break;
|
|
|
|
case VALUE:
|
|
if ( *attribute != '\0' ) {
|
|
if ( numberOfComponents+1 >= components ) {
|
|
components += 10;
|
|
reallocResult = (char **)realloc(component, sizeof(char **)*components);
|
|
if ( reallocResult == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Realloc failed" );
|
|
return ERROR;
|
|
} else
|
|
component = reallocResult;
|
|
}
|
|
sprintf( query, "(%s%s%s)", attribute,
|
|
(soundex)?"~=":"=", buffer );
|
|
component[numberOfComponents++] = strdup( query );
|
|
*attribute = '\0';
|
|
} else {
|
|
if ( *value != '\0' )
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Ignoring old value (%s)", value );
|
|
strcpy( value, buffer );
|
|
}
|
|
break;
|
|
|
|
case HANDLE:
|
|
if ( numberOfComponents+1 >= components ) {
|
|
components += 10;
|
|
reallocResult = (char **)realloc(component, sizeof(char **)*components);
|
|
if ( reallocResult == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Realloc failed" );
|
|
return ERROR;
|
|
} else
|
|
component = reallocResult;
|
|
}
|
|
component[numberOfComponents++] = strdup( buffer );
|
|
return READ;
|
|
|
|
}
|
|
return SEARCH;
|
|
}
|
|
|
|
int
|
|
parseCommand( char *query )
|
|
{
|
|
/*
|
|
* This procedure reads the string sent by the user and breaks it
|
|
* down into command to execute.
|
|
*/
|
|
char buffer[BUFSIZ], attribute[BUFSIZ], objectClass[BUFSIZ],
|
|
value[BUFSIZ];
|
|
char **reallocResult;
|
|
int command, specificName, length, token, i, j, specifier, soundex;
|
|
int trace = FALSE;
|
|
|
|
switch ( command = getToken( buffer ) ) {
|
|
case COMMAND:
|
|
case CONSTRAINTS:
|
|
case DESCRIBE:
|
|
case VERSION:
|
|
/* <command> */
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
case HELP:
|
|
case LIST:
|
|
/* <command> [ <string> ] */
|
|
if ( ( token = getToken( buffer ) ) != EOF && token != COLON ) {
|
|
strcpy( query, buffer );
|
|
token = getToken( buffer );
|
|
} else
|
|
*query = '\0';
|
|
break;
|
|
|
|
case SHOW:
|
|
/* "show" <string> */
|
|
if ( ( token = getToken( buffer ) ) != EOF && token != COLON ) {
|
|
strcpy( query, buffer );
|
|
token = getToken( buffer );
|
|
} else {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Show must have a parameter" );
|
|
return ERROR;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* <term> [ ";" <term> ] */
|
|
*attribute = '\0';
|
|
*value = '\0';
|
|
soundex = FALSE;
|
|
numberOfComponents = 0;
|
|
if ( ( component = (char **)malloc(sizeof(char **)*components) ) == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Malloc failed" );
|
|
return ERROR;
|
|
}
|
|
if ( ( token = term( command, buffer, attribute, &specifier,
|
|
&soundex ) ) != ERROR )
|
|
command = processTerm( specifier, soundex, buffer,
|
|
attribute, value );
|
|
else
|
|
return ERROR;
|
|
if ( token == SEMICOLON ) {
|
|
if ( command == READ ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Multiple components on a Handle query not supported." );
|
|
return ERROR;
|
|
}
|
|
do {
|
|
soundex = FALSE;
|
|
token = getToken( buffer );
|
|
token = term( token, buffer, attribute,
|
|
&specifier, &soundex );
|
|
command = processTerm( specifier, soundex,
|
|
buffer, attribute, value );
|
|
if ( command == READ ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Multiple components on a Handle query not supported." );
|
|
return ERROR;
|
|
} else if ( command == ERROR )
|
|
return ERROR;
|
|
} while ( token == SEMICOLON );
|
|
}
|
|
/*
|
|
* Need to tidy up outstanding single value or attribute terms
|
|
*/
|
|
if ( *attribute != '\0' ) {
|
|
if ( numberOfComponents+1 >= components ) {
|
|
components += 10;
|
|
reallocResult = (char **)realloc(component, sizeof(char **)*components);
|
|
if ( reallocResult == NULL ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Realloc failed" );
|
|
return ERROR;
|
|
} else
|
|
component = reallocResult;
|
|
}
|
|
sprintf( query, "(%s%s*)", attribute,
|
|
(soundex)?"~=":"=" );
|
|
component[numberOfComponents++] = strdup( query );
|
|
}
|
|
if ( *value != '\0' )
|
|
if ( processTerm( SEARCH_ALL, soundex, value, NULL, NULL ) == ERROR )
|
|
return ERROR;
|
|
if ( numberOfComponents == 0 ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"NULL query." );
|
|
return ERROR;
|
|
} else if ( numberOfComponents == 1 )
|
|
strcpy( query, component[0] );
|
|
else {
|
|
strcpy( query, "(&" );
|
|
for ( i = 0; i < numberOfComponents; i++ )
|
|
strcat( query, component[i] );
|
|
strcat( query, ")" );
|
|
}
|
|
free( component );
|
|
break;
|
|
|
|
}
|
|
if ( token == COLON ) { /* global constraints */
|
|
do {
|
|
token = getToken( buffer );
|
|
switch ( token ) {
|
|
case FORMAT:
|
|
if ( ( token = getToken( buffer ) ) != EQUALS ) {
|
|
printFormatted( lineLength, TRUE, stdout, "\"=\" expected" );
|
|
} else
|
|
token = getToken( buffer );
|
|
switch ( token ) {
|
|
case FULL:
|
|
case ABRIDGED:
|
|
case HANDLE:
|
|
case SUMMARY:
|
|
if ( outputFormat != NULL )
|
|
printFormatted( lineLength, TRUE, stdout, "Only one response format can be specified." );
|
|
else
|
|
outputFormat = token;
|
|
break;
|
|
|
|
default:
|
|
printFormatted( lineLength, TRUE, stdout, "Unrecognised format specifier" );
|
|
}
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
case HOLD:
|
|
holdConnection = TRUE;
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
case MAXHITS:
|
|
if ( ( token = getToken( buffer ) ) != EQUALS ) {
|
|
printFormatted( lineLength, TRUE, stdout, "\"=\" expected" );
|
|
} else
|
|
token = getToken( buffer );
|
|
if ( (maxHits = atoi( buffer )) < 1
|
|
|| maxHits > maximumSize ) {
|
|
printFormatted( lineLength, TRUE, stdout, "Invalid maxhits value, defaulting to %s", maximumSize );
|
|
maxHits = maximumSize;
|
|
}
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
case LANGUAGE:
|
|
if ( ( token = getToken( buffer ) ) != EQUALS ) {
|
|
printFormatted( lineLength, TRUE, stdout, "\"=\" expected" );
|
|
} else
|
|
token = getToken( buffer );
|
|
/**/ /* need to save this value and lookup locale */
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Language not currently implemented" );
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
case LINE_LENGTH:
|
|
if ( ( token = getToken( buffer ) ) != EQUALS ) {
|
|
printFormatted( lineLength, TRUE, stdout, "\"=\" expected" );
|
|
} else
|
|
token = getToken( buffer );
|
|
lineLength = atoi( buffer );
|
|
if ( lineLength < MIN_LINE_LENGTH
|
|
|| lineLength > MAX_LINE_LENGTH ) {
|
|
printFormatted( lineLength, TRUE, stdout, "Invalid line length, using default %d", DEFAULT_LINE_LENGTH );
|
|
lineLength = DEFAULT_LINE_LENGTH;
|
|
}
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
case TRACE:
|
|
trace = TRUE;
|
|
token = getToken( buffer );
|
|
break;
|
|
|
|
default:
|
|
printFormatted( lineLength, TRUE, stdout, "Unrecognised global constraint \"%s\"", buffer );
|
|
while ( ( token = getToken( buffer ) ) != EOF
|
|
&& token != COMMA )
|
|
;
|
|
break;
|
|
|
|
}
|
|
} while ( token == COMMA );
|
|
}
|
|
if ( token != EOF ) {
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Data following \"%s\" ignored.", buffer );
|
|
while ( ( token = getToken( buffer ) ) != EOF )
|
|
;
|
|
}
|
|
if ( trace && ( command == READ || command == SEARCH ) )
|
|
switch (command) {
|
|
case READ:
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Attempting to read \"%s\"", query );
|
|
break;
|
|
|
|
case SEARCH:
|
|
printFormatted( lineLength, TRUE, stdout,
|
|
"Searching using LDAP query %s", query );
|
|
break;
|
|
|
|
}
|
|
return command;
|
|
}
|