openldap/contrib/whois++/whois++.c
1999-07-16 18:59:37 +00:00

419 lines
11 KiB
C

#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;
case LDAP_UNAVAILABLE:
printFormatted( lineLength, TRUE, stdout,
"Sorry, the X.500 service is temporarily unavailable. \
Please try again later." );
syslog( LOG_NOTICE, "X.500 service temporarily unavailable" );
exit( 1 );
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;
}