tools.c

00001 /*
00002  * $Id: tools.c 5147 2007-05-08 15:36:22Z ajc $
00003  */
00010 #include "webcit.h"
00011 #include "webserver.h"
00012 
00013 
00014 typedef unsigned char byte; 
00016 #define FALSE 0 
00017 #define TRUE 1  
00019 static byte dtable[256];        
00028 char *safestrncpy(char *dest, const char *src, size_t n)
00029 {
00030         if (dest == NULL || src == NULL) {
00031                 abort();
00032         }
00033         strncpy(dest, src, n);
00034         dest[n - 1] = 0;
00035         return dest;
00036 }
00037 
00038 
00039 
00046 int num_tokens(char *source, char tok)
00047 {
00048         int a = 0;
00049         int count = 1;
00050 
00051         if (source == NULL)
00052                 return (0);
00053         for (a = 0; a < strlen(source); ++a) {
00054                 if (source[a] == tok)
00055                         ++count;
00056         }
00057         return (count);
00058 }
00059 
00068 void extract_token(char *dest, const char *source, int parmnum, char separator, int maxlen)
00069 {
00070         char *d;                /* dest */
00071         const char *s;          /* source */
00072         int count = 0;
00073         int len = 0;
00074 
00075         dest[0] = 0;
00076 
00077         /* Locate desired parameter */
00078         s = source;
00079         while (count < parmnum) {
00080                 /* End of string, bail! */
00081                 if (!*s) {
00082                         s = NULL;
00083                         break;
00084                 }
00085                 if (*s == separator) {
00086                         count++;
00087                 }
00088                 s++;
00089         }
00090         if (!s) return;         /* Parameter not found */
00091 
00092         for (d = dest; *s && *s != separator && ++len<maxlen; s++, d++) {
00093                 *d = *s;
00094         }
00095         *d = 0;
00096 }
00097 
00098 
00099 
00106 void remove_token(char *source, int parmnum, char separator)
00107 {
00108         int i;
00109         int len;
00110         int curr_parm;
00111         int start, end;
00112 
00113         len = 0;
00114         curr_parm = 0;
00115         start = (-1);
00116         end = (-1);
00117 
00118         if (strlen(source) == 0) {
00119                 return;
00120         }
00121 
00122         for (i = 0; i < strlen(source); ++i) {
00123                 if ((start < 0) && (curr_parm == parmnum)) {
00124                         start = i;
00125                 }
00126 
00127                 if ((end < 0) && (curr_parm == (parmnum + 1))) {
00128                         end = i;
00129                 }
00130 
00131                 if (source[i] == separator) {
00132                         ++curr_parm;
00133                 }
00134         }
00135 
00136         if (end < 0)
00137                 end = strlen(source);
00138 
00139         strcpy(&source[start], &source[end]);
00140 }
00141 
00142 
00143 
00144 
00151 int extract_int(const char *source, int parmnum)
00152 {
00153         char buf[32];
00154         
00155         extract_token(buf, source, parmnum, '|', sizeof buf);
00156         return(atoi(buf));
00157 }
00158 
00165 long extract_long(const char *source, int parmnum)
00166 {
00167         char buf[32];
00168         
00169         extract_token(buf, source, parmnum, '|', sizeof buf);
00170         return(atol(buf));
00171 }
00172 
00173 
00174 
00175 
00176 
00177 
00184 int haschar(char *st,char ch)
00185 {
00186         int a, b;
00187         b = 0;
00188         for (a = 0; a < strlen(st); ++a)
00189                 if (st[a] == ch)
00190                         ++b;
00191         return (b);
00192 }
00193 
00194 
00202 char *memreadline(char *start, char *buf, int maxlen)
00203 {
00204         char ch;
00205         char *ptr;
00206         int len = 0;            
00208         ptr = start;
00209         memset(buf, 0, maxlen);
00210 
00211         while (1) {
00212                 ch = *ptr++;
00213                 if ((len < (maxlen - 1)) && (ch != 13) && (ch != 10)) {
00214                         buf[strlen(buf) + 1] = 0;
00215                         buf[strlen(buf)] = ch;
00216                         ++len;
00217                 }
00218                 if ((ch == 10) || (ch == 0)) {
00219                         return ptr;
00220                 }
00221         }
00222 }
00223 
00224 
00225 
00232 int pattern2(char *search, char *patn)
00233 {
00234         int a;
00235         for (a = 0; a < strlen(search); ++a) {
00236                 if (!strncasecmp(&search[a], patn, strlen(patn)))
00237                         return (a);
00238         }
00239         return (-1);
00240 }
00241 
00242 
00247 void striplt(char *buf)
00248 {
00249         if (strlen(buf) == 0) return;
00250         while ((strlen(buf) > 0) && (isspace(buf[0])))
00251                 strcpy(buf, &buf[1]);
00252         if (strlen(buf) == 0) return;
00253         while (isspace(buf[strlen(buf) - 1]))
00254                 buf[strlen(buf) - 1] = 0;
00255 }
00256 
00257 
00267 int is_msg_in_mset(char *mset, long msgnum) {
00268         int num_sets;
00269         int s;
00270         char setstr[SIZ], lostr[SIZ], histr[SIZ];       /* was 1024 */
00271         long lo, hi;
00272 
00273         /*
00274          * Now set it for all specified messages.
00275          */
00276         num_sets = num_tokens(mset, ',');
00277         for (s=0; s<num_sets; ++s) {
00278                 extract_token(setstr, mset, s, ',', sizeof setstr);
00279 
00280                 extract_token(lostr, setstr, 0, ':', sizeof lostr);
00281                 if (num_tokens(setstr, ':') >= 2) {
00282                         extract_token(histr, setstr, 1, ':', sizeof histr);
00283                         if (!strcmp(histr, "*")) {
00284                                 snprintf(histr, sizeof histr, "%ld", LONG_MAX);
00285                         }
00286                 } 
00287                 else {
00288                         strcpy(histr, lostr);
00289                 }
00290                 lo = atol(lostr);
00291                 hi = atol(histr);
00292 
00293                 if ((msgnum >= lo) && (msgnum <= hi)) return(1);
00294         }
00295 
00296         return(0);
00297 }
00298 
00299 
00300 
00311 void stripout(char *str, char leftboundary, char rightboundary)
00312 {
00313         int a;
00314         int lb = (-1);
00315         int rb = (-1);
00316 
00317         do {
00318                 lb = (-1);
00319                 rb = (-1);
00320 
00321                 for (a = 0; a < strlen(str); ++a) {
00322                         if (str[a] == leftboundary)
00323                                 lb = a;
00324                         if (str[a] == rightboundary)
00325                                 rb = a;
00326                 }
00327 
00328                 if ((lb > 0) && (rb > lb)) {
00329                         strcpy(&str[lb - 1], &str[rb + 1]);
00330                 }
00331 
00332         } while ((lb > 0) && (rb > lb));
00333 
00334 }
00335 
00336 
00337 
00342 void sleeeeeeeeeep(int seconds)
00343 {
00344         struct timeval tv;
00345 
00346         tv.tv_sec = seconds;
00347         tv.tv_usec = 0;
00348         select(0, NULL, NULL, NULL, &tv);
00349 }
00350 
00351 
00352 
00362 void CtdlEncodeBase64(char *dest, const char *source, size_t sourcelen, int linebreaks)
00363 {
00364         int i, hiteof = FALSE;
00365         int spos = 0;
00366         int dpos = 0;
00367         int thisline = 0;
00368 
00371         for (i = 0; i < 26; i++) {
00372                 dtable[i] = 'A' + i;
00373                 dtable[26 + i] = 'a' + i;
00374         }
00375         for (i = 0; i < 10; i++) {
00376                 dtable[52 + i] = '0' + i;
00377         }
00378         dtable[62] = '+';
00379         dtable[63] = '/';
00380 
00381         while (!hiteof) {
00382                 byte igroup[3], ogroup[4];
00383                 int c, n;
00384 
00385                 igroup[0] = igroup[1] = igroup[2] = 0;
00386                 for (n = 0; n < 3; n++) {
00387                         if (spos >= sourcelen) {
00388                                 hiteof = TRUE;
00389                                 break;
00390                         }
00391                         c = source[spos++];
00392                         igroup[n] = (byte) c;
00393                 }
00394                 if (n > 0) {
00395                         ogroup[0] = dtable[igroup[0] >> 2];
00396                         ogroup[1] =
00397                             dtable[((igroup[0] & 3) << 4) |
00398                                    (igroup[1] >> 4)];
00399                         ogroup[2] =
00400                             dtable[((igroup[1] & 0xF) << 2) |
00401                                    (igroup[2] >> 6)];
00402                         ogroup[3] = dtable[igroup[2] & 0x3F];
00403 
00410                         if (n < 3) {
00411                                 ogroup[3] = '=';
00412                                 if (n < 2) {
00413                                         ogroup[2] = '=';
00414                                 }
00415                         }
00416                         for (i = 0; i < 4; i++) {
00417                                 dest[dpos++] = ogroup[i];
00418                                 dest[dpos] = 0;
00419                         }
00420                         thisline += 4;
00421                         if ( (linebreaks) && (thisline > 70) ) {
00422                                 dest[dpos++] = '\r';
00423                                 dest[dpos++] = '\n';
00424                                 dest[dpos] = 0;
00425                                 thisline = 0;
00426                         }
00427                 }
00428         }
00429         if ( (linebreaks) && (thisline > 70) ) {
00430                 dest[dpos++] = '\r';
00431                 dest[dpos++] = '\n';
00432                 dest[dpos] = 0;
00433                 thisline = 0;
00434         }
00435 }
00436 
00437 
00447 int CtdlDecodeBase64(char *dest, const char *source, size_t length)
00448 {
00449         int i, c;
00450         int dpos = 0;
00451         int spos = 0;
00452 
00453         for (i = 0; i < 255; i++) {
00454                 dtable[i] = 0x80;
00455         }
00456         for (i = 'A'; i <= 'Z'; i++) {
00457                 dtable[i] = 0 + (i - 'A');
00458         }
00459         for (i = 'a'; i <= 'z'; i++) {
00460                 dtable[i] = 26 + (i - 'a');
00461         }
00462         for (i = '0'; i <= '9'; i++) {
00463                 dtable[i] = 52 + (i - '0');
00464         }
00465         dtable['+'] = 62;
00466         dtable['/'] = 63;
00467         dtable['='] = 0;
00468  while (TRUE) {
00470                 byte a[4], b[4], o[3];
00471 
00472                 for (i = 0; i < 4; i++) {
00473                         if (spos >= length) {
00474                                 return (dpos);
00475                         }
00476                         c = source[spos++];
00477 
00478                         if (c == 0) {
00479                                 if (i > 0) {
00480                                         return (dpos);
00481                                 }
00482                                 return (dpos);
00483                         }
00484                         if (dtable[c] & 0x80) {
00486                                 i--;
00487                                 continue;
00488                         }
00489                         a[i] = (byte) c;
00490                         b[i] = (byte) dtable[c];
00491                 }
00492                 o[0] = (b[0] << 2) | (b[1] >> 4);
00493                 o[1] = (b[1] << 4) | (b[2] >> 2);
00494                 o[2] = (b[2] << 6) | b[3];
00495                 i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
00496                 if (i >= 1)
00497                         dest[dpos++] = o[0];
00498                 if (i >= 2)
00499                         dest[dpos++] = o[1];
00500                 if (i >= 3)
00501                         dest[dpos++] = o[2];
00502                 dest[dpos] = 0;
00503                 if (i < 3) {
00504                         return (dpos);
00505                 }
00506         }
00507 }
00508 
00509 
00510 
00516 void generate_uuid(char *buf) {
00517         static int seq = 0;
00518 
00519         sprintf(buf, "%s-%lx-%lx-%x",
00520                 serv_info.serv_nodename,
00521                 (long)time(NULL),
00522                 (long)getpid(),
00523                 (seq++)
00524         );
00525 }
00526 
00527 
00535 void CtdlMakeTempFileName(char *name, int len) {
00536         int i = 0;
00537 
00538         while (i++, i < 100) {
00539                 snprintf(name, len, "/tmp/ctdl.%04x.%04x",
00540                         getpid(),
00541                         rand()
00542                 );
00543                 if (!access(name, F_OK)) {
00544                         return;
00545                 }
00546         }
00547 }
00548 
00549 
00550 
00551 /*
00552  * \brief       case-insensitive substring search
00553  *
00554  *              This uses the Boyer-Moore search algorithm and is therefore quite fast.
00555  *              The code is roughly based on the strstr() replacement from 'tin' written
00556  *              by Urs Jannsen.
00557  *
00558  * \param       text    String to be searched
00559  * \param       pattern String to search for
00560  */
00561 char *bmstrcasestr(char *text, char *pattern) {
00562 
00563         register unsigned char *p, *t;
00564         register int i, j, *delta;
00565         register size_t p1;
00566         int deltaspace[256];
00567         size_t textlen;
00568         size_t patlen;
00569 
00570         textlen = strlen (text);
00571         patlen = strlen (pattern);
00572 
00573         /* algorithm fails if pattern is empty */
00574         if ((p1 = patlen) == 0)
00575                 return (text);
00576 
00577         /* code below fails (whenever i is unsigned) if pattern too long */
00578         if (p1 > textlen)
00579                 return (NULL);
00580 
00581         /* set up deltas */
00582         delta = deltaspace;
00583         for (i = 0; i <= 255; i++)
00584                 delta[i] = p1;
00585         for (p = (unsigned char *) pattern, i = p1; --i > 0;)
00586                 delta[tolower(*p++)] = i;
00587 
00588         /*
00589          * From now on, we want patlen - 1.
00590          * In the loop below, p points to the end of the pattern,
00591          * t points to the end of the text to be tested against the
00592          * pattern, and i counts the amount of text remaining, not
00593          * including the part to be tested.
00594          */
00595         p1--;
00596         p = (unsigned char *) pattern + p1;
00597         t = (unsigned char *) text + p1;
00598         i = textlen - patlen;
00599         while(1) {
00600                 if (tolower(p[0]) == tolower(t[0])) {
00601                         if (strncasecmp ((const char *)(p - p1), (const char *)(t - p1), p1) == 0) {
00602                                 return ((char *)t - p1);
00603                         }
00604                 }
00605                 j = delta[tolower(t[0])];
00606                 if (i < j)
00607                         break;
00608                 i -= j;
00609                 t += j;
00610         }
00611         return (NULL);
00612 }
00613 
00614 
00615 
00616 
00617 

Generated on Wed Jun 20 23:13:11 2007 for webcit by  doxygen 1.5.2