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