2 * tools.c -- Miscellaneous routines
13 #include <sys/types.h>
15 #include <sys/socket.h>
18 #include <netinet/in.h>
28 #include "webserver.h"
32 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
33 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
37 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
41 char *safestrncpy(char *dest, const char *src, size_t n)
43 if (dest == NULL || src == NULL) {
44 lprintf(1, "safestrncpy: NULL argument\n");
47 strncpy(dest, src, n);
55 * num_tokens() - discover number of parameters/tokens in a string
57 int num_tokens(char *source, char tok) {
61 if (source == NULL) return(0);
62 for (a=0; a<strlen(source); ++a) {
63 if (source[a]==tok) ++count;
69 * extract_token() - a smarter string tokenizer
71 void extract_token(char *dest, char *source, int parmnum, char separator)
81 if (strlen(source)==0) {
85 for (i=0; i<strlen(source); ++i) {
86 if (source[i]==separator) {
89 else if (curr_parm == parmnum) {
91 dest[len++] = source[i];
99 * remove_token() - a tokenizer that kills, maims, and destroys
101 void remove_token(char *source, int parmnum, char separator)
113 if (strlen(source)==0) {
117 for (i=0; i<strlen(source); ++i) {
118 if ( (start < 0) && (curr_parm == parmnum) ) {
122 if ( (end < 0) && (curr_parm == (parmnum+1)) ) {
126 if (source[i]==separator) {
131 if (end < 0) end = strlen(source);
133 strcpy(&source[start], &source[end]);
140 * extract_int() - extract an int parm w/o supplying a buffer
142 int extract_int(char *source, int parmnum)
146 extract_token(buf, source, parmnum, '|');
151 * extract_long() - extract an long parm w/o supplying a buffer
153 long extract_long(char *source, long int parmnum)
157 extract_token(buf, source, parmnum, '|');
176 * check for the presence of a character within a string (returns count)
184 for (a = 0; a < strlen(st); ++a)
192 * Format a date/time stamp for output
194 void fmt_date(char *buf, time_t thetime) {
199 tm = localtime(&thetime);
201 if (hour == 0) hour = 12;
202 else if (hour > 12) hour = hour - 12;
204 sprintf(buf, "%s %d %d %2d:%02d%s",
205 ascmonths[tm->tm_mon],
210 ( (tm->tm_hour > 12) ? "pm" : "am" )
217 * Format TIME ONLY for output
219 void fmt_time(char *buf, time_t thetime) {
224 tm = localtime(&thetime);
226 if (hour == 0) hour = 12;
227 else if (hour > 12) hour = hour - 12;
229 sprintf(buf, "%d:%02d%s",
232 ( (tm->tm_hour > 12) ? "pm" : "am" )
240 * Format a date/time stamp to the format used in HTTP headers
242 void httpdate(char *buf, time_t thetime) {
246 tm = localtime(&thetime);
248 sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d",
249 ascdays[tm->tm_wday],
251 ascmonths[tm->tm_mon],
264 * Utility function to "readline" from memory
265 * (returns new pointer)
267 char *memreadline(char *start, char *buf, int maxlen)
271 int len = 0; /* tally our own length to avoid strlen() delays */
274 memset(buf, 0, maxlen);
278 if ( (len < (maxlen - 1)) && (ch != 13) && (ch != 10) ) {
279 buf[strlen(buf) + 1] = 0;
280 buf[strlen(buf)] = ch;
283 if ((ch == 10) || (ch == 0)) {
292 * pattern2() - searches for patn within search string, returns pos
294 int pattern2(char *search, char *patn)
297 for (a=0; a<strlen(search); ++a) {
298 if (!strncasecmp(&search[a],patn,strlen(patn))) return(a);
305 * Strip leading and trailing spaces from a string
307 void striplt(char *buf)
309 while ((strlen(buf) > 0) && (isspace(buf[0])))
310 strcpy(buf, &buf[1]);
311 while (isspace(buf[strlen(buf) - 1]))
312 buf[strlen(buf) - 1] = 0;
317 * Determine whether the specified message number is contained within the
320 int is_msg_in_mset(char *mset, long msgnum) {
323 char setstr[SIZ], lostr[SIZ], histr[SIZ]; /* was 1024 */
327 * Now set it for all specified messages.
329 num_sets = num_tokens(mset, ',');
330 for (s=0; s<num_sets; ++s) {
331 extract_token(setstr, mset, s, ',');
333 extract_token(lostr, setstr, 0, ':');
334 if (num_tokens(setstr, ':') >= 2) {
335 extract_token(histr, setstr, 1, ':');
336 if (!strcmp(histr, "*")) {
337 snprintf(histr, sizeof histr, "%ld", LONG_MAX);
341 strcpy(histr, lostr);
346 if ((msgnum >= lo) && (msgnum <= hi)) return(1);
355 * Read binary data from server into memory using a series of
356 * server READ commands.
358 void read_server_binary(char *buffer, size_t total_len) {
361 size_t thisblock = 0;
363 memset(buffer, 0, total_len);
364 while (bytes < total_len) {
366 if ((total_len - bytes) < thisblock) {
367 thisblock = total_len - bytes;
368 if (thisblock == 0) return;
370 serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
373 thisblock = (size_t)atoi(&buf[4]);
374 serv_read(&buffer[bytes], thisblock);
378 lprintf(3, "Error: %s<BR>\n", &buf[4]);
387 * Strip a boundarized substring out of a string (for example, remove
388 * parentheses and anything inside them).
390 * This improved version can strip out *multiple* boundarized substrings.
392 void stripout(char *str, char leftboundary, char rightboundary) {
401 for (a = 0; a < strlen(str); ++a) {
402 if (str[a] == leftboundary) lb = a;
403 if (str[a] == rightboundary) rb = a;
406 if ( (lb > 0) && (rb > lb) ) {
407 strcpy(&str[lb - 1], &str[rb + 1]);
410 } while ( (lb > 0) && (rb > lb) );