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