]> git.sur5r.net Git - openldap/blob - clients/ud/util.c
Add OpenLDAP RCSid to *.[ch] in clients, libraries, and servers.
[openldap] / clients / ud / util.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright (c) 1992, 1993  Regents of the University of Michigan.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted
7  * provided that this notice is preserved and that due credit is given
8  * to the University of Michigan at Ann Arbor. The name of the University
9  * may not be used to endorse or promote products derived from this
10  * software without specific prior written permission. This software
11  * is provided ``as is'' without express or implied warranty.
12  */
13
14 #include "portable.h"
15
16 #include <stdio.h>
17
18 #include <ac/stdlib.h>
19
20 #include <ac/ctype.h>
21 #include <ac/errno.h>
22 #include <ac/signal.h>
23 #include <ac/string.h>
24 #include <ac/termios.h>
25 #include <ac/time.h>
26 #include <ac/unistd.h>
27
28 #include <lber.h>
29 #include <ldap.h>
30
31 #include "ldap_defaults.h"
32 #include "ud.h"
33
34 void
35 printbase( char *lead, char *s )
36 {
37         register char **cp;
38         char **rdns;
39
40 #ifdef DEBUG
41         if (debug & D_TRACE)
42                 printf("->printbase(%s, %s)\n", lead, s);
43 #endif
44         if (s == NULL) {
45                 printf("%sroot\n", lead);
46                 return;
47         }
48         printf("%s", lead);
49         rdns = ldap_explode_dn(s, TRUE);
50         for (cp = rdns; ; ) {
51                 printf("%s", friendly_name(*cp));
52                 cp++;
53                 if (*cp == NULL) {
54                         printf("\n");
55                         break;
56                 }
57                 else
58                         printf(", ");
59         }
60         ldap_value_free(rdns);
61         return;
62 }
63
64 void
65 fetch_buffer( char *buffer, int length, FILE *where )
66 {
67         register int i;
68         char *p;
69
70 #ifdef DEBUG
71         if (debug & D_TRACE)
72                 printf("->fetch_buffer(%x, %d, %x)\n", buffer, length, where);
73 #endif
74         /*
75          *  Fetch a buffer and strip off any leading or trailing non-printing
76          *  characters, namely newlines and carriage returns.
77          */
78         if (fgets(buffer, length, where) == NULL) {
79                 if (feof(where))
80                         errno = 0;       /* so fatal() doesn't bitch */
81                 fatal("fgets");
82         }
83         for (i = strlen(buffer) - 1;
84              i >= 0 && !isprint((unsigned char) buffer[i]); i--)
85                 buffer[i] = '\0';
86
87         p = buffer;
88         while ( *p != '\0' ) {
89                 if ( isprint( (unsigned char) *p )) {
90                         ++p;
91                 } else {
92                         SAFEMEMCPY( p, p + 1, strlen( p + 1 ) + 1 ); 
93                 }
94         }
95
96 }
97
98 void
99 fatal( char *s )
100 {
101         if (errno != 0)
102                 perror(s);
103 #ifdef HAVE_KERBEROS
104         destroy_tickets();
105 #endif
106         exit( EXIT_FAILURE );
107 }
108
109 int
110 isgroup( void )
111 {
112         char **vp;
113         register int i;
114         int group = FALSE;
115
116 #ifdef DEBUG
117         if (debug & D_TRACE)
118                 printf("->isgroup()\n");
119 #endif
120         if ((i = attr_to_index("objectClass")) == -1)
121                 return(FALSE);
122         vp = Entry.attrs[i].values;
123         for (i = 0; *vp != NULL; vp++) {
124 #ifdef DEBUG
125                 i++;
126                 if (debug & D_GROUPS)
127                         printf("class #%1d: (%s)\n", i, *vp);
128 #endif
129                 if (!strcmp(*vp, "rfc822MailGroup"))
130                         group = TRUE;
131         }
132         return(group);
133 }
134
135 /*
136  *  Print out the string 's' on a field of 'width' chracters.  Each line
137  *  should be indented 'lead' characters.
138  */
139 void
140 format( char *str, int width, int lead )
141 {
142         char *s, *original, *leader = "";
143         register char *cp;
144
145 #ifdef DEBUG
146         if (debug & D_TRACE)
147                 printf("->format(%s, %d, %d)\n", str, width, lead);
148 #endif
149         if (lead >= width) {
150                 fprintf(stderr, "  Cannot format (%s, %d, %d)\n", str, width, lead);
151                 return;
152         }
153         if (lead > 0) {
154                 leader = (char *) Malloc((unsigned) (lead + 1));
155                 (void) memset(leader, ' ', lead);
156                 *(leader + lead) = '\0';
157         }
158
159         /*
160          *  Some compilers get really unhappy with this function since it
161          *  fiddles around with the first argument, which could be a string
162          *  constant.  We do a strdup() here so we can do whatever the hell
163          *  we want.
164          */
165         s = original = strdup(str);
166         for (;;) {
167                 if (((int) strlen(s) + lead) < width) {
168                         printf("%s%s\n", leader, s);
169                         Free(leader);
170                         Free(original);
171                         return; 
172                         /*NOTREACHED*/
173                 }
174                 cp = s + width - lead;
175                 while (!isspace((unsigned char)*cp) && (cp != s))
176                         cp--;
177                 *cp = '\0';
178                 while (isspace((unsigned char)*s))
179                         s++;
180                 printf("%s%s\n", leader, s);
181                 s = cp + 1;
182         }
183 }
184
185 /*
186  *  Print out the string 's' on a field of 'width' chracters.  The first line
187  *  should be indented 'first_indent' spaces, then followed by 'first_tag', 
188  *  and then followed by the first line of 's'.  Subsequent lines should be
189  *  indented 'indent' spaces, then followed by 'tag', and then followed by
190  *  subsequent lines of 's'.
191  */
192 void
193 format2(
194     char *s,
195     char *first_tag,
196     char *tag,
197     int first_indent,
198     int indent,
199     int width
200 )
201 {
202         char c, *fi, *i;
203         register char *cp;
204
205         if (first_tag == NULL)
206                 first_tag = "";
207         if (tag == NULL)
208                 tag = "";
209 #ifdef DEBUG
210         if (debug & D_TRACE)
211                 printf("format2(\"%s\", \"%s\", \"%s\", %1d, %1d, %1d)\n", s, 
212                                 first_tag, tag, first_indent, indent, width);
213 #endif
214
215         /* make sure the indents are sane */
216         if ((first_indent >= width) || (indent >= width)) {
217                 fprintf(stderr, "  Cannot format:  indent too large\n");
218                 return;
219         }
220
221         /* make the indentations */
222         if (first_indent > 0) {
223                 fi = (char *) Malloc((unsigned) (first_indent + 1));
224                 (void) memset(fi, ' ', first_indent);
225                 *(fi + first_indent) = '\0';
226         }
227         else
228                 fi = "";
229         if (indent > 0) {
230                 i = (char *) Malloc((unsigned) (indent + 1));
231                 (void) memset(i, ' ', indent);
232                 *(i + indent) = '\0';
233         }
234         else
235                 i = "";
236
237         /* now do the first line */
238         if (((int) strlen(s) + (int) strlen(first_tag) + first_indent) < width) {
239                 printf("%s%s%s\n", fi, first_tag, s);
240                 Free(fi);
241                 Free(i);
242                 return; 
243                 /*NOTREACHED*/
244         }
245
246         /*
247          *  's' points to the beginning of the string we want to print.
248          *  We point 'cp' to the end of the maximum amount of text we
249          *  can print (i.e., total width less the indentation and the
250          *  length of the tag).  Once we have set 'cp' initially we
251          *  back it up to the first space character.
252          */
253         cp = s + width - first_indent - strlen(first_tag);
254         while (!isspace((unsigned char)*cp) && (cp != s))
255                 cp--;
256
257         /*
258          *  Once there, we change that space character to a null, print the
259          *  string, and then restore the space character.
260          */
261         c = *cp;
262         *cp = '\0';
263         printf("%s%s%s\n", fi, first_tag, s);
264         *cp = c;
265
266         /*
267          *  Since 'cp' may have been set to a space initially (and so no
268          *  back-tracking was performed), it could have a space after it
269          *  as well.  We should gobble up all of these since we don't want
270          *  unexpected leading blanks.
271          */  
272         for (s = cp + 1; isspace((unsigned char)*s); s++)
273                 ;
274
275         /* now do all of the other lines */
276         for (;;) {
277                 if (((int) strlen(s) + (int) strlen(tag) + indent) < width) {
278                         printf("%s%s%s\n", i, tag, s);
279                         Free(fi);
280                         Free(i);
281                         return; 
282                         /*NOTREACHED*/
283                 }
284                 cp = s + width - indent - strlen(tag);
285                 while (!isspace((unsigned char)*cp) && (cp != s))
286                         cp--;
287                 c = *cp;
288                 *cp = '\0';
289                 printf("%s%s%s\n", i, tag, s);
290                 s = cp + 1;
291                 *cp = c;                        /* don't mess up 's' */
292         }
293 }
294
295 #define IN_A_QUOTE   0
296 #define OUT_OF_QUOTE 1
297
298 char *
299 strip_ignore_chars( char *cp )
300 {
301         int had_a_comma = FALSE;
302         int flag = OUT_OF_QUOTE;
303         register char *rcp, *cp1;
304         char *tmp;
305
306 #ifdef DEBUG
307         if (debug & D_TRACE)
308                 printf("strip_ignore_chars(%s)\n", cp);
309 #endif
310         for (rcp = cp; *rcp != '\0'; rcp++)
311                 if (isignorechar(*rcp) || (*rcp == '"'))
312                         break;
313         if (*rcp == '\0')
314                 return(cp);
315
316         cp1 = tmp = (char *) Malloc((unsigned) strlen(cp));
317         for (rcp = cp; *rcp != '\0'; rcp++) {
318                 /* toss quotes and flip the flag */
319                 if (*rcp == '"')
320                         flag = OUT_OF_QUOTE - flag;
321                 else if (isignorechar(*rcp)) {
322                         if (flag == OUT_OF_QUOTE)
323                                 *cp1++ = ' ';
324                         else
325                                 *cp1++ = *rcp;
326                 }
327                 else if (*rcp == ',') {
328                         *cp1++ = *rcp;
329                         had_a_comma = TRUE;
330                 }
331                 else 
332                         *cp1++ = *rcp;
333         }
334         *cp1 = '\0';
335
336         /* re-quote the name if it had a comma in it */
337         if (had_a_comma == TRUE) {
338                 rcp = cp1 = (char *) Malloc((unsigned) (strlen(tmp) + 3));
339                 *rcp++ = '"';
340                 *rcp = '\0';
341                 strcat(rcp, tmp);
342                 strcat(rcp, "\"");
343                 Free(tmp);
344                 tmp = cp1;
345         }
346         return(tmp);
347 }
348
349 char *
350 code_to_str( int i )
351 {
352         switch(i) {
353         case LDAP_MOD_ADD : return("ADD");
354         case LDAP_MOD_DELETE : return("DELETE");
355         case LDAP_MOD_REPLACE : return("REPLACE");
356         default : return("?????");
357         }
358 }
359
360 char *
361 friendly_name( char *s )
362 {
363         static LDAPFriendlyMap *map = NULL;
364         static char *cp;
365
366         cp = ldap_friendly_name(FRIENDLYFILE, s, &map);
367         if (cp == NULL)
368                 return(s);
369         return(cp);
370 }
371
372 #ifdef UOFM
373
374 /* return TRUE if s has the syntax of a uniqname */
375 int
376 isauniqname( char *s )
377 {
378         int i = strlen(s);
379
380         if ((i < 3) || (i > 8))         /* uniqnames are 3-8 chars */
381                 return(FALSE);
382         if (!isalpha((unsigned char)*s)) /* uniqnames begin with a letter */
383                 return(FALSE);
384         for ( ; *s != '\0'; s++)        /* uniqnames are alphanumeric */
385                 if (!isalnum((unsigned char)*s))
386                         return(FALSE);
387         return(TRUE);
388 }
389 #endif
390
391 /* return TRUE if this attribute should be printed as a DN */
392 int
393 isadn( char *s )
394 {
395         register int i;
396
397         for (i = 0; attrlist[i].quipu_name != NULL; i++)
398                 if (!strcasecmp(s, attrlist[i].quipu_name))
399                         break;
400         if (attrlist[i].flags & ATTR_FLAG_IS_A_DN)
401                 return(TRUE);
402         return(FALSE);
403 }
404
405 char *
406 my_ldap_dn2ufn( char *s )
407 {
408         register char **cpp;
409         static char short_DN[BUFSIZ];
410
411         if (strstr(s, NULL) == NULL)
412                 return(ldap_dn2ufn(s));
413         cpp = ldap_explode_dn(s, TRUE);
414         sprintf(short_DN, "%s, %s", *cpp, *(cpp + 1));
415         ldap_value_free(cpp);
416         return(short_DN);
417 }
418
419 /* return TRUE if this attribute should be printed as a URL */
420 int
421 isaurl( char *s )
422 {
423         register int i;
424
425         for (i = 0; attrlist[i].quipu_name != NULL; i++)
426                 if (!strcasecmp(s, attrlist[i].quipu_name))
427                         break;
428         if (attrlist[i].flags & ATTR_FLAG_IS_A_URL)
429                 return(TRUE);
430         return(FALSE);
431 }
432
433 /* return TRUE if this attribute should be printed as a date and time */
434 int
435 isadate( char *s )
436 {
437         register int i;
438
439         for (i = 0; attrlist[i].quipu_name != NULL; i++)
440                 if (!strcasecmp(s, attrlist[i].quipu_name))
441                         break;
442         if (attrlist[i].flags & ATTR_FLAG_IS_A_DATE)
443                 return(TRUE);
444         return(FALSE);
445 }
446
447 void *
448 Malloc( unsigned int size )
449 {
450         void *void_ptr;
451
452         void_ptr = (void *) malloc(size);
453         if (void_ptr == NULL) {
454                 perror("malloc");
455                 exit( EXIT_FAILURE );
456                 /*NOTREACHED*/
457         }
458         return(void_ptr);
459 }
460
461 void
462 Free( void *ptr )
463 {
464         free(ptr);
465 }
466
467 char *
468 nextstr( char *s )
469 {
470         while (isspace((unsigned char) *s) && (*s != '\0'))
471                 s++;
472         if (s == NULL)
473                 return(NULL);
474         if (*s == '\0')
475                 return(NULL);
476         return(s);
477 }
478
479 void
480 free_mod_struct( LDAPMod *modp )
481 {
482         if (modp->mod_values != NULL)
483                 (void) ldap_value_free(modp->mod_values);
484         Free(modp->mod_type);
485         Free(modp);
486 }
487
488 void
489 StrFreeDup( char **ptr, char *new_value )
490 {
491         if (*ptr != NULL)
492                 Free(*ptr);
493         if (new_value == NULL)
494                 *ptr = NULL;
495         else
496                 *ptr = strdup(new_value);
497 }
498
499
500 int
501 confirm_action( char *msg )
502
503         char    tmp[SMALL_BUF_SIZE];
504         int     i;
505
506         if ( msg != NULL ) {
507                 putchar( '\n' );
508                 format( msg, 75, 2 );
509         }
510
511         printf("\n  Is this OK? ");
512         fflush(stdout);
513         tmp[0] = '\0';
514         fetch_buffer(tmp, sizeof(tmp), stdin);
515         i = strlen(tmp);
516         return( i > 0 &&
517             ( !strncasecmp(tmp, "YES", i) || !strncasecmp(tmp, "OK", i)));
518 }