+++ /dev/null
-This is not really a bugs list (would I admit to having bugs? :-) but a
-limitations list.
-
-This implementation attempts to implement most of the proposed whois++
-interface but those sections that conflict with the underlying X.500 service
-are not implemented. This includes such things as the indexing service. While
-it would be possible to provide this functionality it is likely that a
-production X.500 Directory will have restrictions on access to the Directory
-in order to prevent "trawling" of data. It is unlikely that such a site
-would wish to allow an indexing server carte blanche access to it's data in
-order to index it.
-
-The current version also doesn't support multiple languages, this is not
-because I don't think it's a good idea (I do), but rather due to my wish to
-get this thing out of the door! As a result of this attributes are returned
-using their X.500 attribute names rather than using "whois++" names. Once
-the code to do multi-lingual support has been integrated these attributes
-will be returned in the natural language specified by the client.
-
-Some responses are returned as system messages, and some are returned as
-normal messages (with or without a leading space). At present there is no
-real consistancy, which is a result of me coding whatever I thought was best
-at the time. The current draft lacks adequate direction (except for search
-results) as to the format of responses but once this has been fixed I will
-correct the code.
-
-I am using a beta version of the LDAP beta code (possibly not the latest
-version) to develop this code but you should be able to use any of the
-University of Michigan releases, although the patches to the main Makefile
-may need some tweaking.
-
-This program has only really been tested with Ultrix although John Farrell
-of the ISODE Consortium threw it at SunOS for me so it may work with other
-Unix variants but there are no guarantees.
-
-Mark Prior
-26 April 93
+++ /dev/null
-I assume that you have already obtained the LDAP libraries and installed
-them in the appropriate place. This kit should fit into the directory
-structure created by LDAP. You should use the root.Makefile.diffs file to
-patch the LDAP Makefile so that it knows how to build whois++. This may fail
-depending on what version of LDAP you have but the rejections should be
-trival to fix (hopefully UMich will release a new version RSN).
-
-This program makes use of a number of definitions defined in the main LDAP
-Makefile but it also has a number of it's own definitions that you will
-have to modify (all definitions are located in the Makefile).
-
-CONFIG_DIRECTORY At present the configuration directory only contains
- the template directory. The files in this directory contain the
- attribute fields to return when a template is returned. The objectClass
- of an object determines the whois++ template.
-
-HELP_DIRECTORY The server has a number of help files that it may
- display when queried by a client. These files are stored under the
- specific language.
-
-LDAPHOST Which host is running a ldap server. This program
- communicates to the X.500 Directory via LDAP so you must be able to
- identify a host that is able to provide this communication.
-
-FACILITY Some error diagnostics are reported via syslog, as is
- normal queries if logging is enabled. This variable specifies which
- facility to use. I use local3 so I can create a separate log file just
- for whois++ but you may wish to log under daemon.
-
-SYSLIBS Any additional libraries required. Ultrix requires -li
- to get the Internationalisation support. I also use -lsyslog in order
- to link with a 4.3BSD style syslog rather than the ancient syslog that
- DEC normally ship with Ultrix.
-
-INTERNATIONAL Define this is you have POSIX international support.
- At present this is only used for displaying dates so it's not really
- important but I intend to use this facility to support the language
- constraint in a future release.
- Available under Ultrix but not SunOS.
-
-Once you have modified these variable you should be able to just type "make",
-if you are in the whois++ directory, or "make ldap-whois++" from the main
-LDAP directory. All going well there should be no problems so "make install",
-or "make inst-whois++".
-
-You should now copy the tailor file (whois++dtailor) to the ETCDIR and modify
-the base statement to indicate to whois++ where in the DIT whois++ should base
-its searches. You may also wish to define a user and password if you need to
-authenticate the server.
-
-Modify /etc/inetd.conf to include the new whois++ service with a line such as
- whois stream tcp nowait ETCDIR/whois++d whois++d
-where ETCDIR is the value of your ETCDIR variable.
-You might like to add the -l flag (if you want to log queries) and -i if you
-have an info attribute in the base entry (this will be displayed as a system
-message).
-
-Now send a HUP (or kill and restart) /etc/inetd.
-
-Note that if you turn on RFC931 lookups you will need the rfc931.c
-module from Wietse Venema's log_tcp package (archie should be able to find
-you a copy).
-
-Mark Prior
-mrp@itd.adelaide.edu.au
+++ /dev/null
-#
-# Configuration parameters, can be overridden in config file
-#
-LDAPSRC = ../..
-CONFIG_DIRECTORY = $(ETCDIR)/whois++
-HELP_DIRECTORY = /usr/local/isode/help/whois++
-LDAPHOST = "localhost"
-#
-# Where to stuff the man page
-MANDIR = /usr/local/isode/man
-MANSEC = 8
-#
-# Syslog facility to log queries under, using info serverity level
-#
-FACILITY = LOG_LOCAL3
-#
-# Additional system libraries
-# Under Ultrix I use the 4.3 syslog, hence the additional syslog library
-#
-#SYSLIBS = -li -lsyslog
-#
-# If you want POSIX international support (format of dates), on ultrix
-#
-#INTERNATIONAL = -DINTERNATIONAL
-#
-# If you want RFC931 logging you must have log_tcp source available
-#
-#RFC931DEF = -DRFC931
-#RFC931SRC = /local/src/log_tcp/rfc931.c
-
-SRCS = whois++.c command.c config.c describe.c help.c output.c template.c \
- util.c version.c $(RFC931SRC)
-HDRS = whois++.h
-OBJS = ${SRCS:.c=.o}
-HOST = `hostname`
-# This returns a date such as "26 April 1993", unfortunately SunOS doesn't
-# understand the %B abd %Y macros so you may need to change this.
-#DATE = `date +'%d %B %Y'`
-DATE = `date +'%D'` # this gives 4/26/93 format
-REVISION = 2
-
-DEFINES = -DETCDIR=\"$(ETCDIR)\" -DBUILD="\"$(USER)@$(HOST) on $(DATE)\"" \
- -DCONFIG_DIRECTORY=\"$(CONFIG_DIRECTORY)\" -DMAIN \
- -DHELP_DIRECTORY=\"$(HELP_DIRECTORY)\" -DREVISION="$(REVISION)" \
- -DPROTOCOL="\"[FIRST DRAFT - 15 April 1993]\"" -DRELEASE=\"BETA\" \
- -DFACILITY=$(FACILITY) -DDEFAULT_LDAPHOST=\"$(LDAPHOST)\" \
- $(INTERNATIONAL) $(RFC931DEF)
-
-CFLAGS = -I$(LDAPSRC)/include -I/usr/local/include $(ACFLAGS)
-LIBS = -L$(LDAPSRC)/libraries/libldap -lldap -L$(LDAPSRC)/libraries/liblber \
- -llber $(SYSLIBS) $(KRBLIBFLAG) $(KRBLIBS)
-
-all: whois++d
-
-whois++d: $(OBJS) $(LDAPSRC)/libraries/libldap/libldap.a
- $(CC) $(ALDFLAGS) -o $@ $(OBJS) $(LIBS)
-
-whois++.o: whois++.c $(HDRS)
- $(CC) $(CFLAGS) $(DEFINES) -c whois++.c
-
-install: inst-whois++
-
-inst-whois++: $(DESTDIR)$(ETCDIR)/whois++d
- -$(MKDIR) $(DESTDIR)$(CONFIG_DIRECTORY)
- cp -r templates $(DESTDIR)$(CONFIG_DIRECTORY)
- -$(MKDIR) $(DESTDIR)$(HELP_DIRECTORY)
- cp -r helpfiles/* $(DESTDIR)$(HELP_DIRECTORY)
- -$(MKDIR) $(DESTDIR)$(MANDIR)/man$(MANSEC)
- sed -e 's#ETCDIR#$(ETCDIR)#' whois++d.man > $(DESTDIR)$(MANDIR)/man$(MANSEC)/whois++d.$(MANSEC)
- @echo "Don't forget to modify and install the tailor file"
-
-$(DESTDIR)$(ETCDIR)/whois++d: whois++d
- install -c -m 755 whois++d $(DESTDIR)$(ETCDIR)
-
-lint:;
- lint $(SRCS)
-
-5lint:;
- /usr/5bin/lint $(SRCS)
-
-clean:;
- rm -f *.o core a.out whois++d
-
-depend:;
- ../mkdep $(CFLAGS) $(SRCS)
-
-# DO NOT DELETE THIS LINE -- mkdep uses it.
-# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
-
-# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+++ /dev/null
-This is a DUA interface, using LDAP, that conforms to the latest (not yet)
-Internet Draft for the Whois++ Architecture. It does NOT support the indexing
-service also proposed under Whois++.
-
-It is a gateway to X.500 (similar to the finger and gopher gateways) which
-allows the user to access the directory via a mechanism that they are
-comfortable with and/or have access to. The real Directory Service (and the
-only practical large scale distributed directory service) is provided by the
-underlying X.500 service. This implementation is not an endorsement of Whois++
-but I recognise that there are users whose only interface to a directory
-service is via a whois client. It therefore attempts to service these users,
-much like the other two gateways.
-
-Comments on the Whois++ specification should be sent to the IETF Whois and
-Network Information Lookup Service (WNILS) Working Group. The e-mail address
-of the group is ietf-wnils@ucdavis.edu, to be added to the mailing list send
-a request to ietf-wnils-request@ucdavis.edu. Comments about this program
-should be directed to the discussion list ldap-whois++@itd.adelaide.edu.au,
-(send a message to ldap-whois++-request@itd.adelaide.edu.au to join). I will
-post bug fix announcements to this list.
-
-Mark Prior
-6 May 93
+++ /dev/null
- Things to do list (well the start of one anyway :-)
-
-. Test on something other than Ultrix
-. Finish the multilingual support.
-. Make the parser for the query "language" more error resistant
-. Do a real parser for the config file
-. More help files
-. Think about multi charset, although this is probably an issue for LDAP
-. Kerberos authentication
+++ /dev/null
-#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"
-
-extern char *index(), *rindex();
-
-#define isspecial(c) ( (c) == ',' || (c) == ';' || (c) == ':' || (c) == '=' )
-
-static char **component = NULL;
-static int numberOfComponents;
-static int components = 10;
-
-static int getToken( token )
-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();
- 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( 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( 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( token, value, attribute, specifier, soundex )
-int token;
-char *value, *attribute;
-int *specifier, *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( specifier, soundex, buffer, attribute, value )
-int specifier, soundex;
-char *buffer, *attribute, *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 = index( buffer, ',' ) ) != NULL ) {
- *s++ = '\0';
- while ( *s && isspace( *s ) )
- s++;
- sprintf( query, "(sn%s%s)",
- (soundex)?"~=":"=", buffer );
- component[numberOfComponents++] = strdup( query );
- /* let's just make sure there is no title */
- if ( ( t = rindex( s, ',' ) ) != NULL ) {
- *t++ = '\0';
- while ( *t && isspace( *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 = index( 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 ( index( 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( query )
-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;
-}
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * C O N F I G
- *
- * 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.7
- * Description:
- * Process the configuration file.
- *
- * 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"
-
-static struct {
- char *str;
- int cmd;
- } commands[] = {
-#define CMD_BASE 1
- "base", CMD_BASE,
-#define CMD_LDAP 2
- "ldaphost", CMD_LDAP,
-#define CMD_HELPDIR 3
- "helpdir", CMD_HELPDIR,
-#define CMD_USER 4
- "user", CMD_USER,
-#define CMD_PASSWORD 5
- "password", CMD_PASSWORD,
-#define CMD_CONFIGDIR 6
- "configdir", CMD_CONFIGDIR,
-#define CMD_CONTACT 7
- "contact", CMD_CONTACT,
-#define CMD_HOSTNAME 8
- "hostname", CMD_HOSTNAME,
-#define CMD_LANGUAGE 9
- "language", CMD_LANGUAGE,
-#define CMD_BANNER 10
- "banner", CMD_BANNER,
-#define CMD_TEMPLATE 11
- "template", CMD_TEMPLATE,
- NULL, NULL
- };
-
-static nextLine(fp)
-FILE *fp;
-{
- /*
- * We probably should check that the user hasn't put anything else
- * on the line but I can't be bothered!
- */
- register int c;
-
- while ((c = getc(fp)) != EOF && c != '\n')
- ;
-}
-
-/*
- * Get next word, skipping blanks & comments.
- */
-static int getWord(buffer, size, fp)
-char *buffer;
-int size;
-FILE *fp;
-{
- char *cp;
- int c, string;
-
- string = 0;
- cp = buffer;
- while ((c = getc(fp)) != EOF) {
- if (c == '#') {
- while ((c = getc(fp)) != EOF && c != '\n')
- ;
- continue;
- }
- if (c == '\n') {
- if (cp != buffer)
- ungetc(c, fp);
- break;
- } else if (c == '\\') {
- c = getc(fp);
- if (c == EOF)
- c = '\n';
- } else if (c == '"') {
- string = !string;
- continue;
- }
- if (!string && isspace(c)) {
- while (isspace(c = getc(fp)) && c != '\n')
- ;
- ungetc(c, fp);
- if (cp != buffer) /* Trailing whitespace */
- break;
- continue; /* Leading whitespace */
- }
- if (cp >= buffer+size-1)
- break;
- *cp++ = c;
- }
- *cp = '\0';
- return (cp != buffer);
-}
-
-void readConfiguration( config )
-FILE *config;
-
-{
- char buffer[BUFSIZ];
- char *s;
- int i;
-
- /*
- * A procedure to read in the configuration parameters.
- * At the moment this is just a "quick hack" and it should be
- * replaced in the next version by a proper scanner.
- */
-
- while ( getWord( buffer, BUFSIZ, config ) != NULL ) {
- for ( i = 0; commands[i].str != NULL; i++ )
- if ( EQ( buffer, commands[i].str ) )
- break;
- if ( commands[i].str == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Unrecognised command <%s>", buffer );
- exit( 1 );
- }
- if ( getWord( buffer, BUFSIZ, config ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "value missing in configuration file" );
- exit( 1 );
- }
- switch ( commands[i].cmd ) {
- case CMD_BASE:
- base = strdup( buffer );
- break;
-
- case CMD_LDAP:
- ldaphost = strdup( buffer );
- break;
-
- case CMD_HELPDIR:
- helpDir = strdup( buffer );
- break;
-
- case CMD_USER:
- user = strdup( buffer );
- break;
-
- case CMD_PASSWORD:
- password = strdup( buffer );
- break;
-
- case CMD_CONFIGDIR:
- configDir = strdup( buffer );
- break;
-
- case CMD_CONTACT:
- contact = strdup( buffer );
- break;
-
- case CMD_HOSTNAME:
- hostname = strdup( buffer );
- break;
-
- case CMD_LANGUAGE:
- defaultLanguage = lowerCase( strdup( buffer ) );
- break;
-
- case CMD_BANNER:
- banner = strdup( buffer );
- break;
-
- case CMD_TEMPLATE:
- if ( templateTranslationTable == NULL
- && ( templateTranslationTable = (table *)malloc(sizeof(table)*tableSize) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Malloc failed" );
- exit( 1 );
- } else if ( numberOfTemplates+1 == tableSize ) {
- tableSize += TABLE_INCREMENT;
- if ( ( templateTranslationTable = (table *)realloc(templateTranslationTable, sizeof(table)*tableSize) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Realloc failed" );
- exit( 1 );
- }
- }
- templateTranslationTable[numberOfTemplates].key =
- lowerCase( strdup( buffer ) );
- if ( getWord( buffer, BUFSIZ, config ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "objectClass missing in config file" );
- exit( 1 );
- }
- templateTranslationTable[numberOfTemplates].value =
- lowerCase( strdup( buffer ) );
- numberOfTemplates++;
- break;
-
- default:
- printFormatted( lineLength, TRUE, stdout,
- "Attribute <%s> not recognised.",
- buffer );
- break;
-
- }
- nextLine( config );
- }
-}
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * D E S C R I B E
- *
- * 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.7
- * Description:
- * A module implementing the describe whois++ command.
- *
- * 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"
-
-int displayDescribe( ld, organisation )
-LDAP *ld;
-char *organisation;
-{
-
- int i, len1, len2;
- LDAPMessage *result, *entry;
- char *value, *ptr;
- char **values;
- static char *masterDSA[] = { "masterDSA", NULL };
- static char *manager[] = { "manager", NULL };
- static char *roleOccupant[] = { "roleOccupant", NULL };
- static char *attributes[] = { "postalAddress", "telephoneNumber",
- "facsimileTelephoneNumber", "mail", "lastModifiedBy",
-#if defined(UOFA)
- "preferredName",
-#endif
- NULL };
- extern char *index();
-
- if ( !EQ( language, "english" ) )
- printFormatted( lineLength, TRUE, stdout,
- "The output of the DESCRIBE command must be in english \
-according to the IAFA services template." );
-
- printFormatted( lineLength, FALSE, stdout,
- "%-19s Whois++", "Service-Name:" );
- if ( hostname != NULL )
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Primary-Name:", hostname );
- else
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <unknown>", "Primary-Name:" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s Whois++ service using LDAP to access a Quipu based",
- "Description:" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s X.500 Directory Service.", "" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s whois++ protocol on tcp port 43", "Access-Protocol:" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s whois, x.500, ldap", "Keywords:" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s 24 hours a day, 7 days a week", "Access-Times:" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s Open Access", "Policy:" );
- printFormatted( lineLength, FALSE, stdout,
- "%-19s ", "URI:" );
- if ( contact == NULL ) {
- /*
- * The contact hasn't identified themselves in the tailor file
- * so lets try to work it out by finding out who manages the
- * DSA that masters the organisation's entry!
- */
- if ( debug > 2 )
- printFormatted( lineLength, TRUE, stdout,
- "No contact info provided, searching ..." );
- ldap_search_s( ld, organisation, LDAP_SCOPE_BASE,
- "objectclass=*", masterDSA, 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <Unknown>", "Contact:" );
- return TRUE;
- }
- if ( debug > 2 )
- printFormatted( lineLength, TRUE, stdout,
- "Looking for the master DSA ..." );
- if ( (values = ldap_get_values( ld, result, "masterDSA" )) == NULL
- || values[0] == NULL ) {
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <Unknown>", "Contact:" );
- return TRUE;
- }
- if ( debug > 2 )
- printFormatted( lineLength, TRUE, stdout,
- "Searching for the DSA manager ..." );
- ldap_search_s( ld, values[0], LDAP_SCOPE_BASE, "objectclass=*",
- manager, 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <Unknown>", "Contact:" );
- printFormatted( lineLength, TRUE, stdout,
- "Search failed, %s",
- ldap_err2string( ld->ld_errno ) );
- return TRUE;
- }
- if ( (values = ldap_get_values( ld, result, "manager" )) == NULL ) {
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <Unknown>", "Contact:" );
- return TRUE;
- }
- if ( debug > 2 )
- printFormatted( lineLength, TRUE, stdout,
- "Retrieving the DSA manager's entry ..." );
- /*
- * we have at least one manager for this DSA but which one is
- * the "correct" one to list?
- */
- len1 = strlen( organisation );
- for ( i = 0; values[i] != NULL; i++ )
- if ( strlen( values[i] ) >= len1 ) {
- len2 = strlen( values[i] );
- if ( EQ( organisation, &values[i][len2-len1] ) )
- contact = strdup( values[i] );
- }
- ldap_value_free( values );
- if ( contact == NULL ) {
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <Unknown>", "Contact:" );
- if ( debug )
- printFormatted( lineLength, TRUE, stdout,
- "Cannot find a suitable manager" );
- return TRUE;
- }
- ldap_search_s( ld, contact, LDAP_SCOPE_BASE, "objectclass=*",
- roleOccupant, 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, FALSE, stdout,
- "%-19s <Unknown>", "Contact:" );
- printFormatted( lineLength, TRUE, stdout,
- "Search failed, %s",
- ldap_err2string( ld->ld_errno ) );
- return TRUE;
- }
- if ( (values = ldap_get_values( ld, result, "roleOccupant" )) != NULL
- || values[0] == NULL ) {
- free( contact );
- /* Just pick one! */
- contact = strdup( values[0] );
- ldap_value_free( values );
- }
- if ( debug > 2 )
- printFormatted( lineLength, TRUE, stdout,
- "The contact is %s", contact );
- }
- ldap_search_s( ld, contact, LDAP_SCOPE_BASE, "objectclass=*",
- attributes, 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, FALSE, stdout, "%-19s <Unknown>",
- "Contact:" );
- printFormatted( lineLength, TRUE, stdout,
- "Read for \"%s\" returned error, %s", contact,
- ldap_err2string( ld->ld_errno ) );
- }
-#if defined(UOFA)
- if ( (values = ldap_get_values( ld, result, "preferredName" )) != NULL
- && values[0] != NULL ) {
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Contact:", values[0] );
- ldap_value_free( values );
- } else {
-#endif
- value = strdup( ldap_dn2ufn( ldap_get_dn( ld, result ) ) );
- if ( (ptr = index( value, ',' )) != NULL )
- *ptr = '\0';
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Contact:", value );
-#if defined(UOFA)
- }
-#endif
- if ( ( values = ldap_get_values( ld, result, "postalAddress" )) != NULL ) {
- for ( i = 0; values[i] != NULL; i++ ) {
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Postal-Address:",
- strtok( values[i], "$" ) );
- while ( ( ptr = strtok( NULL, "$" ) ) != NULL )
- printFormatted( lineLength, FALSE, stdout,
- "%-19s%s", "", ptr );
- }
- ldap_value_free( values );
- }
- if ( ( values = ldap_get_values( ld, result, "telephoneNumber" )) != NULL ) {
- for ( i = 0; values[i] != NULL; i++ )
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Telephone:", values[i] );
- ldap_value_free( values );
- }
- if ( ( values = ldap_get_values( ld, result, "facsimileTelephoneNumber" )) != NULL ) {
- for ( i = 0; values[i] != NULL; i++ )
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Fax:", values[i] );
- ldap_value_free( values );
- }
- if ( ( values = ldap_get_values( ld, result, "mail" )) != NULL ) {
- for ( i = 0; values[i] != NULL; i++ )
- printFormatted( lineLength, FALSE, stdout, "%-19s %s",
- "Electronic-Address:", values[i] );
- ldap_value_free( values );
- }
- if ( ( values = ldap_get_values( ld, result, "lastModifiedBy" )) != NULL ) {
- for ( i = 0; values[i] != NULL; i++ )
- printFormatted( lineLength, FALSE, stdout,
- "%-19s \"%s\"", "Modified-By:", values[i] );
- ldap_value_free( values );
- }
- return FALSE;
-}
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * H E L P
- *
- * 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.7
- * Description:
- * The Help module
- *
- * 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"
-
-void needHelp( reason )
-char *reason;
-{
- char filename[MAXPATHLEN];
- char buffer[BUFSIZ];
- int i;
- DIR *dir;
- struct dirent *entry;
- FILE *help;
-
- if ( reason == NULL || *reason == '\0' ) {
- sprintf( filename, "%s/%s/general", helpDir, language );
- if ( ( help = fopen( filename, "r" ) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Sorry cannot open general information help file" );
- return;
- }
- } else {
- sprintf( filename, "%s/%s/%s", helpDir, language,
- lowerCase( reason ) );
- if ( ( help = fopen( filename, "r" ) ) == NULL ) {
- sprintf( filename, "%s/%s/%s", helpDir, defaultLanguage,
- lowerCase( reason ) );
- if ( ( help = fopen( filename, "r" ) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Sorry cannot open help file for topic \"%s\"",
- reason );
- return;
- } else {
- printFormatted( lineLength, TRUE, stdout,
- "Sorry no help in %s, using default language (%s).",
- language, defaultLanguage );
- }
- }
- }
- while ( fgets( buffer, BUFSIZ, help ) != NULL ) {
- i = strlen( buffer );
- while ( i-- > 0 && ( buffer[i] == '\n' || buffer[i] == '\r' ) )
- buffer[i] = '\0';
- printFormatted( lineLength, FALSE, stdout, "%s", buffer );
- }
- fclose( help );
- if ( reason == NULL || *reason == '\0' ) {
- sprintf( filename, "%s/%s", helpDir, language );
- if ( ( dir = opendir( filename ) ) == NULL )
- return;
- printFormatted( lineLength, FALSE, stdout, "" );
- printFormatted( lineLength, FALSE, stdout,
- "Further information is available on the following topics" );
- for ( entry = readdir( dir ); entry != NULL; entry = readdir( dir ) )
- if ( !EQ(entry->d_name, "." ) && !EQ(entry->d_name, ".." ) )
- printFormatted( lineLength, FALSE, stdout,
- " %s", lowerCase( entry->d_name ) );
- closedir( dir );
- }
- return;
-}
+++ /dev/null
-List the commands supported by this server.
+++ /dev/null
-The whois++ query langauge contains a number of mandatory commands which all
-servers should support but there are also a number of optional commands. In
-order that a client can find out what commands are supported by a server
-there is a mandatory command called "command" that should provide a list of
-all commands supported by the server. If you wish to use a command that is
-optional you may wish to use the "command" command to find out if the server
-supports it.
-
-This server only supports the mandatory commands.
+++ /dev/null
-Constraints are a mechanism for modifying the behaviour of the query and are
-divided into two classes (local or global) depending on the scope of the
-modification. Local contraints may appear attached to each term in a query,
-whereas global contraints apply to the entire query and so are listed after
-the actual query (separated from the query by a colon).
-
-This implementation supports the following constraints -
-1. Local constraints
- a. match=(exact|fuzzy)
- The directory is either searched for an exact match of the value
- specified or soundex style matching is attempted.
- If you wish to attempt substring matching you should include a "*" in
- your search string.
- Default=exact
-
-2. Global constraints
- a. format=(full|abridged|handle|summary)
- This specifies the format of the response returned by the query.
- Normally the format used is controlled by the number of matches but this
- constraint may be used to override the default.
- b. hold
- The connection is held open for a maximum of 60 seconds for further
- queries, normally the connection is closed after each query.
- c. language=<string>
- Return any diagnostics in the natural language specified.
- Default=english
- d. linelength=<value>
- This constraint allows you to indicate the maximum length of lines you
- can display via your client.
- Default=80
- e. maxhits=<value>
- The intent of this constraint is to limit the number of hits returned.
- Unfortunately in the context of the server communicating with an X.500
- server this is generally not possible as the DSA will define the
- maximum number of entries it wishes to return. It is still of some use
- if you wish to constrain the value to less than the value that the
- X.500 directory would normally return.
- The default value is dependant on the value configured by the Directory
- Administrator into the DSA.
+++ /dev/null
-The describe command returns information about this service, formatted
-according to the IAFA Services template. This information will include a
-description of the service, access policy, and a contract for the person
-who manages the Directory.
-
+++ /dev/null
-You have connected to a server that implements the new WHOIS++ specification.
-
-This service is provided via an underlying X.500 Directory Service and so
-this server is really only a read-only DUA interface to the X.500 Directory.
-
-A "technical" description of this service may be obtained by using the
-"describe" command, this will also list a contact for this service.
+++ /dev/null
-This is an experimental implementation of a whois++ service being proposed
-by the IETF's WNILS (Whois and Network Information Lookup Service) Working
-Group. It uses a (Quipu 8.0 based) X.500 Directory Service as it's
-information source.
-
-The whois++ server communicates with the Directory via LDAP (Lightweight
-Directory Access Protocol), using the libraries developed by the University
-of Michigan. All user search queries are transformed into LDAP queries that
-are passed to the X.500 Directory service for resolution.
-
-For "normal" whois style queries we make a number of assumptions on the
-attributes of interest depending on the format of the query. If you only
-supply a single token it is assumed that you wish to search for a family
-name or userid. Multiple tokens imply a search on a full name (commonName
-in X.500-speak). We also support e-mail lookups as described in the
-original whois RFC (RFC954) however wildcard style searches may be
-constrained by the X.500 Directory service.
-
-Example queries
-a. ng =>
- (|(sn=ng)(userid=ng)(l=ng)(ou=ng)(&(cn=ng)(!(objectClass=person))))
-b. zhongyi li =>
- (|(l=zhongyi li)(ou=zhongyi li)(preferredName=zhongyi li)\
- (cn=*zhongyi * li))
-c. mrp@ =>
- (|(mail=mrp@*)(userid=mrp))
-
-You can also use structured whois++ queries that specify the attribute to
-search as well as value. Searching using uncommon attributes attributes may
-be restricted by the X.500 Directory system.
+++ /dev/null
-The list command returns a list of the whois++ template types that may be
-returned as a result of a query. You can use the show command to return
-further information about these templates.
+++ /dev/null
-There are 4 different search styles possible when using a whois++ server.
-
-The first of these styles is the familiar whois style query, where your
-client supplies a number of tokens and these tokens are converted into a
-LDAP search query for processing by the X.500 Directory system.
-
-Example queries
-a. ng =>
- (|(sn=ng)(userid=ng)(l=ng)(ou=ng)(&(cn=ng)(!(objectClass=person))))
-
-b. Snoke, Robert Lee =>
- (&(sn=Snoke)(|(l=Robert Lee Snoke)(ou=Robert Lee Snoke)\
- (preferredName=Robert Lee Snoke)(cn=*Robert * Lee * Snoke)))
-
-c. mrp@ =>
- (|(mail=mrp@*)(userid=mrp))
-
-As you can see no attribute information was supplied by the client and so
-the server must "guess" what information is required. X.500 uses the
-attribute cn (commonName) fairly generically to name entries so this is used
-in constructing queries. It is assumed that most queries will relate to a
-search for a person so the query is composed in such a way to emphasise this
-assumption. If only one token is supplied this is assumed to be a family
-name whereas if more than one token is supplied this assumed to be the full
-name, in order to distinguish the family name you may use the "," syntax as
-per example (b).
-
-E-mail lookups as described in the original whois RFC (RFC954) are also
-supported however wildcard style searches may be constrained by the X.500
-Directory service.
-
-The other search styles involve the use of attributes, where the client
-specifies the type of the data that it wishes to search for.
+++ /dev/null
-The show command returns a list of attributes that can be returned if a
-record of that template type is returned as a result of a query.
+++ /dev/null
-The version command provides version number information and should be quoted
-when reporting any problems with the server. The information returned will
-include the version of the protocol as well as the program's revision number.
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * O U T P U T
- *
- * 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.7
- * Description:
- * The Output routines
- *
- * 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 <varargs.h>
-#include "whois++.h"
-
-extern char *index(), *rindex();
-
-static displayEntry();
-static printAttribute();
-
-static char *selectObjectClass( ld, entry )
-LDAP *ld;
-LDAPMessage *entry;
-
-{
- static char *objectClass[] = { "objectClass", NULL };
- LDAPMessage *result;
- char *dn, *template;
- char **val;
- int i;
-
- template = NULL;
- dn = strdup( ldap_get_dn( ld, entry ) );
- ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectclass=*", objectClass,
- 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, TRUE, stdout,
- "Read on object \"%s\" failed, %s",
- dn, ldap_err2string( ld->ld_errno ) );
- free( dn );
- return;
- } else
- free( dn );
- if ( ( val = ldap_get_values( ld, result, "objectClass" ) ) == NULL )
- return;
- for ( i = 0 ; val[i] != NULL ; i++ )
- if ( specifyAttributes( lowerCase( val[i] ) ) != NULL ) {
- template = strdup( val[i] );
- break;
- }
- ldap_value_free( val );
- return template;
-}
-
-int displayResult( ld, result, outputFormat )
-LDAP *ld;
-LDAPMessage *result;
-int outputFormat;
-
-{
- int i, matches, number = 0;
- char *dn;
- LDAPMessage *e;
- char *objectClass;
- char **attributes, **objectClassTable;
-
- matches = ldap_count_entries( ld, result );
- if ( log )
- syslog( LOG_INFO, "%d match(es) to query", matches );
- if ( matches == 0 ) {
- printFormatted( lineLength, TRUE, stdout, "No matches found." );
- return FALSE;
- }
- if ( outputFormat == NULL ) {
- if ( matches == 1 )
- outputFormat = FULL;
- else if ( matches <= ABRIDGED_LIMIT )
- outputFormat = HANDLE;
- else
- outputFormat = SUMMARY;
- }
- switch (outputFormat) {
- case FULL:
- printFormatted( lineLength, FALSE, stdout,
- "#FULL %d", matches );
- for ( e = ldap_first_entry( ld, result ); e != NULL;
- e = ldap_next_entry( ld, e ) ) {
- objectClass = selectObjectClass( ld, e );
- dn = ldap_get_dn( ld, e );
- printFormatted( lineLength, FALSE, stdout,
- "#%s \"%s\"",
- objectClassToTemplate( objectClass ), dn );
- displayEntry( ld, dn,
- specifyAttributes( objectClass ) );
- if ( objectClass != NULL )
- free( objectClass );
- }
- printFormatted( lineLength, FALSE, stdout, "#END" );
- break;
-
- case ABRIDGED:
- /*
- * As the DN contains most of the information wanted in
- * ABRIDGED format we use HANDLE format even if the client
- * really specified ABRIDGED.
- */
- printFormatted( lineLength, TRUE, stdout,
- "Abridged format is not really supported, the handle \
-supplies most of the information specified in the abridged format description \
-so we use the handle format instead." );
-
- case HANDLE:
- printFormatted( lineLength, FALSE, stdout,
- "#HANDLE %d", matches );
- for ( e = ldap_first_entry( ld, result ); e != NULL;
- e = ldap_next_entry( ld, e ) ) {
- objectClass = selectObjectClass( ld, e );
- printFormatted( lineLength, FALSE, stdout, " \"%s\" %s",
- ldap_get_dn( ld, e ),
- objectClassToTemplate( objectClass ) );
- if ( objectClass != NULL )
- free( objectClass );
- }
- printFormatted( lineLength, FALSE, stdout, "#END" );
- break;
-
- case SUMMARY:
- printFormatted( lineLength, FALSE, stdout, "#SUMMARY" );
- printFormatted( lineLength, FALSE, stdout, " matches: %d",
- matches );
- e = ldap_first_entry( ld, result );
- objectClass = selectObjectClass( ld, e );
- if ( ( objectClassTable = (char **)malloc(sizeof(char **)*matches) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Malloc failed" );
- break;
- }
- objectClassTable[number++] = objectClass;
- printFormatted( lineLength, FALSE, stdout, " templates: %s",
- objectClassToTemplate( objectClass ) );
- while ( ( e = ldap_next_entry( ld, e ) ) != NULL ) {
- objectClass = selectObjectClass( ld, e );
- /* have we printed this before? If not do it now */
- for ( i = 0; i < number; i++ )
- if ( EQ( objectClass, objectClassTable[i] ) )
- break;
- if ( i < number ) {
- if ( objectClass != NULL )
- free( objectClass );
- } else {
- objectClassTable[number++] = objectClass;
- printFormatted( lineLength, FALSE, stdout,
- " %s",
- objectClassToTemplate( objectClass ) );
- }
- }
- printFormatted( lineLength, FALSE, stdout, "#END" );
- for ( i = 0; i < number; i++ )
- if ( objectClassTable[i] != NULL )
- free( objectClassTable[i] );
- free( objectClassTable );
- break;
-
- }
- return TRUE;
-}
-
-static displayEntry( ld, dn, attributes )
-LDAP *ld;
-char *dn, *attributes[];
-{
- char *ufn;
- int i;
- char *s, *department;
- LDAPMessage *result, *entry;
-
- ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectclass=*", attributes,
- 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, TRUE, stdout,
- "Read on object \"%s\" failed, %s", dn,
- ldap_err2string( ld->ld_errno ) );
- return;
- }
-
- entry = ldap_first_entry( ld, result );
-
- if ( entry == NULL ) {
- /* something very weird has happened */
- printFormatted( lineLength, TRUE, stdout,
- "Possible conflict with ACLs for \"%s\"", dn );
- return;
- }
-
- /*
- * Get the UFN version of the DN and then cut it up into
- * name and department.
- */
- ufn = ldap_dn2ufn( dn );
- if ( ( s = index( ufn, ',' ) ) != NULL ) {
- *s++ = '\0';
- while ( *s != '\0' && isspace( *s ) )
- s++;
- department = s;
- while ( s != NULL && *s != '\0' && !EQ( s, organisation ) )
- if ( ( s = index( s, ',' ) ) != NULL ) {
- s++;
- while ( *s != '\0' && isspace( *s ) )
- s++;
- }
- if ( s != NULL )
- if ( s != department ) {
- while ( isspace( *--s ) )
- ;
- *s = '\0';
- } else
- department = NULL;
- } else
- department = NULL;
-
-/**/ /*
- * Name, Organization, Department, Organization-Type, and Handle
- * should be read in from language dictionary rather than hard coded.
- */
- printFormatted( lineLength, FALSE, stdout, " %-19s %s", "Name", ufn );
- if ( department != NULL && *department != '\0' )
- printFormatted( lineLength, FALSE, stdout,
- " %-19s %s", "Department", department );
- printFormatted( lineLength, FALSE, stdout, " %-19s %s",
- "Organization", organisation );
- if ( category != NULL )
- for ( i = 0; category[i] != NULL; i++ )
- printFormatted( lineLength, FALSE, stdout, " %-19s %s",
- "Organization-type", category[i] );
- for ( i = 0; attributes != NULL && attributes[i] != NULL; i++ ) {
- printAttribute( ld, attributes[i], entry );
- }
- printFormatted( lineLength, FALSE, stdout, " %-19s \"%s\"",
- "Handle", dn );
-
- free( ufn );
-}
-
-char *attributeLabel( attribute )
-char *attribute;
-
-{
-/**/ /* need to get printable string from language dictionary */
- return attribute;
-}
-
-static printAttribute( ld, attribute, entry )
-LDAP *ld;
-char *attribute;
-LDAPMessage *entry;
-{
- char **val;
- char *tag, *ptr;
- int i;
-
-/**/ /*
- * We really should determine whether the attribute value needs line
- * processing or not rather than just hard coding in a couple of cases
- * but for the moment we will ignore the problem.
- */
- if ( ( val = ldap_get_values( ld, entry, attribute )) == NULL )
- return;
-
- tag = attributeLabel( attribute );
- for ( i = 0; val[i] != NULL; i++ )
- if ( EQ( attribute, "lastModifiedTime" ) )
- printFormatted( lineLength, FALSE, stdout, " %-19s %s",
- tag, convertTime( val[i], locale ) );
- else if ( EQ( attribute, "postalAddress" )
- || EQ( attribute, "homePostalAddress" ) ) {
- printFormatted( lineLength, FALSE, stdout, " %-19s %s",
- tag, strtok( val[i], "$" ) );
- while ( ( ptr = strtok( NULL, "$" ) ) != NULL )
- printFormatted( lineLength, FALSE, stdout,
- " %-19s%s", "", ptr );
- } else
- printFormatted( lineLength, FALSE, stdout, " %-19s %s",
- tag, val[i] );
-
- ldap_value_free( val );
-}
-
-printFormatted( lineLength, systemMessage, output, format, va_alist )
-int lineLength, systemMessage;
-FILE *output;
-char *format;
-va_dcl
-
-{
- va_list ap;
- char buffer[BUFSIZ];
- char *head, *p, *q;
- char *tag;
- int count;
-
- if ( systemMessage ) {
- lineLength--;
- tag = "% ";
- } else
- tag = "";
- va_start( ap );
- vsprintf( buffer, format, ap );
- va_end( ap );
- if ( strlen( buffer ) < lineLength )
- fprintf( output, "%s%s\r\n", tag, buffer );
- else {
- head = buffer;
- do {
- count = strlen( tag );
- for ( q = head; *q && *q != ' '; q++ )
- count++;
- if ( *q == NULL ) {
- fprintf( output, "%s%s\r\n", tag, head );
- break;
- } else if ( count > lineLength ) {
- *q++ = '\0';
- fprintf( output, "%s%s\r\n", tag, head );
- head = q;
- } else {
- do {
- p = q++;
- count++;
- for (; *q && *q != ' '; q++ )
- count++;
- } while ( *p != '\0' && count <= lineLength );
- if ( *p != '\0' )
- *p++ = '\0';
- fprintf( output, "%s%s\r\n", tag, head );
- head = p;
- }
- if ( !systemMessage )
- tag = "+ ";
- } while ( *head != NULL );
- }
-}
+++ /dev/null
-*** Makefile-dist Fri Apr 23 15:29:24 1993
---- Makefile Fri Apr 23 15:33:04 1993
-***************
-*** 86,92 ****
-
- LDIRS = libldap liblber # library directories
- SDIRS = ldapd # server directories
-! CDIRS = finger gopher ud rcpt500 whois mail500 # client directories
- ALLDIRS = $(CDIRS) $(SDIRS) $(LDIRS)
-
- VERSION = 2.0 # set this to be the same as what's in ./version
---- 86,92 ----
-
- LDIRS = libldap liblber # library directories
- SDIRS = ldapd # server directories
-! CDIRS = finger gopher ud rcpt500 whois mail500 whois++ # client directories
- ALLDIRS = $(CDIRS) $(SDIRS) $(LDIRS)
-
- VERSION = 2.0 # set this to be the same as what's in ./version
-***************
-*** 99,105 ****
-
- lib-only: lber-library ldap-library
-
-! others: ldap-finger ldap-gopher ldap-ud ldap-rcpt500 ldap-whois ldap-mail500
-
- lber-library:
- @echo "cd liblber; $(MAKE) all"
---- 99,106 ----
-
- lib-only: lber-library ldap-library
-
-! others: ldap-finger ldap-gopher ldap-ud ldap-rcpt500 ldap-whois ldap-mail500 \
-! ldap-whois++
-
- lber-library:
- @echo "cd liblber; $(MAKE) all"
-***************
-*** 181,186 ****
---- 182,194 ----
- ETCDIR=$(ETCDIR) CC=$(CC) \
- all)
-
-+ ldap-whois++:
-+ @echo "cd whois++; $(MAKE) all"
-+ @(cd whois++; $(MAKE) ACFLAGS="$(ACFLAGS)" ALDFLAGS="$(ALDFLAGS)" \
-+ KRBLIBFLAG=$(KRBLIBFLAG) KRBLIBS="$(KRBLIBS)" \
-+ ETCDIR=$(ETCDIR) CC=$(CC) \
-+ all)
-+
- #
- # rules to install the software
- #
-***************
-*** 188,194 ****
- install: inst-include inst-server inst-lberlib inst-ldaplib inst-man
-
- inst-others: inst-finger inst-gopher inst-ud inst-rcpt500 inst-whois \
-! inst-mail500
-
- inst-lib: inst-lberlib inst-ldaplib
-
---- 196,202 ----
- install: inst-include inst-server inst-lberlib inst-ldaplib inst-man
-
- inst-others: inst-finger inst-gopher inst-ud inst-rcpt500 inst-whois \
-! inst-mail500 inst-whois++
-
- inst-lib: inst-lberlib inst-ldaplib
-
-***************
-*** 231,236 ****
---- 239,248 ----
- inst-whois:
- @echo "cd whois; $(MAKE) install"
- @( cd whois; $(MAKE) ETCDIR=$(ETCDIR) install )
-+
-+ inst-whois++:
-+ @echo "cd whois++; $(MAKE) inst-whois++"
-+ @( cd whois++; $(MAKE) ETCDIR=$(ETCDIR) inst-whois++ )
-
- inst-mail500:
- @echo "cd mail500; $(MAKE) install"
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * T E M P L A T E
- *
- * 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.7
- * Description:
- * This module deals with whois++ templates
- *
- * 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"
-
-void showTemplate( template )
-char *template;
-
-{
- char filename[MAXPATHLEN], buffer[BUFSIZ];
- FILE *description;
- int i;
-
- if ( template == NULL || *template == '\0' )
- return;
- sprintf( filename, "%s/templates/%s", configDir, template );
- if ( ( description = fopen( filename, "r" ) ) == NULL )
- printFormatted( lineLength, TRUE, stdout,
- "Cannot find template %s", template );
- else {
- while ( fgets( buffer, BUFSIZ, description ) != NULL ) {
- i = strlen( buffer );
- while ( i-- > 0 &&
- ( buffer[i] == '\n' || buffer[i] == '\r' ) )
- buffer[i] = '\0';
- printFormatted( lineLength, FALSE, stdout,
- " %s", buffer );
- }
- fclose( description );
- }
-}
-
-void listTemplates( query )
-char *query;
-
-{
- char filename[MAXPATHLEN];
- DIR *dir;
- struct dirent *entry;
-
- if ( query == NULL || *query == '\0' ) {
- sprintf( filename, "%s/templates", configDir );
- if ( ( dir = opendir( filename ) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Cannot access template descriptions - %s",
- strerror( errno ) );
- return;
- }
- for ( entry = readdir( dir ); entry != NULL; entry = readdir( dir ) )
- if ( !EQ(entry->d_name, "." ) && !EQ(entry->d_name, ".." ) )
- printFormatted( lineLength, FALSE, stdout,
- " %s", lowerCase( entry->d_name ) );
- closedir( dir );
- } else {
- sprintf( filename, "%s/templates/%s", configDir, query );
- if ( fopen( filename, "r" ) == NULL )
- printFormatted( lineLength, TRUE, stdout,
- "No such template (%s)", query );
- else
- printFormatted( lineLength, FALSE, stdout,
- " %s", query );
- }
-}
-
-char **specifyAttributes( objectClass )
-char *objectClass;
-
-{
- FILE *description;
- char filename[MAXPATHLEN], buffer[BUFSIZ];
- char **attributes;
- int max = ATTRIBUTE_INCREMENT;
- int i, number = 0;
-
- if ( objectClass == NULL || *objectClass == '\0' )
- return NULL;
- sprintf( filename, "%s/templates/%s", configDir,
- lowerCase( objectClass ) );
- if ( ( description = fopen( filename, "r" ) ) == NULL )
- return NULL;
- if ( ( attributes = (char **)malloc( max*sizeof(char *) ) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Error while attempting to create attribute list - %s",
- strerror( errno ) );
- return NULL;
- }
- while ( fgets( buffer, BUFSIZ, description ) != NULL ) {
- i = strlen( buffer );
- while ( i-- > 0 && ( buffer[i] == '\n' || buffer[i] == '\r' ) )
- buffer[i] = '\0';
- attributes[number++] = strdup( buffer );
- if ( number == max ) {
- max += ATTRIBUTE_INCREMENT;
- if ( ( attributes = (char **)realloc( attributes, max*sizeof(char *)) ) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Error while attempting to extend attribute list - %s",
- strerror( errno ) );
- return NULL;
- }
- }
- }
- attributes[number] = NULL;
- fclose( description );
- return attributes;
-}
-
-char *templateToObjectClass( template )
-char *template;
-
-{
- int i;
-
- if ( template == NULL || *template == '\0' ) {
- printFormatted( lineLength, TRUE, stdout,
- "Unrecognised template" );
- return "unrecognised";
- }
- for ( i = 0; i < numberOfTemplates; i++ )
- if ( EQ( template, templateTranslationTable[i].key ) )
- return templateTranslationTable[i].value;
- printFormatted( lineLength, TRUE, stdout,
- "Template (%s) not recognised, assuming that it is already an objectClass",
- template );
- return template;
-}
-
-char *objectClassToTemplate( objectClass )
-char *objectClass;
-
-{
- int i;
-
- if ( objectClass == NULL || *objectClass == '\0' ) {
- printFormatted( lineLength, TRUE, stdout,
- "Unrecognised template" );
- return "unrecognised";
- }
- for ( i = 0; i < numberOfTemplates; i++ )
- if ( EQ( objectClass, templateTranslationTable[i].value ) )
- return templateTranslationTable[i].key;
- return objectClass;
-}
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * U T I L
- *
- * Author: Mark R. Prior
- * Communications and Systems Branch
- * Information Technology Division
- * The University of Adelaide
- * E-mail: mrp@itd.adelaide.edu.au
- * Date: November 1992
- * Version: 1.7
- * Description:
- * Some routines that I use in most my LDAP playthings :-)
- *
- * 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 <stdio.h>
-#include <signal.h>
-#include <ctype.h>
-#if defined(SYS5) || defined(XOS_2)
-#include <termio.h>
-#else
-#include <sgtty.h>
-#endif
-#include <time.h>
-#if defined(INTERNATIONAL)
-#include <langinfo.h>
-#include <locale.h>
-#endif
-
-static void handler();
-
-char *lowerCase( string )
-char *string;
-
-{
- char *s;
-
- for ( s = string; s != NULL && *s != '\0'; s++ )
- if ( isupper( *s ) )
- *s = tolower( *s );
- return string;
-}
-
-char *convertTime( date, locale )
-char *date, *locale;
-
-{
- /*
- * A quick hack to convert the time from the format Quipu uses into
- * a more normal representation.
- */
- struct tm *tm;
- time_t time;
- static char result[BUFSIZ];
- int UTCOffset;
-
- /*
- * Get local timezone information, we need to apply this to the
- * zulu time that Quipu uses later.
- */
- time = 0;
- tm = localtime(&time);
- UTCOffset = tm->tm_gmtoff;
- sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
- &tm->tm_year, &tm->tm_mon, &tm->tm_mday,
- &tm->tm_hour, &tm->tm_min, &tm->tm_sec );
- tm->tm_mon--;
- tm->tm_isdst = 0;
- tm->tm_gmtoff = 0;
- time = mktime(tm);
- time += UTCOffset;
- tm = localtime(&time);
-#if defined(INTERNATIONAL)
- setlocale(LC_TIME, locale);
- strftime(result, sizeof(result), nl_langinfo(D_T_FMT), tm);
-#else
- strftime(result, sizeof(result), "%c", tm);
-#endif
- return result;
-}
-
-static long interrupt;
-
-char *getPassword( prompt )
-char *prompt;
-
-{
-#if defined(SYS5) || defined(XOS_2)
- struct termios ttyb;
-#else
- struct sgttyb ttyb;
-#endif
- FILE *input;
- struct sigvec ovec, vec;
- void handler();
- unsigned long flags;
- int c, idx;
- static char buffer[BUFSIZ + 1];
-
- if ( ( input = fopen( "/dev/tty", "r" ) ) == NULL )
- input = stdin;
- else
- setbuf( input, (char *) NULL );
- vec.sv_handler = handler;
- vec.sv_mask = 0;
- vec.sv_flags = SV_INTERRUPT;
- sigvec( SIGINT, &vec, &ovec );
- interrupt = 0;
-#if defined(SYS5) || defined(XOS_2)
- ioctl( fileno( input ), TCGETS, &ttyb );
- flags = ttyb.c_lflag;
- ttyb.c_lflags &= ~ ( ECHO | ECHOE | ECHOK | ECHONL );
- ioctl( fileno( input ), TCSETSF, &ttyb );
-#else
- ioctl( fileno( input ), TIOCGETP, &ttyb );
- flags = ttyb.sg_flags;
- ttyb.sg_flags &= ~ ECHO;
- ioctl( fileno( input ), TIOCSETN, &ttyb );
-#endif
- fputs( prompt, stderr );
- idx = 0;
- while ( !interrupt && ( c = getc( input ) ) != EOF ) {
- if ( c == '\n' || c == '\r' )
- break;
- if ( idx < BUFSIZ )
- buffer[idx++] = c;
- }
- if ( interrupt )
- buffer[0] = '\0';
- else
- buffer[idx] = '\0';
-#if defined(SYS5) || defined(XOS_2)
- ttyb.c_lflag = flags;
- ioctl( fileno( input ), TCSETSW, &ttyb );
-#else
- ttyb.sg_flags = flags;
- ioctl( fileno( input ), TIOCSETN, &ttyb );
-#endif
- putc( '\n', stderr );
- sigvec( SIGINT, &ovec, (struct sigvec *) NULL );
- if ( input != stdin )
- fclose( input );
- if ( interrupt )
- kill( getpid(), SIGINT );
- return buffer;
-}
-
-static void handler()
-
-{
- ++interrupt;
-}
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * V E R S I O N
- *
- * 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.7
- * Description:
- * Provide a minor revision number
- *
- * 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.
- */
-
-char *version()
-
-{
- return "1.7";
-}
+++ /dev/null
-#if !defined(lint)
-static char copyright[] = "Copyright 1992 The University of Adelaide";
-#endif
-
-/*
- * W H O I S + +
- *
- * 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.7
- * Description:
- * This is an experimental implementation of the proposed IETF
- * WNILS WG update to the whois/nicname protocol (whois++).
- *
- * 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 <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-static initialise();
-
-main( argc, argv )
-int argc;
-char **argv;
-{
- FILE *tailorFile, *bannerFile;
- char tailor[MAXPATHLEN];
- char query[BUFSIZ], buffer[BUFSIZ];
- char *s, *hostname, *remote;
- char **info;
- int i, printInfo = FALSE;
- extern char *optarg;
- LDAP *ld;
- LDAPMessage *result, *entry;
- int timelimit = DEFAULT_TIMELIMIT;
- struct hostent *hp;
- static struct sockaddr sa;
- struct sockaddr_in *sin = (struct sockaddr_in *) (&sa);
- /* #### length should be socklen_t when we include portable.h #### */
- int length = sizeof(sa);
- static char options[] = "[-b searchbase] [-d debug ] \
-[-h ldaphost ] [-i] [-l] [-s sizelimit] [-t timelimit] [-T tailorfile ] \
-[-u user] [-v]";
- static char *attributes[] =
- { "businessCategory", "info", NULL };
-
- if ( (program = strrchr( argv[0], '/' )) == NULL )
- program = strdup( argv[0] );
- else
- program = strdup( program + 1 );
-
-#if defined(LOG_DAEMON)
- openlog(program, LOG_PID, FACILITY );
-#else
- openlog(program, LOG_PID );
-#endif
-
- initialise();
-
- sprintf( tailor, "%s/%stailor", ETCDIR, program );
- if ( (tailorFile = fopen( tailor, "r" )) != NULL ) {
- readConfiguration( tailorFile );
- fclose( tailorFile );
- }
-
- while ( (i = getopt( argc, argv, "b:d:h:ils:t:T:u:v?" )) != EOF ) {
- switch ( i ) {
- case 'b': /* search base */
- base = strdup( optarg );
- break;
-
- case 'd': /* debug */
- debug = atoi( optarg );
- break;
-
- case 'h': /* ldap host */
- ldaphost = strdup( optarg );
- break;
-
- case 'i': /* print info attribute */
- printInfo = TRUE;
- break;
-
- case 'l': /* enable logging via syslog */
- log = TRUE;
- break;
-
- case 's': /* size limit */
- if ( ( maxHits = atoi( optarg ) ) < 1 ) {
- fprintf( stderr, "%s: Invalid maxhits value\n",
- program );
- syslog( LOG_ERR, "Invalid maxhits value" );
- exit( 1 );
- }
- maximumSize = maxHits;
- break;
-
- case 't': /* time limit */
- timelimit = atoi( optarg );
- break;
-
- case 'T': /* tailor file */
- if ( (tailorFile = fopen( optarg, "r" )) != NULL ) {
- readConfiguration( tailorFile );
- fclose( tailorFile );
- } else {
- perror( program );
- exit( 1 );
- }
- break;
-
- case 'u': /* user to bind as */
- user = strdup( optarg );
- break;
-
- case 'v': /* version */
- fprintf( stderr, "%s: %s %d.%s\n",
- program, RELEASE, REVISION, version() );
- exit( 0 );
-
- default: /* usage message, don't "fail" if ? */
- fprintf( stderr, "usage: %s %s\n", program, options );
- exit( i != '?' );
- }
- }
-
- language = defaultLanguage;
-
- /*
- * We can cope without knowing most things but we do need to know
- * where to start looking!
- */
- if ( base == NULL ) {
- syslog( LOG_ERR, "No base specified" );
- fprintf( stderr, "%s: No base specified.\n", program );
- exit( 1 );
- }
-
- if ( ! debug ) {
- if ( getpeername(0, &sa, &length) < 0) {
- perror( "getpeername" );
- exit( 1 );
- }
- if ( log ) {
- if ( ( hp = gethostbyaddr((char *) &sin->sin_addr,
- sizeof(sin->sin_addr), AF_INET) ) != 0 ) {
- hostname = strdup( hp->h_name );
- if ( ( hp = gethostbyname( hostname ) ) == 0 ) {
- free( hostname );
- hostname = strdup( inet_ntoa(sin->sin_addr) );
- }
- } else
- hostname = strdup( inet_ntoa(sin->sin_addr) );
-#if defined(RFC931)
- remote = rfc931_name( sin );
-#else
- remote = NULL;
-#endif
- syslog( LOG_INFO, "Connection from %s%s%s [%s]",
- (remote)?remote:"", (remote)?"@":"",
- hostname, inet_ntoa(sin->sin_addr) );
- }
- }
-
- if ( (ld = ldap_init( ldaphost, LDAP_PORT )) == NULL ) {
- printFormatted( lineLength, TRUE, stdout,
- "Connection to LDAP port on %s has failed", ldaphost );
- syslog( LOG_ERR, "Initialization of LDAP session (%s)",
- ldaphost );
- exit( 1 );
- }
- ld->ld_timelimit = timelimit;
- ld->ld_sizelimit = maxHits;
- ld->ld_deref = LDAP_DEREF_FINDING;
-
- ldap_simple_bind_s( ld, user, password );
- switch ( ld->ld_errno ) {
- case LDAP_SUCCESS:
- break;
-
- default:
- printFormatted( lineLength, TRUE, stdout,
- "Bind to Directory failed, %s",
- ldap_err2string( ld->ld_errno ) );
- syslog( LOG_ERR, "Bind to Directory failed, %s",
- ldap_err2string( ld->ld_errno ) );
- exit( 1 );
-
- }
-
- ldap_search_s( ld, base, LDAP_SCOPE_BASE, "objectclass=*",
- attributes, 0, &result );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- printFormatted( lineLength, TRUE, stdout,
- "Read of entry \"%s\" failed, %s",
- base, ldap_err2string( ld->ld_errno ) );
- exit( 1 );
- }
- entry = ldap_first_entry( ld, result );
- organisation = ldap_dn2ufn( ldap_get_dn( ld, entry ) );
- category = ldap_get_values( ld, entry, "businessCategory" );
-
- printFormatted( lineLength, FALSE, stdout,
- "Whois++ Service at %s.", ldap_dn2ufn( base ) );
- printFormatted( lineLength, FALSE, stdout,
- "For more information about this service send the \"help\" command." );
-
- if ( printInfo && ( info = ldap_get_values( ld, entry, "info" ) ) != NULL ) {
- for ( i = 0; info[i] != NULL; i++ ) {
- printFormatted( lineLength, FALSE, stdout, "" );
- printFormatted( lineLength, TRUE, stdout,
- "%s", info[i] );
- }
- ldap_value_free( info );
- }
- if ( banner != NULL && ( bannerFile = fopen( banner, "r" ) ) != NULL ) {
- printFormatted( lineLength, FALSE, stdout, "" );
- while ( fgets( buffer, BUFSIZ, bannerFile ) != NULL ) {
- i = strlen( buffer );
- while ( i-- > 0 && ( buffer[i] == '\n' || buffer[i] == '\r' ) )
- buffer[i] = '\0';
- printFormatted( lineLength, TRUE, stdout, "%s", buffer );
- }
- fclose( bannerFile );
- }
- printFormatted( lineLength, FALSE, stdout, "" );
-
- do {
- *query = '\0';
- holdConnection = FALSE;
- switch ( parseCommand( query ) ) {
- case READ:
- /* No need to search, just read the entry given! */
- ldap_search_s( ld, query, LDAP_SCOPE_BASE,
- "objectclass=*", NULL, 0, &result );
- switch( ld->ld_errno ) {
- case LDAP_SUCCESS:
- break;
-
- case LDAP_NO_SUCH_OBJECT:
-/**/ /* PROBABLY WANT SPECIAL PROCESSING HERE */
-
- default:
- printFormatted( lineLength, TRUE, stdout,
- "Read failed, %s",
- ldap_err2string( ld->ld_errno ) );
- return 1;
-
- }
- displayResult( ld, result, outputFormat );
- break;
-
- case SEARCH:
- if ( debug > 2 )
- fprintf( stderr, "LDAP Query %s\n", query );
- if ( log )
- syslog( LOG_INFO, "LDAP Query %s", query );
-
- ld->ld_sizelimit = maxHits;
- ldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, query,
- NULL, 0, &result );
- switch ( ld->ld_errno ) {
- case LDAP_SUCCESS:
- break;
-
- case LDAP_SIZELIMIT_EXCEEDED:
- printFormatted( lineLength, TRUE, stdout,
- "Partial results only - a size limit \
-was exceeded, only %d entries returned", ldap_count_entries( ld, result ) );
- break;
-
- case LDAP_TIMELIMIT_EXCEEDED:
- printFormatted( lineLength, TRUE, stdout,
- "Partial results only - a time limit \
-was exceeded." );
- break;
-
- default:
- printFormatted( lineLength, TRUE, stdout,
- "Search failed, %s",
- ldap_err2string( ld->ld_errno ) );
- exit( 1 );
-
- }
- displayResult( ld, result, outputFormat );
- break;
-
- case HELP:
- needHelp( lowerCase( query ) );
- break;
-
- case DESCRIBE:
- displayDescribe( ld, base );
- break;
-
- case VERSION:
- printFormatted( lineLength, TRUE, stdout,
- "Whois++ Protocol version %s", PROTOCOL );
- printFormatted( lineLength, TRUE, stdout,
- "Program version %s %d.%s",
- RELEASE, REVISION, version() );
- printFormatted( lineLength, TRUE, stdout,
- "Default language is %s", defaultLanguage );
- printFormatted( lineLength, TRUE, stdout,
- "Built by %s", BUILD );
- break;
-
- case LIST:
- listTemplates( lowerCase( query ) );
- break;
-
- case SHOW:
- showTemplate( lowerCase( query ) );
- break;
-
- case CONSTRAINTS:
- printFormatted( lineLength, TRUE, stdout,
- "This implementation supports the following constraints." );
- printFormatted( lineLength, TRUE, stdout,
- "Local constraints are" );
- printFormatted( lineLength, TRUE, stdout,
- " match=(exact|fuzzy)" );
- printFormatted( lineLength, TRUE, stdout,
- "Global constraints are" );
- printFormatted( lineLength, TRUE, stdout,
- " format=(full|abridged|handle|summary)" );
- printFormatted( lineLength, TRUE, stdout,
- " hold" );
- printFormatted( lineLength, TRUE, stdout,
- " language=<string>" );
- printFormatted( lineLength, TRUE, stdout,
- " linelength=<number>" );
- printFormatted( lineLength, TRUE, stdout,
- " maxhits=<number>" );
- break;
-
- case COMMAND:
- printFormatted( lineLength, TRUE, stdout,
- "Commands supported by this implementation are" );
- printFormatted( lineLength, TRUE, stdout,
- " command" );
- printFormatted( lineLength, TRUE, stdout,
- " constraints" );
- printFormatted( lineLength, TRUE, stdout,
- " describe" );
- printFormatted( lineLength, TRUE, stdout,
- " help" );
- printFormatted( lineLength, TRUE, stdout,
- " list" );
- printFormatted( lineLength, TRUE, stdout,
- " show" );
- printFormatted( lineLength, TRUE, stdout,
- " version" );
- break;
-
- case ERROR:
- break;
-
- }
- } while ( holdConnection );
- closelog();
- ldap_unbind( ld );
-}
-
-static initialise()
-
-{
- char buffer[BUFSIZ];
-
- debug = FALSE;
- maxHits = DEFAULT_SIZELIMIT;
- maximumSize = maxHits;
- outputFormat = NULL;
- lineLength = DEFAULT_LINE_LENGTH;
- ldaphost = DEFAULT_LDAPHOST;
- defaultLanguage = DEFAULT_LANGUAGE;
- locale = "";
- base = NULL;
- contact = NULL;
- if ( gethostname( buffer, BUFSIZ ) == 0 )
- hostname = strdup( buffer );
- else
- hostname = NULL;
- user = NULL;
- password = NULL;
- helpDir = HELP_DIRECTORY;
- configDir = CONFIG_DIRECTORY;
- organisation = NULL;
- banner = NULL;
- log = FALSE;
- numberOfTemplates = 0;
- tableSize = TABLE_INCREMENT;
- templateTranslationTable = NULL;
-}
+++ /dev/null
-/*
- * W H O I S + +
- *
- * 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
- * Copyright: (C) 1992, The University of Adelaide
- * Version: 1.7
- * Description:
- * This is an experimental implementation of the proposed IETF
- * WNILS WG update to the whois/nicname protocol (whois++).
- *
- * 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 <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <dirent.h>
-#if defined(INTERNATIONAL)
-#include <langinfo.h>
-#include <locale.h>
-#include <nl_types.h>
-#endif
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include "syslog.h"
-#include <ldap.h>
-
-#define EQ(x,y) (strcasecmp(x,y) == 0)
-
-#if defined(sun)
-extern int sys_nerr;
-extern char *sys_errlist[];
-#define strerror(_e) ( ( ( (_e) >= 0 ) && ( (_e) < sys_nerr ) ) ? \
- sys_errlist[(_e)] : "Undocumented error code" )
-#endif
-
-#if !defined(TRUE)
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#if defined(MAIN)
-#define EXTERN
-#else
-#define EXTERN extern
-#endif
-
-#if !defined(ABRIDGED_LIMIT)
-#define ABRIDGED_LIMIT 10
-#endif
-#if !defined(DEFAULT_LDAPHOST)
-#define DEFAULT_LDAPHOST "localhost"
-#endif
-#if !defined(DEFAULT_SIZELIMIT)
-#define DEFAULT_SIZELIMIT 50
-#endif
-#if !defined(DEFAULT_TIMELIMIT)
-#define DEFAULT_TIMELIMIT 60
-#endif
-#if !defined(HELP_DIRECTORY)
-#define HELP_DIRECTORY "/usr/local/isode/help/whois++"
-#endif
-#if !defined(CONFIG_DIRECTORY)
-#define CONFIG_DIRECTORY "/usr/local/isode/etc/whois++"
-#endif
-#if !defined(DEFAULT_LANGUAGE)
-#define DEFAULT_LANGUAGE "english"
-#endif
-
-#define ATTRIBUTE_INCREMENT 10
-#define TABLE_INCREMENT 10
-#define DEFAULT_LINE_LENGTH 80
-#define MIN_LINE_LENGTH 40
-#define MAX_LINE_LENGTH 200
-
-/*
- * Tokens
- */
-#define HELP 1
-#define LIST 2
-#define DESCRIBE 3
-#define VERSION 4
-#define SHOW 5
-#define CONSTRAINTS 6
-#define SEARCH 7
-#define TEMPLATE 8
-#define HANDLE 9
-#define ATTRIBUTE 10
-#define VALUE 11
-#define SEARCH_ALL 12
-#define COMMA 13
-#define ERROR 14
-#define EQUALS 15
-#define COLON 16
-#define SEMICOLON 17
-#define FULL 18
-#define ABRIDGED 19
-#define SUMMARY 20
-#define READ 21
-#define LANGUAGE 22
-#define FORMAT 23
-#define HOLD 24
-#define MAXHITS 25
-#define MATCH 26
-#define LINE_LENGTH 27
-#define COMMAND 28
-#define TRACE 29
-
-typedef struct {
- char *key;
- char *value;
- } table;
-
-EXTERN int debug, outputFormat, lineLength, holdConnection, log;
-EXTERN int maxHits, numberOfTemplates, tableSize, maximumSize;
-EXTERN char *program, *ldaphost, *language, *locale, *base;
-EXTERN char *contact, *hostname, *user, *password, *helpDir;
-EXTERN char *configDir, *organisation, *defaultLanguage;
-EXTERN char *banner;
-EXTERN char **category;
-EXTERN table *templateTranslationTable;
-
-extern int displayDescribe(), parseCommand(char *query);
-extern void needHelp(char *reason);
-extern void showTemplate(char *template), listTemplates(char *query);
-extern char **specifyAttributes(char *objectClass);
-extern char *lowerCase(char *string), *version(void), *attributeLabel();
-extern char *rfc931_name();
-extern char *templateToObjectClass(char *template);
+++ /dev/null
-.\" Copyright (c) 1993 The University of Adelaide.
-.\" All rights reserved.
-.\"
-.\" 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.
-.\"
-.\" @(#)whois++d.man 1.5
-.\"
-.TH WHOIS++D 8 "26 April 1993"
-.SH NAME
-whois++d \- Whois++ white pages server
-.SH SYNOPSIS
-.B whois++d
-[
-.B \-b
-.I basename
-] [
-.B \-d
-.I debuglevel
-] [
-.B \-h
-.I ldaphost
-] [
-.B \-i
-] [
-.B \-l
-] [
-.B \-s
-.I maxhits
-] [
-.B \-t
-.I timelimit
-] [
-.B \-T
-.I tailorfile
-] [
-.B \-u
-.I user
-] [
-.B \-v
-] [
-.B \-?
-]
-.SH DESCRIPTION
-.I Whois++d
-is an implementation of the new whois++ white pages server. The server is in
-reality a DUA interface that uses the lightweight directory access protocol
-[RFC????] to communicate with an X.500 Directory System Agent (DSA) via a
-.MS ldapd 8
-server. The whois++ architecture (and command format) is described in an
-Internet Draft of the IETF's WNILS Working Group.
-
-By default
-.I whois++d
-reads it's configuration information from a tailor file (whois++dtailor)
-located in the
-.IR ETCDIR
-but this may be supplemented by command line options, including the
-specification of a secondary tailor file.
-.PP
-Options are:
-.TP
-.B \-b
-Specify the base for all queries, this must be specified either via the
-commandline or (more normally) via the tailor file.
-.TP
-.B \-d
-Print debugging information.
-A number after the ``d'' determines the level of messages printed.
-.TP
-.B \-h
-Specify the host running the
-.MS ldapd 8
-server.
-.TP
-.B \-i
-If the entry for the ``base'' of the searches has an info attribute then
-print it as part of the welcome banner.
-.TP
-.B \-l
-Enable logging of queries via syslog.
-.TP
-.B \-s
-Specify the maximum number of entries you wish returned as a result of a
-search. This is normally controlled by the DSA but if this is not possible
-then it can be restricted via this option.
-.TP
-.B \-t
-Specify a timelimit for queries to the DSA. Note this is
-.B not
-the timeout limit between queries when using the
-.I hold
-constraint.
-.TP
-.B \-T
-Specify an additional tailor file. Useful if you only have a binary and the
-default location is not what you consider to be a ``normal'' place.
-.TP
-.B \-u
-Specify the user's DN to use when binding to the directory.
-.TP
-.B \-v
-Return the version number of this server and then exit.
-.TP
-.B \-?
-Print a list of valid commandline options and then exit.
-.SH "CONFIGURATION FILE"
-When started
-.B whois++d
-reads it's configuration file before processing any command line options.
-The configuration commands that may be included in this tailor file are
-.IP banner
-Specify a file to display as a welcome message.
-.IP base
-This specifies the entry within the DIT where searches will commence. This is
-normally set to the organisation's entry.
-.IP configdir
-Identifies where the configuration files may be found, currently only used
-for the template descriptions.
-.IP contact
-This is the distinguished name of the person responsible for this service, and
-whose entry will be displayed if the client uses the `describe' query. If this
-is not defined in the configuration file it defaults to the DSA manager.
-.IP helpdir
-This directory contains the multi-lingual help files. There should be a
-subdirectory for each language supported and within these subdirectories
-are helpfiles that are displayed by the server. At a minimum there should be
-an english directory containing a `general' helpfile (which contains
-introductory information).
-.IP hostname
-Used when the server is queried using the `describe' command. If not specified
-it will default to the local hostname.
-.IP language
-Specify the default language to be used when producing diagnostic messages.
-.IP ldaphost
-This specifies the host running a ldap server which can be used to communicate
-with the X.500 DSA.
-.IP password
-The password to use then binding to the X.500 DSA.
-.IP template
-The whois++ template name is not always the same as the X.500 object class
-so this option allows the two values to be associated with each other. The
-two values are template-name and objectclass-name.
-.IP user
-The LDAP distinguished name of the user to use when binding to the directory.
-This is optional but the DSA may restrict the information available to the
-whois++ server unless it authenticates itself.
-.NT
-Multi-lingual support is not available yet.
-.SH FILES
-ETCDIR/whois++dtailor whois++ server tailor file
-.SH "SEE ALSO"
-ldapd(8)
+++ /dev/null
-base "o=The University of Adelaide, c=AU"
-template user person
-template service applicationEntity
-template department organizationalUnit
-template role organizationalRole