]> code.citadel.org Git - citadel.git/blob - webcit/tools.c
* Brought over the newer string tokenizer from Citadel
[citadel.git] / webcit / tools.c
1 /*
2  * tools.c -- Miscellaneous routines 
3  */
4
5
6
7 #include <ctype.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <sys/socket.h>
16 #include <sys/time.h>
17 #include <limits.h>
18 #include <netinet/in.h>
19 #include <netdb.h>
20 #include <string.h>
21 #include <pwd.h>
22 #include <errno.h>
23 #include <stdarg.h>
24 #include <pthread.h>
25 #include <signal.h>
26 #include <sys/time.h>
27 #include "webcit.h"
28
29
30 char *ascmonths[] = {
31         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
32         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
33 };
34
35 char *ascdays[] = {
36         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
37 };
38
39
40 char *safestrncpy(char *dest, const char *src, size_t n)
41 {
42         if (dest == NULL || src == NULL) {
43                 fprintf(stderr, "safestrncpy: NULL argument\n");
44                 abort();
45         }
46         strncpy(dest, src, n);
47         dest[n - 1] = 0;
48         return dest;
49 }
50
51
52
53 /*
54  * num_tokens()  -  discover number of parameters/tokens in a string
55  */
56 int num_tokens(char *source, char tok) {
57         int a;
58         int count = 1;
59
60         if (source == NULL) return(0);
61         for (a=0; a<strlen(source); ++a) {
62                 if (source[a]==tok) ++count;
63         }
64         return(count);
65 }
66
67 /*
68  * extract_token()  -  a smarter string tokenizer
69  */
70 void extract_token(char *dest, char *source, int parmnum, char separator) 
71 {
72         int i;
73         int len;
74         int curr_parm;
75
76         strcpy(dest,"");
77         len = 0;
78         curr_parm = 0;
79
80         if (strlen(source)==0) {
81                 return;
82                 }
83
84         for (i=0; i<strlen(source); ++i) {
85                 if (source[i]==separator) {
86                         ++curr_parm;
87                 }
88                 else if (curr_parm == parmnum) {
89                         dest[len+1] = 0;
90                         dest[len++] = source[i];
91                 }
92         }
93 }
94
95
96
97 /*
98  * remove_token()  -  a tokenizer that kills, maims, and destroys
99  */
100 void remove_token(char *source, int parmnum, char separator)
101 {
102         int i;
103         int len;
104         int curr_parm;
105         int start, end;
106
107         len = 0;
108         curr_parm = 0;
109         start = (-1);
110         end = (-1);
111
112         if (strlen(source)==0) {
113                 return;
114                 }
115
116         for (i=0; i<strlen(source); ++i) {
117                 if ( (start < 0) && (curr_parm == parmnum) ) {
118                         start = i;
119                 }
120
121                 if ( (end < 0) && (curr_parm == (parmnum+1)) ) {
122                         end = i;
123                 }
124
125                 if (source[i]==separator) {
126                         ++curr_parm;
127                 }
128         }
129
130         if (end < 0) end = strlen(source);
131
132         printf("%d .. %d\n", start, end);
133
134         strcpy(&source[start], &source[end]);
135 }
136
137
138
139
140 /*
141  * extract_int()  -  extract an int parm w/o supplying a buffer
142  */
143 int extract_int(char *source, int parmnum)
144 {
145         char buf[SIZ];
146         
147         extract_token(buf, source, parmnum, '|');
148         return(atoi(buf));
149 }
150
151 /*
152  * extract_long()  -  extract an long parm w/o supplying a buffer
153  */
154 long extract_long(char *source, long int parmnum)
155 {
156         char buf[SIZ];
157         
158         extract_token(buf, source, parmnum, '|');
159         return(atol(buf));
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 /*
177  * check for the presence of a character within a string (returns count)
178  */
179 int haschar(st, ch)
180 char st[];
181 char ch;
182 {
183         int a, b;
184         b = 0;
185         for (a = 0; a < strlen(st); ++a)
186                 if (st[a] == ch)
187                         ++b;
188         return (b);
189 }
190
191
192 /*
193  * Format a date/time stamp for output 
194  */
195 void fmt_date(char *buf, time_t thetime) {
196         struct tm *tm;
197
198         strcpy(buf, "");
199         tm = localtime(&thetime);
200
201         sprintf(buf, "%s %d %d %2d:%02d%s",
202                 ascmonths[tm->tm_mon],
203                 tm->tm_mday,
204                 tm->tm_year + 1900,
205                 ( (tm->tm_hour > 12) ? (tm->tm_hour - 12) : (tm->tm_hour) ),
206                 tm->tm_min,
207                 ( (tm->tm_hour > 12) ? "pm" : "am" )
208         );
209 }
210
211
212
213
214 /*
215  * Format a date/time stamp to the format used in HTTP headers
216  */
217 void httpdate(char *buf, time_t thetime) {
218         struct tm *tm;
219
220         strcpy(buf, "");
221         tm = localtime(&thetime);
222
223         sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d",
224                 ascdays[tm->tm_wday],
225                 tm->tm_mday,
226                 ascmonths[tm->tm_mon],
227                 tm->tm_year + 1900,
228                 tm->tm_hour,
229                 tm->tm_min,
230                 tm->tm_sec
231         );
232 }
233
234
235
236
237
238 /*
239  * Utility function to "readline" from memory
240  * (returns new pointer)
241  */
242 char *memreadline(char *start, char *buf, int maxlen)
243 {
244         char ch;
245         char *ptr;
246         int len = 0;    /* tally our own length to avoid strlen() delays */
247
248         ptr = start;
249         memset(buf, 0, maxlen);
250
251         while (1) {
252                 ch = *ptr++;
253                 if ( (len < (maxlen - 1)) && (ch != 13) && (ch != 10) ) {
254                         buf[strlen(buf) + 1] = 0;
255                         buf[strlen(buf)] = ch;
256                         ++len;
257                 }
258                 if ((ch == 10) || (ch == 0)) {
259                         return ptr;
260                 }
261         }
262 }
263
264
265
266