]> code.citadel.org Git - citadel.git/blob - webcit/tools.c
* Replaced sleep() with a function that sleeps using select() in order to
[citadel.git] / webcit / tools.c
1 /*
2  * tools.c -- Miscellaneous routines 
3  */
4
5 #include <ctype.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <signal.h>
11 #include <sys/types.h>
12 #include <sys/wait.h>
13 #include <sys/socket.h>
14 #include <sys/time.h>
15 #include <limits.h>
16 #include <netinet/in.h>
17 #include <netdb.h>
18 #include <string.h>
19 #include <pwd.h>
20 #include <errno.h>
21 #include <stdarg.h>
22 #include <pthread.h>
23 #include <signal.h>
24 #include <sys/time.h>
25 #include "webcit.h"
26 #include "webserver.h"
27
28
29 char *ascmonths[] = {
30         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
31         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
32 };
33
34 char *ascdays[] = {
35         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
36 };
37
38
39 char *safestrncpy(char *dest, const char *src, size_t n)
40 {
41         if (dest == NULL || src == NULL) {
42                 lprintf(1, "safestrncpy: NULL argument\n");
43                 abort();
44         }
45         strncpy(dest, src, n);
46         dest[n - 1] = 0;
47         return dest;
48 }
49
50
51
52 /*
53  * num_tokens()  -  discover number of parameters/tokens in a string
54  */
55 int num_tokens(char *source, char tok) {
56         int a;
57         int count = 1;
58
59         if (source == NULL) return(0);
60         for (a=0; a<strlen(source); ++a) {
61                 if (source[a]==tok) ++count;
62         }
63         return(count);
64 }
65
66 /*
67  * extract_token()  -  a smarter string tokenizer
68  */
69 void extract_token(char *dest, char *source, int parmnum, char separator) 
70 {
71         int i;
72         int len;
73         int curr_parm;
74
75         strcpy(dest,"");
76         len = 0;
77         curr_parm = 0;
78
79         if (strlen(source)==0) {
80                 return;
81         }
82
83         for (i=0; i<strlen(source); ++i) {
84                 if (source[i]==separator) {
85                         ++curr_parm;
86                 }
87                 else if (curr_parm == parmnum) {
88                         dest[len+1] = 0;
89                         dest[len++] = source[i];
90                 }
91         }
92 }
93
94
95
96 /*
97  * remove_token()  -  a tokenizer that kills, maims, and destroys
98  */
99 void remove_token(char *source, int parmnum, char separator)
100 {
101         int i;
102         int len;
103         int curr_parm;
104         int start, end;
105
106         len = 0;
107         curr_parm = 0;
108         start = (-1);
109         end = (-1);
110
111         if (strlen(source)==0) {
112                 return;
113                 }
114
115         for (i=0; i<strlen(source); ++i) {
116                 if ( (start < 0) && (curr_parm == parmnum) ) {
117                         start = i;
118                 }
119
120                 if ( (end < 0) && (curr_parm == (parmnum+1)) ) {
121                         end = i;
122                 }
123
124                 if (source[i]==separator) {
125                         ++curr_parm;
126                 }
127         }
128
129         if (end < 0) end = strlen(source);
130
131         strcpy(&source[start], &source[end]);
132 }
133
134
135
136
137 /*
138  * extract_int()  -  extract an int parm w/o supplying a buffer
139  */
140 int extract_int(char *source, int parmnum)
141 {
142         char buf[SIZ];
143         
144         extract_token(buf, source, parmnum, '|');
145         return(atoi(buf));
146 }
147
148 /*
149  * extract_long()  -  extract an long parm w/o supplying a buffer
150  */
151 long extract_long(char *source, long int parmnum)
152 {
153         char buf[SIZ];
154         
155         extract_token(buf, source, parmnum, '|');
156         return(atol(buf));
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 /*
174  * check for the presence of a character within a string (returns count)
175  */
176 int haschar(st, ch)
177 char st[];
178 char ch;
179 {
180         int a, b;
181         b = 0;
182         for (a = 0; a < strlen(st); ++a)
183                 if (st[a] == ch)
184                         ++b;
185         return (b);
186 }
187
188
189 /*
190  * Format a date/time stamp for output 
191  */
192 void fmt_date(char *buf, time_t thetime) {
193         struct tm *tm;
194         int hour;
195
196         strcpy(buf, "");
197         tm = localtime(&thetime);
198         hour = tm->tm_hour;
199         if (hour == 0) hour = 12;
200         else if (hour > 12) hour = hour - 12;
201
202         sprintf(buf, "%s %d %d %2d:%02d%s",
203                 ascmonths[tm->tm_mon],
204                 tm->tm_mday,
205                 tm->tm_year + 1900,
206                 hour,
207                 tm->tm_min,
208                 ( (tm->tm_hour > 12) ? "pm" : "am" )
209         );
210 }
211
212
213
214 /*
215  * Format TIME ONLY for output 
216  */
217 void fmt_time(char *buf, time_t thetime) {
218         struct tm *tm;
219         int hour;
220
221         strcpy(buf, "");
222         tm = localtime(&thetime);
223         hour = tm->tm_hour;
224         if (hour == 0) hour = 12;
225         else if (hour > 12) hour = hour - 12;
226
227         sprintf(buf, "%d:%02d%s",
228                 hour,
229                 tm->tm_min,
230                 ( (tm->tm_hour > 12) ? "pm" : "am" )
231         );
232 }
233
234
235
236
237 /*
238  * Format a date/time stamp to the format used in HTTP headers
239  */
240 void httpdate(char *buf, time_t thetime) {
241         struct tm *tm;
242
243         strcpy(buf, "");
244         tm = localtime(&thetime);
245
246         sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d",
247                 ascdays[tm->tm_wday],
248                 tm->tm_mday,
249                 ascmonths[tm->tm_mon],
250                 tm->tm_year + 1900,
251                 tm->tm_hour,
252                 tm->tm_min,
253                 tm->tm_sec
254         );
255 }
256
257
258
259
260
261 /*
262  * Utility function to "readline" from memory
263  * (returns new pointer)
264  */
265 char *memreadline(char *start, char *buf, int maxlen)
266 {
267         char ch;
268         char *ptr;
269         int len = 0;    /* tally our own length to avoid strlen() delays */
270
271         ptr = start;
272         memset(buf, 0, maxlen);
273
274         while (1) {
275                 ch = *ptr++;
276                 if ( (len < (maxlen - 1)) && (ch != 13) && (ch != 10) ) {
277                         buf[strlen(buf) + 1] = 0;
278                         buf[strlen(buf)] = ch;
279                         ++len;
280                 }
281                 if ((ch == 10) || (ch == 0)) {
282                         return ptr;
283                 }
284         }
285 }
286
287
288
289 /*
290  * pattern2()  -  searches for patn within search string, returns pos
291  */
292 int pattern2(char *search, char *patn)
293 {
294         int a;
295         for (a=0; a<strlen(search); ++a) {
296                 if (!strncasecmp(&search[a],patn,strlen(patn))) return(a);
297                 }
298         return(-1);
299         }
300
301
302 /*
303  * Strip leading and trailing spaces from a string
304  */
305 void striplt(char *buf)
306 {
307         while ((strlen(buf) > 0) && (isspace(buf[0])))
308                 strcpy(buf, &buf[1]);
309         while (isspace(buf[strlen(buf) - 1]))
310                 buf[strlen(buf) - 1] = 0;
311 }
312
313
314 /*
315  * Determine whether the specified message number is contained within the
316  * specified set.
317  */
318 int is_msg_in_mset(char *mset, long msgnum) {
319         int num_sets;
320         int s;
321         char setstr[SIZ], lostr[SIZ], histr[SIZ];       /* was 1024 */
322         long lo, hi;
323
324         /*
325          * Now set it for all specified messages.
326          */
327         num_sets = num_tokens(mset, ',');
328         for (s=0; s<num_sets; ++s) {
329                 extract_token(setstr, mset, s, ',');
330
331                 extract_token(lostr, setstr, 0, ':');
332                 if (num_tokens(setstr, ':') >= 2) {
333                         extract_token(histr, setstr, 1, ':');
334                         if (!strcmp(histr, "*")) {
335                                 snprintf(histr, sizeof histr, "%ld", LONG_MAX);
336                         }
337                 } 
338                 else {
339                         strcpy(histr, lostr);
340                 }
341                 lo = atol(lostr);
342                 hi = atol(histr);
343
344                 if ((msgnum >= lo) && (msgnum <= hi)) return(1);
345         }
346
347         return(0);
348 }
349
350
351 /*
352  * Strip a boundarized substring out of a string (for example, remove
353  * parentheses and anything inside them).
354  *
355  * This improved version can strip out *multiple* boundarized substrings.
356  */
357 void stripout(char *str, char leftboundary, char rightboundary) {
358         int a;
359         int lb = (-1);
360         int rb = (-1);
361
362         do {
363                 lb = (-1);
364                 rb = (-1);
365         
366                 for (a = 0; a < strlen(str); ++a) {
367                         if (str[a] == leftboundary) lb = a;
368                         if (str[a] == rightboundary) rb = a;
369                 }
370
371                 if ( (lb > 0) && (rb > lb) ) {
372                         strcpy(&str[lb - 1], &str[rb + 1]);
373                 }
374
375         } while ( (lb > 0) && (rb > lb) );
376
377 }
378
379
380
381 /*
382  * Replacement for sleep() that uses select() in order to avoid SIGALRM
383  */
384 void sleeeeeeeeeep(int seconds)
385 {
386         struct timeval tv;
387
388         tv.tv_sec = seconds;
389         tv.tv_usec = 0;
390         select(0, NULL, NULL, NULL, &tv);
391 }
392