]> git.sur5r.net Git - openldap/blob - contrib/tweb/support.c
Update man page date.
[openldap] / contrib / tweb / support.c
1 /*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 *                                                                          *
3 * support.c..                                                              *
4 *                                                                          *
5 * Function:..WorldWideWeb-X.500-Gateway - Supporting Routines              *
6 *            Based on web500gw.c 1.3 written by Frank Richter, TU Chemmniz *
7 *            which is based on go500gw by Tim Howes, University of         *
8 *            Michigan  - All rights reserved                               *
9 *                                                                          *
10 * Authors:...Dr. Kurt Spanier & Bernhard Winkler,                          *
11 *            Zentrum fuer Datenverarbeitung, Bereich Entwicklung           *
12 *            neuer Dienste, Universitaet Tuebingen, GERMANY                *
13 *                                                                          *
14 *                                       ZZZZZ  DDD    V   V                *
15 *            Creation date:                Z   D  D   V   V                *
16 *            August 16 1995               Z    D   D   V V                 *
17 *            Last modification:          Z     D  D    V V                 *
18 *            September 7 1999           ZZZZ   DDD      V                  *
19 *                                                                          *
20 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
21
22 /*
23  * $Id: support.c,v 1.6 1999/09/10 15:01:20 zrnsk01 Exp $
24  *
25  */
26
27 #include "tgeneral.h"
28 #include "tglobal.h"
29 #include "init_exp.h"
30 #include "support.h"
31
32 /*
33  *  Utilities for dealing with HTML junk
34  */
35
36 char hex[17] = "0123456789abcdef";
37 char buffer[1024];
38
39 PUBLIC char * hex_decode (in)
40 char *in;
41 {
42         char b, c;
43         int q = 0;
44         char *out = in;
45
46         while (*in) {
47         if (*in == '?')        /* start search */
48             q = 1;
49                 if (*in == '%') {    /* Hex escape */
50                         in++;
51                         if(!(c = *in++)) break;
52                         b = from_hex(c);
53                         if(!(c = *in++)) break;
54                         *out++ = (b<<4) + from_hex(c);
55                 } else if (q && *in == '+') {
56             /* '+' is legal in path, in search it's a ' ' */
57             *out++ = ' ';
58             in++;
59         } else {
60                         *out++ = *in++;
61                 }
62         }
63         *out = '\0';
64         return (out);
65 }
66 /* end of function: hex_decode */
67
68 /* decode in search (for do_modify) */
69
70 PUBLIC char * hex_qdecode (in)
71 char *in;
72 {
73         char b, c;
74         char *out = in;
75
76         while (*in) {
77                 if (*in == '%') {     /* Hex escape */
78                         in++;
79                         if(!(c = *in++)) break;
80                         b = from_hex(c);
81                         if(!(c = *in++)) break;
82                         *out++ = (b<<4) + from_hex(c);
83                 } else if (*in == '+') { /* we are in search, so: '+' -> ' ' */
84                         *out++ = ' ';
85                         in++;
86                 } else {
87                         *out++ = *in++;
88                 }
89         }
90         *out = '\0';
91         return (out);
92 }
93 /* end of function: hex_qdecode */
94
95 PUBLIC char * form_encode (in)
96 char *in;
97 {
98     char *out = buffer;
99     
100     /* bzero(out, 1024); */
101     while (*in) {
102             if (*in == '"' || *in == '>' ) {
103             *out++ = '\\';
104         }
105                    *out++ = *in++;
106     }
107          *out = '\0';
108
109      /* fprintf( stderr, "returning - esc: %s.\n", buffer); */
110     return (buffer);
111 }
112 /* end of function: form_encode */
113
114 /* gtime(): the inverse of localtime().
115     This routine was supplied by Mike Accetta at CMU many years ago.
116  */
117
118 int    dmsize[] = {
119     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
120 };
121
122 #define    dysize(y)    \
123     (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
124
125 #define    YEAR(y)        ((y) >= 100 ? (y) : (y) + 1900)
126
127 PRIVATE time_t gtime (tm)
128 struct tm *tm;
129 {
130     register int    i,
131                     sec,
132                     mins,
133                     hour,
134                     mday,
135                     mon,
136                     year;
137     register long   result;
138
139     if ((sec = tm -> tm_sec) < 0 || sec > 59
140         || (mins = tm -> tm_min) < 0 || mins > 59
141         || (hour = tm -> tm_hour) < 0 || hour > 24
142         || (mday = tm -> tm_mday) < 1 || mday > 31
143         || (mon = tm -> tm_mon + 1) < 1 || mon > 12)
144     return ((long) -1);
145     if (hour == 24) {
146     hour = 0;
147     mday++;
148     }
149     year = YEAR (tm -> tm_year);
150     result = 0L;
151     for (i = 1970; i < year; i++)
152     result += dysize (i);
153     if (dysize (year) == 366 && mon >= 3)
154     result++;
155     while (--mon)
156     result += dmsize[mon - 1];
157     result += mday - 1;
158     result = 24 * result + hour;
159     result = 60 * result + mins;
160     result = 60 * result + sec;
161     return result;
162 }
163 /* end of function: gtime */
164
165 PUBLIC char * format_date (s, format)
166 char **s;
167 char *format;
168 {
169 /*  PATCHED by /KSp, 94/04/29  */
170     static char    date[256];
171 /*      ^^^^^^ */
172 /*  END PATCH  */
173
174     struct tm       tm, *ntm;
175     time_t        t;
176
177
178     tm.tm_year = 10*((*s)[0] - '0') + ((*s)[1] - '0');
179     tm.tm_mon  = 10*((*s)[2] - '0') + ((*s)[3] - '0') - 1;
180     tm.tm_mday = 10*((*s)[4] - '0') + ((*s)[5] - '0');
181     tm.tm_hour = 10*((*s)[6] - '0') + ((*s)[7] - '0');
182     tm.tm_min  = 10*((*s)[8] - '0') + ((*s)[9] - '0');
183     tm.tm_sec  = 10*((*s)[10] - '0') + ((*s)[11] - '0');
184
185 /*  PATCHED for HPUX by /KSp, 94/04/28  */
186
187     tm.tm_isdst = 0;
188
189 #if !defined(__hpux) && !defined(__linux__)  && !defined(__sun)
190     tm.tm_gmtoff = 0;
191 #endif
192
193 /*  END PATCH  */
194
195     t = gtime(&tm);
196     ntm = gmtime(&t);
197     strftime(date, 256, format, ntm);
198     return (date);
199 }
200 /* end of function: format_date */
201
202 PUBLIC char * friendly_dn (dn, glob)
203 char *dn;
204 GLOB_STRUCT *glob;
205 {
206 /*  PATCHED BY /KSp, 94/04/29  */
207     /* static char    fufn[1024], **s; */
208 /*      ^^^^^^  */
209 /*  END PATCH  */
210
211 /*  Again patched by /KSp, 97/01/25: dynamic mem-allocation  */
212         char  *fufn;
213
214         if ( ( fufn = calloc( 1, BUFSIZ )) ) {
215
216                 if (strlen(dn) == 0) {
217                         strcpy( fufn, glob->la[77] );
218                 } else {
219
220                         int    i = 0;
221                         char   **s;
222
223                         s = ldap_explode_dn( dn, 1 );
224                         while (s[i+1]) {
225                                 strcat( fufn, s[i++] );
226                                 strcat( fufn, ", " );
227                         }
228                         strcat( fufn, ldap_friendly_name( glob->friendlyfile, s[i], &fm ));
229                 }
230         }
231
232     return (fufn);
233 }
234 /* end of function: friendly_dn */
235
236
237 PUBLIC char * format_time (whatTime)
238 time_t  whatTime;
239 {
240            time_t    timer;
241     static char      theTime[_TIMEOUT_LEN+1];
242
243     timer = whatTime ? whatTime : time (&timer);
244     strftime (theTime, (_TIMEOUT_LEN + 1), _LOG_TIME, localtime (&timer));
245
246     return (theTime);
247
248 } /* end of function: format_time */
249
250 PUBLIC char * strQuoteChr(string, c)
251 char *string;
252 char c;
253 {
254     char *cPtr;
255     int inQuote = FALSE;
256
257     cPtr = string;
258     while(*cPtr) {
259         if( *cPtr == '\"')
260             inQuote = ( (inQuote == TRUE) ? FALSE : TRUE );
261         if( (*cPtr == c) && (inQuote == FALSE) )
262             return(cPtr);
263         cPtr++;
264         }
265
266     return(NULL);
267 }
268 /* end of function: strQuoteChr */
269
270 PUBLIC char * strrQuoteChr(string, c)
271 char *string;
272 char c;
273 {
274     char *cPtr;
275     int inQuote = FALSE;
276
277     cPtr = string + strlen(string) - 1;
278     while(cPtr >= string) {
279         if( *cPtr == '\"')
280             inQuote = ( (inQuote == TRUE) ? FALSE : TRUE );
281         if( (*cPtr == c) && (inQuote == FALSE) )
282             return(cPtr);
283         cPtr--;
284         }
285
286     return(NULL);
287 }
288 /* end of function: strrQuoteChr */
289
290
291 PUBLIC void disp_file(glob, filename, fp)
292 GLOB_STRUCT *glob;
293 char *filename;
294 FILE *fp;
295 {
296 char buf[4096];
297 FILE *fp2;
298     if(filename && (fp2 = fopen(filename, "r" ))) {
299         while ( fgets(buf, 4095, fp2) != NULL )
300             fprintf( fp, "%s",buf);
301         fclose(fp2);
302     }
303
304     /* Copyright-Zeile */
305     if(filename == glob->footer ||
306        (glob->basedn && filename == glob->basedn->foot))
307         fprintf( fp, glob->la[99],glob->la[101], copyright );
308 }
309 /* end of function: disp_file */
310
311
312 PUBLIC int dn_cmp(dn1, dn2)
313 char *dn1, *dn2;
314 {
315         do {
316                 while(*dn1 == ' ' || *dn1 == '"')
317                         dn1++;
318                 while(*dn2 == ' ' || *dn2 == '"')
319                         dn2++;
320                 if(!*dn1 && !*dn2)
321                         return(FALSE); /* equality */
322         } while(tolower(*dn1++) == tolower(*dn2++));
323         return(TRUE);
324 }
325 /* end of function: dn_cmp */
326
327
328 /*
329  *  dn_cmp_parts()
330  *
331  *    comparison of dns by rdn parts. in case of unmatched the part(s) which
332  *    matched can be returned (matched not NULL)
333  *
334  *  input:
335  *
336  *    - dn1 (in url format)
337  *    - dn2 (     "       )
338  *    - matched (pointer to dynamically allocatable string, or NULL)
339  *
340  *  output:
341  *
342  *    - DN_EQUAL | DN_LESS | DN_GREATER | DN_UNMATCHED (with matched allocated)
343  */
344
345 PUBLIC int
346 dn_cmp_parts( dn1, dn2, matched )
347 char  *dn1;
348 char  *dn2;
349 char **matched;
350 {
351         char   **dn1arr = dn2charray( dn1 );
352         char   **dn2arr = dn2charray( dn2 );
353         int    idx;
354         int    domatch  = TRUE;
355         int    result   = DN_EQUAL;
356
357         for ( idx = 0; dn1arr[idx] && dn2arr[idx]; idx++ ) {
358
359                 if ( strcasecmp( dn1arr[idx], dn2arr[idx] )) {
360
361                         domatch = FALSE;
362                         break;
363
364                 }
365         }
366
367         /*  what was the result  */
368
369         if ( !domatch ) {
370
371                 if ( matched ) {
372                         char buf[BUFSIZ];
373                         char buf2[BUFSIZ];
374                         int  idx2;
375
376                         *buf = '\0';
377
378                         for ( idx2 = 0; idx2 < idx; idx2++ ) {
379
380                                 strcpy( buf2, buf );
381                                 sprintf( buf, "%s,%s", dn1arr[idx2], buf2 );
382
383                         }
384                         trimright( buf, "," );
385
386                         *matched = strdup( buf );
387
388                 }
389
390                 result = DN_UNMATCHED;
391
392         } else if ( dn1arr[idx] ) result = DN_GREATER;
393         else if ( dn2arr[idx] ) result = DN_LESS;
394
395         charray_free( dn1arr ); charray_free( dn2arr );
396
397         return( result );
398
399 }  /*  dn_cmp_parts  */
400
401
402
403 /*
404  *  Comparison of substring lists
405  */
406
407 PUBLIC int strlstcmp (s1, s2, sep)
408 char  *s1, *s2;
409 char   sep;
410 {
411     int   retCode = FALSE;
412     char *target;
413     char *source;
414     char *idx, *idx2;
415     char  tmpChar;
416
417     if ( !s1 || !s2 )
418         return( FALSE );
419
420     target = str_tolower (strdup (s1));
421     source = str_tolower (strdup (s2));
422     idx    = source;
423
424     while (idx && (idx2 = strchr (idx+1, sep))) {
425
426         tmpChar = *(++idx2); *idx2 = '\0';
427         if (strstr (target, idx)) {
428
429             retCode = TRUE;
430             break;
431
432         }
433
434         *(idx2) = tmpChar;
435         idx = --idx2;
436
437     }
438
439     free (source);
440     free (target);
441     return (retCode);
442
443 }
444 /* end of function: strlstcmp */
445
446 PUBLIC char *hex_html_encode(string, flag)
447 char *string;
448 int flag; /* 0->hex 1->html */
449 {
450         static char strbuf[10*BUFSIZ];
451         char *strptr;
452
453         *strbuf = '\0';
454         for(strptr = string; *strptr; strptr++){
455                 /* 200 a -> &auml; fuer aouAOU */
456                 if((flag==1) && (((int)*strptr&255)==200)) {
457                         if(strchr("aouAOU", *(strptr+1))) {
458                                 sprintf(strbuf, "%s&%cuml;", strbuf, *++strptr);
459                                 continue;
460                         }
461                 }
462
463                 /* &#xxx; Handling-Patch */
464                 if((flag==1) && (((int)*strptr&255)>=160)) {
465                         sprintf(strbuf, "%s&#%d;", strbuf, ((int)*strptr&255));
466                         continue;
467                 }
468                 /* end Patch */
469
470                 if(!encoding_tbl[(int)*strptr&255][flag]) {
471                         sprintf(strbuf, "%s%c", strbuf, *strptr);
472                 } else {
473                         strcat(strbuf, encoding_tbl[(int)*strptr&255][flag]);
474                 }
475         }
476         return(strbuf);
477 }
478 /* end of function: hex_html_encode */
479
480 /* Strips basecount+1 characters of type target at the end of an RDN */
481 PUBLIC char *dnrcut(rdn, target, basecount) 
482 char *rdn;
483 char *target;
484 int basecount;
485 {
486         static char buf[BUFSIZ];
487         char *strptr;
488         int rdncount, morecount;
489
490         rdncount = chrcnt(rdn, target);
491         if( (morecount = (rdncount - basecount)) > 0) {
492                 strcpy(buf, rdn);
493                 strptr = buf-1;
494                 while(morecount--) {
495                         strptr = strpbrk(strptr+1, target);
496                 }
497                 *strptr = '\0';
498         } else *buf = '\0';
499         return(buf);
500 }
501 /* end of function: dnrcut */
502
503 PUBLIC char **dn2charray(dn)
504 char *dn;
505 {
506     char *dnbuf, *strptr, **a=NULL;
507
508         if ( !dn || !*dn ) {
509
510                 a = (char **) ch_calloc( 1, sizeof( char ** ));
511                 return( a );
512
513         }
514
515     dnbuf = strdup(dn);
516     do {
517         strptr = strrQuoteChr(dnbuf, ',');
518         if(strptr) {
519             *strptr++ = '\0';
520 /*
521             while(*strptr == ' ') 
522                 strptr++;
523 */
524                         strptr = trim( strptr, " " );
525         }
526         charray_add( &a, strptr ? strptr : trim( dnbuf, " " ));
527     } while(strptr);
528     free(dnbuf);
529     return(a);
530 }
531 /* end of function: dn2charray */
532
533
534 /* get the parent DN for a given one */
535 PUBLIC char *
536 get_parentDN( dn )
537 char  *dn;
538 {
539         char  **a   = NULL;
540         char    tmp[BUFSIZ];
541
542         a = dn2charray( dn );
543         *tmp = *(tmp + 1) = '\0';
544
545         if ( a ) {
546                 char **rdnH;
547
548                 /*  we have to re-build the DN beginning at the last array element  */
549                 for ( rdnH = a; *rdnH; rdnH++ )
550                         ;
551
552                 /*  re-build DN from it's parts  */
553                 rdnH--; rdnH--;
554                 for ( ; rdnH >= a; rdnH-- ) {
555
556                         sprintf( tmp, "%s,%s", tmp, *rdnH );
557
558                 }
559
560                 charray_free( a );
561
562         }
563
564         /*  ignore a leading ','  */
565         return( strdup( tmp + 1 ));
566
567 }  /* get_parentDN */
568
569
570 PUBLIC char *elapsed(firsttime, secondtime)
571 struct timeval firsttime;
572 struct timeval secondtime;
573 {
574     long int elapsedmicrosec, elapsedsec;
575     char elapsed_string[BUFSIZ];
576     
577     elapsedsec = secondtime.tv_sec - firsttime.tv_sec;
578     elapsedmicrosec = secondtime.tv_usec - firsttime.tv_usec;
579     if(elapsedmicrosec < 0) {
580         elapsedmicrosec += 1000000;
581         elapsedsec -= 1;
582     }
583     if(elapsedsec > 1000){
584         elapsedsec = 0;
585         elapsedmicrosec = 0;
586     }
587     sprintf(elapsed_string, "%ld.%.6ld", elapsedsec, elapsedmicrosec);
588     return(strdup(elapsed_string));
589 }
590 /* end of function: elapsed */
591
592
593 /* performance-log on exit */
594 PUBLIC int exit_tweb(rc)
595 int rc;
596 {
597     struct timeval secondtime;
598
599     gettimeofday(&secondtime, NULL);
600     if(!secondtime.tv_sec || !timestore[0].tv_sec) exit(rc);
601
602     if (dosyslog)
603                  syslog (LOG_INFO, "performance: %s#%s#%s#%s#%s#%s#%d seconds <%08d>",
604                 elapsed(timestore[0], secondtime), elapsed(timestore[0],
605                         timestore[1]), elapsed(timestore[1], timestore[2]),
606                 elapsed(timestore[2], timestore[3]),
607                 elapsed(timestore[3], items_displayed ? timestore[4] : secondtime),
608                 items_displayed ? elapsed(timestore[4], secondtime) : "",
609                 items_displayed, globP->svc_cnt);
610     exit(rc);
611 }
612 /* end of function: exit_tweb */
613