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