]> git.sur5r.net Git - openldap/blob - contrib/whois++/whois++.c
Update lutil_lockf (aka: ldap_lockf) to hide implementation in
[openldap] / contrib / whois++ / whois++.c
1 #if !defined(lint)
2 static char copyright[] = "Copyright 1992 The University of Adelaide";
3 #endif
4
5 /*
6  *                      W H O I S + +
7  *
8  * Author:      Mark R. Prior
9  *              Communications and Systems Branch
10  *              Information Technology Division
11  *              The University of Adelaide
12  * E-mail:      mrp@itd.adelaide.edu.au
13  * Date:        October 1992
14  * Version:     1.7
15  * Description:
16  *      This is an experimental implementation of the proposed IETF
17  *      WNILS WG update to the whois/nicname protocol (whois++).
18  *
19  * Redistribution and use in source and binary forms are permitted
20  * provided that the above copyright notice and this paragraph are
21  * duplicated in all such forms and that any documentation,
22  * advertising materials, and other materials related to such
23  * distribution and use acknowledge that the software was developed
24  * by the University of Adelaide. The name of the University may not
25  * be used to endorse or promote products derived from this software
26  * without specific prior written permission.
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
28  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
29  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  */
31
32 #include "whois++.h"
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <netdb.h>
36
37 static initialise();
38
39 main( argc, argv )
40 int     argc;
41 char    **argv;
42 {
43         FILE                    *tailorFile, *bannerFile;
44         char                    tailor[MAXPATHLEN];
45         char                    query[BUFSIZ], buffer[BUFSIZ];
46         char                    *s, *hostname, *remote;
47         char                    **info;
48         int                     i, printInfo = FALSE;
49         extern char             *optarg;
50         LDAP                    *ld;
51         LDAPMessage             *result, *entry;
52         int                     timelimit = DEFAULT_TIMELIMIT;
53         struct hostent          *hp;
54         static struct sockaddr  sa;
55         struct sockaddr_in      *sin = (struct sockaddr_in *) (&sa);
56         int                     length = sizeof(sa);
57         static char             options[] = "[-b searchbase] [-d debug ] \
58 [-h ldaphost ] [-i] [-l] [-s sizelimit] [-t timelimit] [-T tailorfile ] \
59 [-u user] [-v]";
60         static char             *attributes[] =
61                                         { "businessCategory", "info", NULL };
62
63         if ( (program = strrchr( argv[0], '/' )) == NULL )
64                 program = strdup( argv[0] );
65         else
66                 program = strdup( program + 1 );
67
68 #if defined(LOG_DAEMON)
69         openlog(program, LOG_PID, FACILITY );
70 #else
71         openlog(program, LOG_PID );
72 #endif
73
74         initialise();
75
76         sprintf( tailor, "%s/%stailor", ETCDIR, program );
77         if ( (tailorFile = fopen( tailor, "r" )) != NULL ) {
78                 readConfiguration( tailorFile );
79                 fclose( tailorFile );
80         }
81
82         while ( (i = getopt( argc, argv, "b:d:h:ils:t:T:u:v?" )) != EOF ) {
83                 switch ( i ) {
84                 case 'b':       /* search base */
85                         base = strdup( optarg );
86                         break;
87
88                 case 'd':       /* debug */
89                         debug = atoi( optarg );
90                         break;
91
92                 case 'h':       /* ldap host */
93                         ldaphost = strdup( optarg );
94                         break;
95
96                 case 'i':       /* print info attribute */
97                         printInfo = TRUE;
98                         break;
99
100                 case 'l':       /* enable logging via syslog */
101                         log = TRUE;
102                         break;
103
104                 case 's':       /* size limit */
105                         if ( ( maxHits = atoi( optarg ) ) < 1 ) {
106                                 fprintf( stderr, "%s: Invalid maxhits value\n",
107                                         program );
108                                 syslog( LOG_ERR, "Invalid maxhits value" );
109                                 exit( 1 );
110                         }
111                         maximumSize = maxHits;
112                         break;
113
114                 case 't':       /* time limit */
115                         timelimit = atoi( optarg );
116                         break;
117
118                 case 'T':       /* tailor file */
119                         if ( (tailorFile = fopen( optarg, "r" )) != NULL ) {
120                                 readConfiguration( tailorFile );
121                                 fclose( tailorFile );
122                         } else {
123                                 perror( program );
124                                 exit( 1 );
125                         }
126                         break;
127
128                 case 'u':       /* user to bind as */
129                         user = strdup( optarg );
130                         break;
131
132                 case 'v':       /* version */
133                         fprintf( stderr, "%s: %s %d.%s\n",
134                                 program, RELEASE, REVISION, version() );
135                         exit( 0 );
136
137                 default:        /* usage message, don't "fail" if ? */
138                         fprintf( stderr, "usage: %s %s\n", program, options );
139                         exit( i != '?' );
140                 }
141         }
142
143         language = defaultLanguage;
144
145         /*
146          * We can cope without knowing most things but we do need to know
147          * where to start looking!
148          */
149         if ( base == NULL ) {
150                 syslog( LOG_ERR, "No base specified" );
151                 fprintf( stderr, "%s: No base specified.\n", program );
152                 exit( 1 );
153         }
154
155         if ( ! debug ) {
156                 if ( getpeername(0, &sa, &length) < 0) {
157                         perror( "getpeername" );
158                         exit( 1 );
159                 }
160                 if ( log ) {
161                         if ( ( hp = gethostbyaddr((char *) &sin->sin_addr,
162                                 sizeof(sin->sin_addr), AF_INET) ) != 0 ) {
163                                 hostname = strdup( hp->h_name );
164                                 if ( ( hp = gethostbyname( hostname ) ) == 0 ) {
165                                         free( hostname );
166                                         hostname = strdup( inet_ntoa(sin->sin_addr) );
167                                 }
168                         } else
169                                 hostname = strdup( inet_ntoa(sin->sin_addr) );
170 #if defined(RFC931)
171                         remote = rfc931_name( sin );
172 #else
173                         remote = NULL;
174 #endif
175                         syslog( LOG_INFO, "Connection from %s%s%s [%s]",
176                                 (remote)?remote:"", (remote)?"@":"",
177                                 hostname, inet_ntoa(sin->sin_addr) );
178                 }
179         }
180
181         if ( (ld = ldap_open( ldaphost, LDAP_PORT )) == NULL ) {
182                 printFormatted( lineLength, TRUE, stdout,
183                         "Connection to LDAP port on %s has failed", ldaphost );
184                 syslog( LOG_ERR, "Connection to LDAP port on %s has failed",
185                         ldaphost );
186                 exit( 1 );
187         }
188         ld->ld_timelimit = timelimit;
189         ld->ld_sizelimit = maxHits;
190         ld->ld_deref = LDAP_DEREF_FINDING;
191
192         ldap_simple_bind_s( ld, user, password );
193         switch ( ld->ld_errno ) {
194         case LDAP_SUCCESS:
195                 break;
196
197         case LDAP_UNAVAILABLE:
198                 printFormatted( lineLength, TRUE, stdout,
199                         "Sorry, the X.500 service is temporarily unavailable. \
200 Please try again later." );
201                 syslog( LOG_NOTICE, "X.500 service temporarily unavailable" );
202                 exit( 1 );
203
204         default:
205                 printFormatted( lineLength, TRUE, stdout,
206                         "Bind to Directory failed, %s",
207                         ldap_err2string( ld->ld_errno ) );
208                 syslog( LOG_ERR, "Bind to Directory failed, %s",
209                         ldap_err2string( ld->ld_errno ) );
210                 exit( 1 );
211
212         }
213
214         ldap_search_s( ld, base, LDAP_SCOPE_BASE, "objectclass=*",
215                 attributes, 0, &result );
216         if ( ld->ld_errno != LDAP_SUCCESS ) {
217                 printFormatted( lineLength, TRUE, stdout,
218                         "Read of entry \"%s\" failed, %s",
219                         base, ldap_err2string( ld->ld_errno ) );
220                 exit( 1 );
221         }
222         entry = ldap_first_entry( ld, result );
223         organisation = ldap_dn2ufn( ldap_get_dn( ld, entry ) );
224         category = ldap_get_values( ld, entry, "businessCategory" );
225
226         printFormatted( lineLength, FALSE, stdout,
227                 "Whois++ Service at %s.", ldap_dn2ufn( base ) );
228         printFormatted( lineLength, FALSE, stdout,
229                 "For more information about this service send the \"help\" command." );
230
231         if ( printInfo && ( info = ldap_get_values( ld, entry, "info" ) ) != NULL ) {
232                 for ( i = 0; info[i] != NULL; i++ ) {
233                         printFormatted( lineLength, FALSE, stdout, "" );
234                         printFormatted( lineLength, TRUE, stdout,
235                                 "%s", info[i] );
236                 }
237                 ldap_value_free( info );
238         }
239         if ( banner != NULL && ( bannerFile = fopen( banner, "r" ) ) != NULL ) {
240                 printFormatted( lineLength, FALSE, stdout, "" );
241                 while ( fgets( buffer, BUFSIZ, bannerFile ) != NULL ) {
242                         i = strlen( buffer );
243                         while ( i-- > 0 && ( buffer[i] == '\n' || buffer[i] == '\r' ) )
244                                 buffer[i] = '\0';
245                         printFormatted( lineLength, TRUE, stdout, "%s", buffer );
246                 }
247                 fclose( bannerFile );
248         }
249         printFormatted( lineLength, FALSE, stdout, "" );
250
251         do {
252                 *query = '\0';
253                 holdConnection = FALSE;
254                 switch ( parseCommand( query ) ) {
255                 case READ:
256                         /* No need to search, just read the entry given! */
257                         ldap_search_s( ld, query, LDAP_SCOPE_BASE,
258                                 "objectclass=*", NULL, 0, &result );
259                         switch( ld->ld_errno ) {
260                         case LDAP_SUCCESS:
261                                 break;
262                 
263                         case LDAP_NO_SUCH_OBJECT:
264 /**/                            /* PROBABLY WANT SPECIAL PROCESSING HERE */
265
266                         default:
267                                 printFormatted( lineLength, TRUE, stdout,
268                                         "Read failed, %s",
269                                         ldap_err2string( ld->ld_errno ) );
270                                 return 1;
271
272                         }
273                         displayResult( ld, result, outputFormat );
274                         break;
275
276                 case SEARCH:
277                         if ( debug > 2 )
278                                 fprintf( stderr, "LDAP Query %s\n", query );
279                         if ( log )
280                                 syslog( LOG_INFO, "LDAP Query %s", query );
281
282                         ld->ld_sizelimit = maxHits;
283                         ldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, query,
284                                 NULL, 0, &result );
285                         switch ( ld->ld_errno ) {
286                         case LDAP_SUCCESS:
287                                 break;
288
289                         case LDAP_SIZELIMIT_EXCEEDED:
290                                 printFormatted( lineLength, TRUE, stdout,
291                                         "Partial results only - a size limit \
292 was exceeded, only %d entries returned", ldap_count_entries( ld, result ) );
293                                 break;
294
295                         case LDAP_TIMELIMIT_EXCEEDED:
296                                 printFormatted( lineLength, TRUE, stdout,
297                                         "Partial results only - a time limit \
298 was exceeded." );
299                                 break;
300
301                         default:
302                                 printFormatted( lineLength, TRUE, stdout,
303                                         "Search failed, %s",
304                                         ldap_err2string( ld->ld_errno ) );
305                                 exit( 1 );
306
307                         }
308                         displayResult( ld, result, outputFormat );
309                         break;
310
311                 case HELP:
312                         needHelp( lowerCase( query ) );
313                         break;
314
315                 case DESCRIBE:
316                         displayDescribe( ld, base );
317                         break;
318
319                 case VERSION:
320                         printFormatted( lineLength, TRUE, stdout,
321                                 "Whois++ Protocol version %s", PROTOCOL );
322                         printFormatted( lineLength, TRUE, stdout,
323                                 "Program version %s %d.%s",
324                                 RELEASE, REVISION, version() );
325                         printFormatted( lineLength, TRUE, stdout,
326                                 "Default language is %s", defaultLanguage );
327                         printFormatted( lineLength, TRUE, stdout,
328                                 "Built by %s", BUILD );
329                         break;
330
331                 case LIST:
332                         listTemplates( lowerCase( query ) );
333                         break;
334
335                 case SHOW:
336                         showTemplate( lowerCase( query ) );
337                         break;
338
339                 case CONSTRAINTS:
340                         printFormatted( lineLength, TRUE, stdout, 
341                                 "This implementation supports the following constraints." );
342                         printFormatted( lineLength, TRUE, stdout, 
343                                 "Local constraints are" );
344                         printFormatted( lineLength, TRUE, stdout, 
345                                 "    match=(exact|fuzzy)" );
346                         printFormatted( lineLength, TRUE, stdout, 
347                                 "Global constraints are" );
348                         printFormatted( lineLength, TRUE, stdout, 
349                                 "    format=(full|abridged|handle|summary)" );
350                         printFormatted( lineLength, TRUE, stdout, 
351                                 "    hold" );
352                         printFormatted( lineLength, TRUE, stdout, 
353                                 "    language=<string>" );
354                         printFormatted( lineLength, TRUE, stdout, 
355                                 "    linelength=<number>" );
356                         printFormatted( lineLength, TRUE, stdout, 
357                                 "    maxhits=<number>" );
358                         break;
359
360                 case COMMAND:
361                         printFormatted( lineLength, TRUE, stdout,
362                                 "Commands supported by this implementation are" );
363                         printFormatted( lineLength, TRUE, stdout,
364                                 "    command" );
365                         printFormatted( lineLength, TRUE, stdout,
366                                 "    constraints" );
367                         printFormatted( lineLength, TRUE, stdout,
368                                 "    describe" );
369                         printFormatted( lineLength, TRUE, stdout,
370                                 "    help" );
371                         printFormatted( lineLength, TRUE, stdout,
372                                 "    list" );
373                         printFormatted( lineLength, TRUE, stdout,
374                                 "    show" );
375                         printFormatted( lineLength, TRUE, stdout,
376                                 "    version" );
377                         break;
378
379                 case ERROR:
380                         break;
381
382                 }
383         } while ( holdConnection );
384         closelog();
385         ldap_unbind( ld );
386 }
387
388 static initialise()
389
390 {
391         char    buffer[BUFSIZ];
392
393         debug = FALSE;
394         maxHits = DEFAULT_SIZELIMIT;
395         maximumSize = maxHits;
396         outputFormat = NULL;
397         lineLength = DEFAULT_LINE_LENGTH;
398         ldaphost = DEFAULT_LDAPHOST;
399         defaultLanguage = DEFAULT_LANGUAGE;
400         locale = "";
401         base = NULL;
402         contact = NULL;
403         if ( gethostname( buffer, BUFSIZ ) == 0 )
404                 hostname = strdup( buffer );
405         else
406                 hostname = NULL;
407         user = NULL;
408         password = NULL;
409         helpDir = HELP_DIRECTORY;
410         configDir = CONFIG_DIRECTORY;
411         organisation = NULL;
412         banner = NULL;
413         log = FALSE;
414         numberOfTemplates = 0;
415         tableSize = TABLE_INCREMENT;
416         templateTranslationTable = NULL;
417 }