00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "cgi.h"
00022 #include <stdarg.h>
00023 #include <math.h>
00024
00025
00026 #define EATCOLIN(x) while (*x && (strchr(":",*x) != NULL)) x++
00027 #define EATWHITE(x) while (*x && (strchr(" \t\r\n",*x) != NULL)) x++
00028 #define EATTEXT(x) while (*x && (strchr(" \t\r\n",*x) == NULL)) x++
00029
00030 size_t int16ToUTF8(unsigned int in, char* out)
00031 {
00032 if (in < 0x80)
00033 {
00034 out[0]=(char)in;
00035 return 1;
00036 }
00037 else if (in < 0x800)
00038 {
00039 out[1] = (char)((in & 0x3f) | 0x80);
00040 out[0] = (char)((in >> 6) | 0xc0);
00041 return 2;
00042 }
00043 else
00044 {
00045 out[2] = (char)((in & 0x3f) | 0x80);
00046 out[1] = (char)(((in >> 6) & 0x3f) | 0x80);
00047 out[0] = (char)((in >> 12) | 0xe0);
00048 return 3;
00049 }
00050 }
00051
00052 static char basis_64[] =
00053 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00054
00058 int B64encode(char* in, char* out)
00059 {
00060 unsigned char c1=in[0], c2=0, c3=0;
00061 if (c1) c2 = in[1];
00062 if (c2) c3 = in[2];
00063 out[0] = basis_64[c1>>2];
00064 out[1] = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
00065
00066 if (c2)
00067 {
00068 out[2] = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
00069 out[3] = basis_64[c3 & 0x3F];
00070 return c3;
00071 }
00072 else if (c2)
00073 out[2] = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
00074 else
00075 out[2] = '=';
00076
00077 out[3] = '=';
00078 return 0;
00079 }
00080 int unB64(int c)
00081 {
00082 if (c >= 'A' && c <= 'Z') return c-'A';
00083 if (c >= 'a' && c <= 'z') return c-'a'+26;
00084 if (c >= '0' && c <= '9') return c-'0'+52;
00085 if (c == '=') return 62;
00086 if (c == '/') return 63;
00087 return -1;
00088 }
00089
00090
00105 int ContainsANSIChars(char* s)
00106 {
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 unsigned c = *s++ & 0x00ff;
00121 unsigned d;
00122
00123 while (c)
00124 {
00125 if (c & 0x80)
00126 {
00127 if ((c & 0x60) == 0) return 1;
00128 d = *s;
00129 if ((d & 0xc0) != 0x80) return 1;
00130
00131
00132
00133
00134 if ((c & 0x60) == 0x40)
00135 {
00136 s++;
00137 goto next;
00138 }
00139
00140 d = s[1];
00141 if ((d & 0xc0) != 0x80) return 1;
00142
00143 if ((c & 0xf0) == 0xe0)
00144 {
00145 s += 2;
00146 goto next;
00147 }
00148
00149 d = s[2];
00150 if ((d & 0xc0) != 0x80) return 1;
00151
00152 if ((c & 0xf8) == 0xf0)
00153 {
00154 s += 3;
00155 goto next;
00156 }
00157
00158 return 1;
00159 }
00160 next:
00161 c = *s++ & 0x00ff;
00162 }
00163
00164 return 0;
00165 }
00166
00167
00168 unsigned ANSIchars []=
00169 {
00170 8364,
00171 '?',
00172 8218,
00173 402,
00174 8222,
00175 8230,
00176 8224,
00177 8225,
00178 710,
00179 8240,
00180 352,
00181 8249,
00182 338,
00183 '?',
00184 381,
00185 '?',
00186 '?',
00187 8216,
00188 8217,
00189 8220,
00190 8221,
00191 8226,
00192 8211,
00193 8212,
00194 732,
00195 8482,
00196 353,
00197 8250,
00198 339,
00199 '?',
00200 382,
00201 376,
00202 };
00203
00204 char* ANSItoUTF8(char* s)
00205 {
00206 char* r = malloc(strlen(s)*4+1);
00207 char* c = r;
00208 for (; *s; s++)
00209 {
00210 unsigned x = (*s) & 0x00ff;
00211 if ((x & 0x80) == 0)
00212 {
00213 *c++ = x;
00214 continue;
00215 }
00216
00217 if ((x & 0x60) == 0)
00218 x = ANSIchars[x - 128];
00219
00220 c += int16ToUTF8(x, c);
00221 }
00222 *c=0;
00223 return r;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 void B64decode(char* write)
00258 {
00259 char* read = write;
00260 int x, step=0, i[2];
00261 while (*read && *read != '=')
00262 {
00263 x = unB64(*read);
00264 if (x == -1) break;
00265 i[step % 2]=x;
00266
00267 if (step % 4)
00268 *write++ = (char)((i[(step+1)%2] << ((step%4) * 2)) | (i[step%2] >> (6 - ((step%4) * 2)))) & 0x00ff;
00269
00270 read++;
00271 step = (step + 1) % 8;
00272 }
00273 *write = 0;
00274 }
00275
00276
00277
00278
00279
00280 void UTF7toUTF8(char* write)
00281 {
00282 char* read = write;
00283
00284 while (*read)
00285 {
00286 if (*read == '+')
00287 {
00288 int x, step, out, i[2], ch[2];
00289 if (read[1] == '-')
00290 {
00291 *write++ = *read++;
00292 read++;
00293 continue;
00294 }
00295 read++;
00296 step = 0;
00297 out = 0;
00298
00299 while (*read && *read != '-')
00300 {
00301 x = unB64(*read);
00302 if (x == -1) break;
00303 i[step % 2]=x;
00304
00305 if (step % 4)
00306 ch[out++%2] = ((i[(step+1)%2] << ((step%4) * 2)) | (i[step%2] >> (6 - ((step%4) * 2)))) & 0x00ff;
00307
00308 if (step == 2 || step == 5 || step == 7)
00309 write += int16ToUTF8((ch[0] << 8) | ch[1],write);
00310 read++;
00311 step = (step + 1) % 8;
00312 }
00313 if (*read == '-') read++;
00314 else if (*read) *write++ = *read++;
00315 }
00316 else
00317 {
00318 *write++ = *read++;
00319 }
00320 }
00321 *write = 0;
00322 }
00323
00324 char x2c(char *what) {
00325 register char digit;
00326
00327 digit =
00328 (char)(what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
00329 digit *=
00330 (char)16;
00331 digit +=
00332 (char)(what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
00333 return(digit);
00334 }
00335
00336 int ExpandUrl(char *url) {
00337 register int x,y;
00338
00339 for(x=0,y=0;url[y];++x,++y) {
00340 if((url[x] = url[y]) == '%') {
00341 url[x] = x2c(&url[y+1]);
00342 y+=2;
00343 }
00344 }
00345 url[x] = '\0';
00346 return x;
00347 }
00348
00349 int IsNumber(char *c,size_t length)
00350 {
00351
00352
00353
00354
00355 char *x;
00356 size_t i;
00357 if (!c) return 0;
00358 if (!*c) return 0;
00359 strtod(c,&x);
00360 i = x - c;
00361 return ((length == 0 && *x == 0) || (length != 0 && length == i));
00362 }
00363
00364 TextBuffer * NewBuffer(int length)
00365 {
00366 TextBuffer* t = CGIMALLOC(sizeof(TextBuffer));
00367 t->data = CGIMALLOC(length+1);
00368 t->data[length] = 0;
00369 t->size = length;
00370 t->used = 0;
00371 t->Next = NULL;
00372 t->Last = t;
00373 return t;
00374 }
00375
00376 void DeleteBuffer(TextBuffer* t)
00377 {
00378 while (t)
00379 {
00380 TextBuffer* n = t->Next;
00381 CGIFREE(t->data);
00382 CGIFREE(t);
00383 t = n;
00384 }
00385 }
00386
00387 size_t BufferWrite(TextBuffer* start,char* text)
00388 {
00389 if (text) return BufferWriteL(start,text,strlen(text));
00390 return 0;
00391 }
00392
00393 size_t BufferWriteL(TextBuffer* start,char* text,size_t length)
00394 {
00395 size_t current, next;
00396 TextBuffer* t = (TextBuffer*)start->Last;
00397
00398 if (length == 0) return 0;
00399
00400 if (length >= (t->size - t->used))
00401 {
00402 current = (t->size - t->used);
00403 next = length - current;
00404 }
00405 else
00406 {
00407 current = length;
00408 next = 0;
00409 }
00410
00411 memcpy(t->data + t->used,text,current);
00412 t->used += current;
00413
00414 if (next)
00415 {
00416 size_t i = 1024u;
00417 TextBuffer* tn;
00418
00419 if (i < next) i = next;
00420 start->Last = NewBuffer(i);
00421 t->Next = start->Last;
00422 tn = (TextBuffer*)t->Next;
00423 memcpy(tn->data, text + current, next);
00424 tn->used = next;
00425 }
00426
00427 return length;
00428 }
00429
00430 size_t BufferSize(TextBuffer* t)
00431 {
00432 size_t length = 0;
00433 while (t)
00434 {
00435 TextBuffer* n = t->Next;
00436 length += t->used;
00437 t = n;
00438 }
00439 return length;
00440 }
00441
00442 char* CopyBuffer(TextBuffer* t)
00443 {
00444 size_t l = BufferSize(t);
00445 char * x = CGIMALLOC(l+4);
00446 BufferRead(t,x,l+4);
00447 memset(x+l,0,4);
00448 return x;
00449 }
00450 #define MIN(a,b) (a<b?a:b)
00451
00452 size_t BufferRead(TextBuffer* start, char* out,size_t length)
00453 {
00454 size_t read=0;
00455
00456 while( read < length)
00457 {
00458 size_t x = MIN((length - read), start->used);
00459 memcpy(out + read, start->data, x);
00460 read += x;
00461 if (!start->Next) break;
00462 start = (TextBuffer*)start->Next;
00463 }
00464 return read;
00465 }
00466
00467
00468 int ReadUntilWord2(FILE * in, char * out,size_t max,char*check1,char*check2)
00469 {
00470 size_t len = strlen(check1);
00471 size_t pos = 0;
00472 char* buf = 0;
00473 int quit = 0;
00474
00475 if (len == 0) {return 0;}
00476
00477 buf = CGIMALLOC(len+1);
00478 buf[len]=0;
00479
00480 if (fread(buf,len,1,in) != 1) {CGIFREE(buf); return 0;}
00481
00482 len --;
00483
00484 while (stricmp(buf,check1) && (check1 == check2 ? 1 : stricmp(buf,check2)))
00485 {
00486 if (out)
00487 if (pos < max)
00488 {
00489 out[pos] = buf[0];
00490 pos ++;
00491 if (pos < max) out[pos]=0;
00492 }
00493
00494 if(quit) {CGIFREE(buf); return 0;}
00495
00496 memmove((char*)buf,(char*)buf+1,len);
00497
00498 if (fread((char*)buf + len,1,1,in) != 1) {quit=1;}
00499 }
00500
00501 if (!stricmp(buf,check1)) len = 1;
00502 else len = 2;
00503 CGIFREE(buf);
00504 return len;
00505 }
00506
00507 int ReadUntilWord(FILE * in, char * out,size_t max,char*check)
00508 {
00509 return ReadUntilWord2(in,out,max,check,check);
00510 }
00511
00512 int ReadUntilWordS2(FILE * in,STREAM out, char * check1, char* check2)
00513 {
00514 size_t len = strlen(check1);
00515 size_t l2;
00516 char* buf;
00517
00518 if (len == 0) return 0;
00519 buf = CGIMALLOC(len+1);
00520 buf[len]=0;
00521 l2 = len - 1;
00522
00523 if (fread(buf,len,1,in) != 1)
00524 {
00525 CGIFREE(buf); return 0;
00526 }
00527
00528 while (stricmp(buf,check1) && (check1 == check2 ? 1 : stricmp(buf,check2)))
00529 {
00530 if (out)
00531 {
00532 char c[2];
00533 c[0]=buf[0];
00534 c[1]=0;
00535 HTMLWrite(out,c);
00536 }
00537 memmove((char*)buf,(char*)buf+1,len);
00538 if (fread((char*)buf + l2,1,1,in) != 1) {CGIFREE(buf); return 0;}
00539 }
00540
00541 if (!stricmp(buf,check1)) len = 1;
00542 else len = 2;
00543 CGIFREE(buf);
00544 return len;
00545 }
00546
00547 int ReadUntilWordS(FILE * in,STREAM out, char * check)
00548 {
00549 return ReadUntilWordS2(in,out,check,check);
00550 }
00551
00552 void HTMLSend(STREAM htmlout, TextBuffer* start)
00553 {
00554 if (!htmlout) return;
00555 while (start)
00556 {
00557 HTMLWriteL(htmlout,start->data,start->used);
00558 start = (TextBuffer*)start->Next;
00559 }
00560 }
00561
00562 FILE* FileOpen(char* argv0, char* file,char* extension)
00563 {
00564 char filename[MAXPATH];
00565 if (!file) return 0;
00566 if (!*file) return 0;
00567 ExpandLocalPath(argv0,filename,file,extension);
00568 return CGIFOPEN(filename,"rb");
00569 }
00570
00571 int ReadUntilChar(FILE * in, char * out, size_t max, char * stop, int skip)
00572 {
00573 char c;
00574 if (out) *out = 0;
00575 if (max) max--;
00576 if (feof(in)) return -1;
00577 while (fread(&c,1,1,in)>0)
00578 {
00579 if (skip && skip == c)
00580 continue;
00581
00582 if (strchr(stop,c))
00583 {
00584 if (out && max) *out = 0;
00585 return c;
00586 }
00587 else
00588 {
00589 if (out && max)
00590 {
00591 *out = c;
00592 out++;
00593 *out = 0;
00594 max--;
00595 }
00596 }
00597 }
00598 return -1;
00599 }
00600
00601 CGINameValue* ReadHTMLAttributes(FILE * source,size_t max)
00602 {
00603 CGINameValue * v = NewNVP(max > 0 ? max : 16);
00604 int i = 0;
00605 char temp[4096];
00606
00607 while (i < 20)
00608 {
00609 int e = ReadUntilChar(source,temp,sizeof(temp)-1,"=> \t\r\n",0);
00610 char *s = temp;
00611 while (*s && strchr(" \t\r\n",*s)!=NULL) s++;
00612
00613 if (*s)
00614 {
00615 v[i].name = strdup(s);
00616
00617 if (e == '=')
00618 {
00619 fread(temp,1,1,source);
00620 if (temp[0] == '\"')
00621 e = ReadUntilChar(source,temp,sizeof(temp),"\"",0);
00622 else
00623 e = ReadUntilChar(source,temp+1,sizeof(temp)-1,"> \t\r\n",0);
00624
00625 v[i].value = strdup(temp);
00626 }
00627 i++;
00628 }
00629 if (e == '>' || e == -1) return v;
00630 }
00631 ReadUntilChar(source,0,0,">",0);
00632 return v;
00633 }
00634
00635 #ifdef __WINCE__
00636 extern char serverRootA[MAXPATH];
00637 #endif
00638
00639 void ExpandLocalPath(char * argv0, char * fn,char* finish,char* a)
00640 {
00641 char * c;
00642 #ifdef XP_WIN
00643 int i;
00644 #endif
00645 #ifdef __WINCE__
00646 if (finish[0] == '\\')
00647 #elif defined XP_WIN
00648 if ((finish[0] == '\\' && finish[1] == '\\') || (finish[0] != 0 && finish[1] == ':'))
00649 #else
00650 if (finish[0] == '/')
00651 #endif
00652 {
00653 strcpy(fn,finish);
00654 if (a != NULL) strcat(fn,a);
00655 return;
00656 }
00657
00658 strcpy(fn,argv0);
00659 #ifdef XP_WIN
00660 c = strrchr(fn,'\\');
00661 #else
00662 c = strrchr(fn,'/');
00663 #endif
00664 if (c)
00665 {
00666 c++;
00667 }
00668 else
00669 {
00670 #ifdef __WINCE__
00671 strcpy(fn,serverRootA);
00672 #else
00673 getcwd(fn, MAXPATH);
00674 #ifdef XP_WIN
00675 strcat(fn, "\\");
00676 #else
00677 strcat(fn, "/");
00678 #endif
00679 #endif
00680 c = fn + strlen(fn);
00681
00682 }
00683 strcpy(c,finish);
00684 if (a != NULL) strcat(c,a);
00685 #ifdef XP_WIN
00686 for (i=0; c[i]; i++)
00687 if (c[i] == '/') c[i] = '\\';
00688 #endif
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 char * GetSetting(CGINameValue*section,char * key, char* def)
00706 {
00707 CGINameValue * n;
00708 n = GetField(section, key);
00709 if (n == NULL) return def;
00710 if (n->value == NULL) return def;
00711 if (n->value[0] == 0) return def;
00712 return n->value;
00713 }
00714
00715
00716 #ifdef WINCGI
00717 char module[256];
00718 int SplitArgs (char *str, char *argv[],int max)
00719 {
00720 int argc;
00721 char *c;
00722
00723 GetModuleFileName(0,module,256);
00724
00725 argv[0]=module;
00726 argc = 1;
00727 c = str;
00728 while (*c && argc < max)
00729 {
00730 while(*c && isspace(*c)) c++;
00731 if (*c) argv[argc] = c;
00732 while(*c && !isspace(*c)) c++;
00733 if (*c) { *c = 0; c++; }
00734 argc++;
00735 }
00736 argv[argc]=0;
00737 return argc;
00738 }
00739 #endif
00740
00741 void swapchars(char * str, char find, char repl)
00742 {
00743 int x;
00744 for(x=0;str[x];x++) if(str[x] == find) str[x] = repl;
00745 }
00746
00747 #ifndef stricmp
00748 int stricmp(const char * a,const char * b)
00749 {
00750 int i;
00751 while (*a && *b)
00752 {
00753 i = toupper(*a) - toupper(*b);
00754 if (i != 0) return i;
00755 a++;
00756 b++;
00757 }
00758 return *a - *b;
00759 }
00760
00761 int strnicmp(const char * a,const char * b, size_t length)
00762 {
00763 int i;
00764 while (*a && *b && length)
00765 {
00766 i = toupper(*a) - toupper(*b);
00767 if (i != 0) return i;
00768 ++a;
00769 ++b;
00770 --length;
00771 }
00772 return length ? toupper(*a) - toupper(*b) : 0;
00773 }
00774 #endif
00775
00776 #ifndef strdup
00777 char *strdup(const char *s)
00778 {
00779 size_t length ;
00780 length = s ? strlen(s) : 0;
00781 return strndup((char*)s,length);
00782 }
00783 #endif
00784
00785 char* strdup3(char* a,char* b,char*c)
00786 {
00787 size_t l = strlen(a) + strlen(b)+strlen(c);
00788 char* x = CGIMALLOC(l+1);
00789 x[0]=0;
00790 if (x) strcpy(x,a);
00791 if (b) strcat(x,b);
00792 if (c) strcat(x,c);
00793 return x;
00794 }
00795
00796 char *strndup(char *s,size_t length)
00797 {
00798 char * c;
00799 c = CGIMALLOC(length+3);
00800 if (s && length) strncpy(c,s,length);
00801 c[length]=0;
00802 return c;
00803 }
00804
00809 char * PopList2(char* list,int end)
00810 {
00811 char* r;
00812 size_t l,m;
00813 char* x = list;
00814 l=0;
00815
00816 if (end)
00817 while (x[l] && x[l] != end) l++;
00818 else
00819 while (x[l] && x[l] != ',' && x[l] != ' ') l++;
00820
00821 if (!x[l]) return NULL;
00822 x = list + l + 1;
00823 m = strlen(x);
00824 r = CGIMALLOC(l+1);
00825
00826 memcpy(r,list,l);
00827 r[l]=0;
00828
00829 memmove(list,x,m);
00830 list[m]=0;
00831
00832 x = list + m + 1;
00833 memcpy(x,r,l);
00834 x[l]=0;
00835
00836 CGIFREE(r);
00837 return x;
00838 }
00839
00840 char * PopList(CGINameValue*list,char* key,int end)
00841 {
00842 char* x = GetFieldValue(list,key);
00843 char* p;
00844 size_t i = 0;
00845
00846
00847 while (x[i] == ',' || x[i] == ' ') i++;
00848 if (i)
00849 memmove(x,x+i,strlen(x+i) + 1);
00850
00851 p = PopList2(x,end);
00852
00853
00854 i = strlen(x);
00855 while (i && (x[i-1] == ',' || x[i-1] == ' ')) i--;
00856 x[i]=0;
00857
00858 if (p != NULL) return p;
00859 else
00860 {
00861 size_t l = strlen(x);
00862 memmove(x+1,x,strlen(x));
00863 x[l+1] = 0;
00864 x[0]=0;
00865 return x+1;
00866 }
00867 }
00868
00869 int strmatch(char * c1,char * c2, size_t length,char* end,int cs)
00870 {
00871 if (length) do
00872 {
00873 if (cs)
00874 {
00875 if (*c1 != *c2) return 0;
00876 }
00877 else if (toupper(*c1) != toupper(*c2)) return 0;
00878
00879 c1++;
00880 c2++;
00881 length--;
00882
00883 if ((*c2==0) && (!length||*c1==0||strchr(end,*c1))) return 1;
00884 } while (length);
00885 return 0;
00886 }
00887
00888 int HasTokenX(char * c, char * code,int*loc,int cs)
00889 {
00890 size_t length = strlen(c);
00891 size_t i = 0;
00892 if (loc) *loc = 1;
00893
00894 while (i < length && (c[i]==',' || c[i]==' ')) {i++; }
00895
00896 while (i < length)
00897 {
00898 if (c[i] == ','|| c[i]==' ') { i++; if (loc) (*loc)++;}
00899 else
00900 {
00901 if (strmatch(c+i,code,length,", ",cs)) return 1;
00902 while (i<length && c[i] != ',' && c[i] != ' ') {i++; }
00903 }
00904 }
00905 return 0;
00906 }
00907
00908 int HasToken(char * c, char * code,int*loc)
00909 {return HasTokenX(c,code,loc,1);}
00910
00911 int HasTokenI(char * c, char * code,int*loc)
00912 {return HasTokenX(c,code,loc,0);}
00913
00914 void ClearToken(char * c,char * code)
00915 {
00916 size_t length=strlen(c);
00917 while (length)
00918 {
00919 if (*c == ',' || *c == ' ') { c++; length--; }
00920 else
00921 {
00922 if (strmatch(c,code,length,", ",1))
00923 {
00924 size_t cl = strlen(code);
00925 while (c[cl] == ',' || c[cl] == ' ') cl++;
00926
00927 if (length >= cl)
00928 {
00929 length -= cl;
00930 memmove(c,c+cl,length);
00931 memset(c+length,0,cl);
00932 }
00933 return;
00934 }
00935 while (length && *c != ',' && *c != ' ') {c++; length--;}
00936 }
00937 }
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00952 STREAM NewStream(int size)
00953 {
00954 #if defined(FASTCGI)
00955 STREAM str = (STREAM)CGIMALLOC(sizeof(FCGISTREAM));
00956 str->strp=0;
00957 #else
00958 STREAM str = (STREAM)CGIMALLOC(sizeof(EZSSTREAM));
00959 str->f=0;
00960 #endif
00961 #ifdef __WINCE__
00962 str->s = 0;
00963 #endif
00964 #ifdef ISAPICGI
00965 str->ecb = 0;
00966 str->pos = 0;
00967 #endif
00968 str->t = NewBuffer(size);
00969 return str;
00970 }
00971
00972 void DeleteStream(STREAM str)
00973 {
00974 if (!str) return;
00975 if (str->t) DeleteBuffer(str->t);
00976 CGIFREE(str);
00977 }
00978
00980 char * CopyStream(STREAM str)
00981 {
00982 return CopyBuffer(str->t);
00983 }
00984
00985
00986
00987 void HTMLPrintf(STREAM htmlout,char * formatting, ...)
00988 {
00989 if (htmlout)
00990 {
00991 va_list argptr;
00992 va_start(argptr, formatting);
00993 #ifdef FASTCGI
00994 if (htmlout->strp)
00995 {
00996 FCGX_VFPrintF(htmlout->strp,formatting,argptr);
00997 }
00998 else
00999 #endif
01000 if (htmlout->f)
01001 vfprintf(htmlout->f,formatting, argptr);
01002 else
01003 {
01004 char temp[MAXBUF];
01005 vsprintf(temp,formatting,argptr);
01006 HTMLWrite(htmlout,temp);
01007 }
01008
01009 va_end(argptr);
01010 }
01011 }
01012
01013 size_t UTF8ToUCS2C(char* in,int *c)
01014 {
01015 if ((in[0] & 0x80) == 0) {*c=in[0]; return 1;}
01016
01017
01018 if (((in[0] & 0xe0) == 0xc0) && ((in[1] & 0xc0) == 0x80))
01019 { *c = (int)( ((in[0] & 0x1f) << 6) | (in[1] & 0x3f)); return 2;}
01020
01021
01022 if (((in[0] & 0xf0) == 0xe0) && ((in[1] & 0xc0) == 0x80) && ((in[2] & 0xc0 )== 0x80))
01023 { *c = (int)(((in[0] & 0x0f) << 12) | ((in[1] & 0x3f) << 6)| (in[2] & 0x3f)); return 3;}
01024
01025
01026 if (((in[0] & 0xf8) == 0xf0) && ((in[1] & 0xc0) == 0x80) && ((in[2] & 0xc0 )== 0x80)&& ((in[3] & 0xc0) == 0x80))
01027 { *c = (int)(((in[0] & 0x0f) << 18) | ((in[1] & 0x3f) << 12)| ((in[2] & 0x3f) <<6)| ((in[3] & 0x3f))); return 4;}
01028
01029 return 0;
01030 }
01031
01032 void HTMLEscape(STREAM htmlout, char* out)
01033 {
01034 size_t k;
01035 int c=0;
01036
01037 if (!htmlout) return;
01038
01039 while (out && out[0])
01040 {
01041 k = UTF8ToUCS2C(out,&c);
01042 if (k > 1)
01043 {
01044 char x[32];
01045 sprintf(x,"&#%d;",c);
01046 HTMLWriteL(htmlout,x,strlen(x));
01047 out += k;
01048 continue;
01049 }
01050
01051 switch (out[0])
01052 {
01053 case '<': HTMLWriteL(htmlout,"<",4); out++; break;
01054 case '>': HTMLWriteL(htmlout,">",4); out++; break;
01055 case '&': HTMLWriteL(htmlout,"&",5); out++; break;
01056 case '\"': HTMLWriteL(htmlout,""",6); out++; break;
01057 default: HTMLWriteL(htmlout,out,1); out++;
01058 }
01059 }
01060 }
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 void HTMLWrite(STREAM htmlout,char* data)
01080 {
01081 if (!data) return;
01082 if (!htmlout) return;
01083 HTMLWriteL(htmlout,data,strlen(data));
01084 }
01085
01086
01087 #ifndef VPWSCGI
01088 void HTMLWriteL(STREAM htmlout,char* data,size_t length)
01089 {
01090 if (length==0||data==NULL||htmlout==NULL) return;
01091
01092 #if defined(FASTCGI)
01093 if (htmlout->strp)
01094 FCGX_PutStr(data,length,htmlout->strp);
01095 else
01096 #endif
01097 #ifdef ISAPICGI
01098 if (htmlout->ecb !=NULL)
01099 {
01100 int c = length + htmlout->pos;
01101 if (c < MAXPATH)
01102 {
01103 memcpy(htmlout->buffer + htmlout->pos,data,length);
01104 htmlout->pos = c;
01105 return;
01106 }
01107
01108 c = MAXPATH - htmlout->pos;
01109
01110 if (c) memcpy(htmlout->buffer + htmlout->pos, data, c);
01111 htmlout->pos = MAXPATH;
01112 htmlout->ecb->WriteClient(htmlout->ecb->ConnID, (PVOID)htmlout->buffer,&htmlout->pos,0);
01113 htmlout->pos = length - c;
01114
01115
01116 if (htmlout->pos >= MAXPATH)
01117 {
01118 htmlout->ecb->WriteClient(htmlout->ecb->ConnID, (PVOID) (data + c), &htmlout->pos,0);
01119 htmlout->pos = 0;
01120 return;
01121 }
01122 memcpy(htmlout->buffer,data+c,htmlout->pos);
01123 }
01124 else
01125 #endif
01126 if (htmlout->f !=NULL)
01127 fwrite(data,1,length,htmlout->f);
01128 else if (htmlout->t !=NULL)
01129 BufferWriteL(htmlout->t,data,length);
01130 }
01131 #endif
01132
01133 void HTMLWriteFileF(STREAM htmlout,FILE* handle)
01134 {
01135 char temp[MAXPATH];
01136 size_t length;
01137 if (!htmlout) return;
01138 length = fread(temp,1,sizeof(temp),handle);
01139 while(length>0)
01140 {
01141 HTMLWriteL(htmlout,temp,length);
01142 length = fread(temp,1,sizeof(temp),handle);
01143 }
01144 }
01145
01146 int HTMLWriteFile(STREAM htmlout,char * filename)
01147 {
01148 FILE * handle;
01149 if (!htmlout) return 0;
01150 handle = CGIFOPEN(filename,"rb");
01151 if (!handle) return 0;
01152
01153 HTMLWriteFileF(htmlout,handle);
01154 CGIFCLOSE(handle);
01155
01156 return 1;
01157 }
01158
01159 void DebugShowNVP(STREAM htmlout,CGINameValue* v)
01160 {
01161 if (!htmlout) return;
01162 while (v->name)
01163 {
01164 if (*v->name)
01165 {
01166 HTMLWrite(htmlout,v->name);
01167 if (v->value)
01168 {
01169 HTMLWrite(htmlout,"=");
01170 HTMLWrite(htmlout,v->value);
01171 }
01172 HTMLWrite(htmlout,"\n");
01173 }
01174 v++;
01175 }
01176 }
01177
01178 void GetTime(char * Date,char * Time,int type)
01179 {
01180 #ifdef __WINCE__
01181 SYSTEMTIME tb;
01182
01183
01184 GetLocalTime(&tb);
01185
01186 switch (type)
01187 {
01188 case 2:
01189 if (Date) sprintf(Date,"%2.2d/%2.2d/%4.4d",
01190 tb.wMonth,tb.wDay,tb.wYear);
01191 if (Time) sprintf(Time,"%2.2d:%2.2d:%2.2d",
01192 tb.wHour,tb.wMinute,tb.wSecond); break;
01193 case 1:
01194 if (Date) sprintf(Date,"%2.2d/%2.2d/%4.4d",
01195 tb.wDay,tb.wMonth,tb.wYear);
01196 if (Time) sprintf(Time,"%2.2d:%2.2d:%2.2d",
01197 tb.wHour,tb.wMinute,tb.wSecond); break;
01198
01199 default:
01200 if (Date) sprintf(Date,"%4.4d%2.2d%2.2d",
01201 tb.wYear,tb.wMonth,tb.wDay);
01202 if (Time) sprintf(Time,"%2.2d%2.2d%2.2d",
01203 tb.wHour,tb.wMinute,tb.wSecond);
01204 }
01205
01206 #else
01207 time_t timer;
01208 struct tm *tb;
01209
01210
01211 time(&timer);
01212
01213
01214 tb = localtime(&timer);
01215 switch (type)
01216 {
01217 case 2:
01218 if (Date) sprintf(Date,"%2.2d/%2.2d/%4.4d",
01219 tb->tm_mday,tb->tm_mon+1,tb->tm_year+1900);
01220 if (Time) sprintf(Time,"%2.2d:%2.2d:%2.2d",
01221 tb->tm_hour,tb->tm_min,tb->tm_sec); break;
01222 case 1:
01223 if (Date) sprintf(Date,"%2.2d/%2.2d/%4.4d",
01224 tb->tm_mon+1,tb->tm_mday,tb->tm_year+1900);
01225 if (Time) sprintf(Time,"%2.2d:%2.2d:%2.2d",
01226 tb->tm_hour,tb->tm_min,tb->tm_sec); break;
01227
01228 default:
01229 if (Date) sprintf(Date,"%4.4d%2.2d%2.2d",
01230 tb->tm_year+1900,tb->tm_mon+1,tb->tm_mday);
01231 if (Time) sprintf(Time,"%2.2d%2.2d%2.2d",
01232 tb->tm_hour,tb->tm_min,tb->tm_sec);
01233 }
01234 #endif
01235 }
01236
01237 double Div(double a, double b)
01238 {
01239 if (b == 0.0) return 0.0;
01240 return a / b;
01241 }
01242
01243 #if 0
01244
01245 #define Power(x,y) pow(x,y)
01246 #else
01247 double Power(double x, double y)
01248 {
01249 int neg = 0;
01250 if (x < 0)
01251 {
01252 if (fmod(y,1.0) != 0.0) return 0.0;
01253
01254 if (fmod(y,2.0) != 0.0) neg = 1;
01255 x = -x;
01256 }
01257
01258 #ifdef XP_WIN
01259 x = exp(log(x) * y);
01260 #else
01261 return pow(x,y);
01262 #endif
01263 return neg ? -x : x;
01264
01265
01266
01267
01268
01269
01270
01271
01272 }
01273 #endif
01274
01275 int StringLength(char* text)
01276 {
01277 int i = 1;
01278 int end = text[0];
01279 while (text[i])
01280 {
01281 if (text[i] == '\\') i++;
01282 else if (text[i] == end) break;
01283 i++;
01284 }
01285 return i;
01286 }
01287
01288 int FindEndChar(char * text,char start,char finish,int skipquote)
01289 {
01290 int pcount = 0;
01291 int i = 0;
01292 while (text[i])
01293 {
01294 if (text[i] == start ) pcount ++;
01295 else if (text[i] == finish ) pcount --;
01296 else if (skipquote)
01297 {
01298 if (text[i] == '\"' || text[i] == '\'')
01299 i += StringLength(text);
01300 }
01301 if (pcount == 0) return i;
01302 i++;
01303 }
01304 return -1;
01305 }
01306
01307 char * EvaluateExpressionL(CGINameValue*v, CGINameValue*v2, char* equation,size_t length)
01308 {
01309 char * c;
01310 char * x = CGIMALLOC(length+1);
01311 strncpy(x,equation,length);
01312 x[length]=0;
01313 c = EvaluateExpression(v,v2,x);
01314 CGIFREE(x);
01315 return c;
01316 }
01317
01318 double EvaluateAlgebraL(CGINameValue*v, CGINameValue*v2,char* equation,size_t length)
01319 {
01320 double c;
01321 char * x = CGIMALLOC(length+1);
01322 strncpy(x,equation,length);
01323 x[length]=0;
01324 c = EvaluateAlgebra(v,v2,x);
01325 CGIFREE(x);
01326 return c;
01327 }
01328
01329 char* GetField2(CGINameValue*v, CGINameValue*v2, char* x)
01330 {
01331 if (x[0] == '$')
01332 {
01333 if (v2)
01334 v = v2;
01335 x++;
01336 }
01337
01338 return GetFieldValue(v,x);
01339 }
01340
01341 char * EvaluateExpression(CGINameValue*v, CGINameValue*v2, char* equation)
01342 {
01343 char *c = strrchr(equation,' ');
01344 if (c) *c = 0;
01345 EATWHITE(equation);
01346
01347 if (strcspn(equation,"(+-*/^%") != strlen(equation))
01348 {
01349 double d = EvaluateAlgebra(v,v2,equation);
01350 int i = (int)d;
01351 char*t = CGIMALLOC(64);
01352 if (i == d)
01353 sprintf(t,"%d",i);
01354 else
01355 sprintf(t,"%f",d);
01356 return t;
01357 }
01358 else if (IsNumber(equation,0))
01359 return strdup(equation);
01360 else
01361 return strdup(GetField2(v,v2,equation));
01362 }
01363
01369 double EvaluateAlgebra(CGINameValue * v, CGINameValue*v2, char * equation)
01370 {
01371 char * c, *left, *right;
01372 double lastmath;
01373 size_t length;
01374
01375 if (equation == NULL) return 0.0;
01376
01377 EATWHITE(equation);
01378 if (*equation == '=') equation++;
01379
01380 c = strrchr(equation,' ');
01381 if (c) *c = 0;
01382
01383
01384 length = strcspn(equation,"(+-*/^%");
01385
01386
01387 if ((length) == strlen(equation))
01388 return strtod(GetField2(v,v2,equation),0);
01389
01390
01391 right = strdup(equation + length);
01392
01393
01394 left = strndup(equation,length);
01395
01396
01397 if (*left && !IsNumber(left,0))
01398 c = GetField2(v,v2,left);
01399 else
01400 c = 0;
01401
01402 if (c && *c)
01403 lastmath = strtod(c,0);
01404 else
01405 lastmath = strtod(left,0);
01406
01407 c = right;
01408
01409 while (c && *c)
01410 {
01411 double math;
01412 char * d, * argument ;
01413 EATWHITE(c);
01414 if (*c == '(')
01415 argument = c;
01416 else
01417 argument = c + 1;
01418 EATWHITE(argument);
01419 if (isdigit(*argument))
01420 math = strtod(argument,&d);
01421 else if (*argument != '(')
01422 {
01423 length = strcspn(argument,"(+-*/^% \t\r\n");
01424 d = argument+length;
01425 math = EvaluateAlgebraL(v,v2,argument,length);
01426 }
01427 else
01428 {
01429 int l = FindEndChar(argument,'(',')',0);
01430 d = argument + l + 1;
01431 if (l < 2) break;
01432 math = EvaluateAlgebraL(v,v2,argument+1,l-2);
01433 }
01434
01435 switch (*c) {
01436 case '(': lastmath = math; break;
01437 case '+': lastmath += math; break;
01438 case '-': lastmath -= math; break;
01439 case '*': lastmath *= math; break;
01440 case '^': lastmath = Power(lastmath,math); break;
01441 case '/': lastmath = Div(lastmath,math); break;
01442 case '%': lastmath = ((int)(math)) ?((int)lastmath)%(int)(math):0; break;
01443 default: break; }
01444 c = d;
01445 }
01446
01447 CGIFREE(left);
01448 CGIFREE(right);
01449 return lastmath;
01450 }
01451
01452 char * strn2istr(char *s1, char *s2,size_t l2)
01453 {
01454 while (*s1)
01455 {
01456 if (strnicmp(s1,s2,l2) == 0) return s1;
01457 s1++;
01458 }
01459 return 0;
01460 }
01461
01462 char * stristr(char *s1, char *s2)
01463 {
01464 return strn2istr(s1,s2,strlen(s2));
01465 }
01466
01467 int DoEvaluateLogic(char* current,CGINameValue* Variables,CGINameValue* Var2,char** lastc,int eval);
01468 int DoEvaluateComparison(char* Comparison ,CGINameValue* v,CGINameValue* Var2,char** lastc,int eval);
01469 int LogicSub(char* Comparison ,CGINameValue* v,CGINameValue* Var2,char** lastc,int eval)
01470 {
01471 int bnot = 0;
01472 int ret;
01473 if (Comparison[0] == '!')
01474 {
01475 Comparison++;
01476 EATWHITE(Comparison);
01477 bnot = 1;
01478 }
01479 if (Comparison[0] == '(')
01480 ret = DoEvaluateLogic(Comparison+1,v,Var2,lastc,eval);
01481 else
01482 ret = DoEvaluateComparison(Comparison,v,Var2,lastc,eval);
01483
01484 if (ret < 0) return ret;
01485 return ret ^ bnot;
01486 }
01487
01489 int DoEvaluateLogic(char* current,CGINameValue* Variables,CGINameValue* Var2,char** lastc,int eval)
01490 {
01491 int left, right;
01492 if (!eval && !lastc)
01493 return 0;
01494
01495 EATWHITE(current);
01496
01497 if (!*current) return 1;
01498
01499 left = LogicSub(current,Variables,Var2,¤t,eval);
01500 if (left < 0) return -1;
01501
01502 EATWHITE(current);
01503
01504 while (*current)
01505 {
01506 int op = *current;
01507 int neg = 0;
01508
01509 if (op == ')')
01510 { current ++; break;}
01511
01512 if (op == '|' || op == '&' || op == '^')
01513 while (*current == op) current++;
01514 else break;
01515
01516 EATWHITE(current);
01517 if (!*current) return -1;
01518 right = LogicSub(current,Variables,Var2,¤t,eval);
01519 if (right < 0) return -1;
01520 if (neg) right = !right;
01521
01522 switch (op)
01523 {
01524 case '|': left = left || right; break;
01525 case '&': left = left && right; break;
01526 case '^': left = left ^ right; break;
01527 default: return -1;
01528 }
01529 EATWHITE(current);
01530 }
01531 if (lastc) *lastc = current;
01532 return left;
01533 }
01534
01535 int EvaluateLogic(char* line,CGINameValue* Variables,CGINameValue* Var2)
01536 {
01537 return DoEvaluateLogic(line,Variables,Var2,0,1);
01538 }
01539
01540 int ComparisonEvaluation(char*field,char*comp,size_t rlength,int op,int isundef)
01541 {
01542 int result = 0;
01543 if (isundef && !field)
01544 {
01545 field = comp = "undefined";
01546 if (op == 9) op = 1;
01547 rlength = 9;
01548 }
01549 else if (!field) return -1;
01550
01551 {
01552 char * rval = strndup(comp,rlength);
01553
01554 switch(op)
01555 {
01556 case 0: if (strlen(field)) if (*field != '0') result = 1;
01557 break;
01558
01559 case 1: if (strlen(field) == rlength)
01560 if (!strnicmp(field,comp,rlength))
01561 result = 1;
01562 break;
01563
01564 case 2: if (strtod(field,NULL) > strtod(rval,NULL)) result = 1; break;
01565 case 3: if (strtod(field,NULL) < strtod(rval,NULL)) result = 1; break;
01566 case 4: if (strn2istr(field,rval,rlength) != NULL) result = 1; break;
01567 case 5: if (strtod(field,NULL) >= strtod(rval,NULL)) result = 1; break;
01568 case 6: if (strtod(field,NULL) <= strtod(rval,NULL)) result = 1; break;
01569 case 7: if (strlen(field) != rlength || strnicmp(field,rval,rlength)) result = 1; break;
01570 case 8: if (strn2istr(field,rval,rlength) == NULL) result = 1; break;
01571 case 9: if (strtod(field,NULL) == strtod(rval,NULL)) result = 1; break;
01572 case 10: if (HasToken(field,rval,NULL)) result = 1;
01573
01574 }
01575 CGIFREE(rval);
01576 }
01577 return result;
01578 }
01579
01584 int DoEvaluateComparison(char* Comparison ,CGINameValue* v,CGINameValue* Var2,char** lastc,int eval)
01585 {
01586 char *comp, *freeme=0;
01587 int op = 0;
01588 int result;
01589 int ORsearch = 0;
01590 size_t x,length;
01591 int bnot = 0;
01592 int isundef = 0;
01593 size_t rlength = 0;
01594
01595 if (!v) return 0;
01596 if (!eval && !lastc)
01597 return 0;
01598
01599 if (lastc) *lastc = Comparison;
01600 if (Comparison[0] == 0) return -1;
01601
01602 if (Comparison[0] == '!')
01603 {
01604 bnot = 1;
01605 Comparison++;
01606 EATWHITE(Comparison);
01607 }
01608
01609 if (Comparison[0] == '/')
01610 {
01611 Comparison++;
01612 ORsearch = 1;
01613 }
01614
01615
01616
01617 comp = Comparison;
01618
01619 while (op == 0 && comp[0])
01620 {
01621 if (!strnicmp(comp,"gte ",4)){op = 5; rlength = 4;}
01622 else if (!strnicmp(comp,"has ",4)){op = 10; rlength = 4; ORsearch = 1;}
01623 else if (!strnicmp(comp,">=",2)) {op = 5; rlength = 2;}
01624 else if (!strnicmp(comp,"<=",2)) {op = 6; rlength = 2;}
01625 else if (!strnicmp(comp,"lte ",4)){op = 6; rlength = 3;}
01626 else if (!strnicmp(comp,">",1)) {op = 2; rlength = 1;}
01627 else if (!strnicmp(comp,"gt ",3)) {op = 2; rlength = 3;}
01628 else if (!strnicmp(comp,"<",1)) {op = 3; rlength = 1;}
01629 else if (!strnicmp(comp,"lt ",3)) {op = 3; rlength = 3;}
01630 else if (!strnicmp(comp,"=~",2)) {op = 4; rlength = 2;}
01631 else if (!strnicmp(comp,"!~",2)) {op = 8; rlength = 2;}
01632 else if (!strnicmp(comp,"s ",2)) {op = 4; rlength = 2;}
01633 else if (!strnicmp(comp,"eq ",3)) {op = 1; rlength = 2;}
01634 else if (!strnicmp(comp,"===",3)) {op = 9; rlength = 3;}
01635 else if (!strnicmp(comp,"==",2)) {op = 9; rlength = 2;}
01636 else if (!strnicmp(comp,"=",1)) {op = 1; rlength = 1;}
01637 else if (!strnicmp(comp,"!=",2)) {op = 7; rlength = 2;}
01638 else if (!strnicmp(comp,"ne ",3)) {op = 7; rlength = 2;}
01639 else if (strchr("?:",comp[0])) break;
01640 else if (strchr(" \t\r\n",comp[0])) EATWHITE(comp);
01641 else if (strchr("~=<>!",comp[0])) return -1;
01642 else {
01643 while (comp[0] && strchr("~=<>! ",comp[0]) == NULL) comp++;
01644 EATWHITE(comp); }
01645 }
01646
01647 if (!*comp)
01648 return -1;
01649
01650 length = comp - Comparison;
01651 if (!length)
01652 return -1;
01653
01654
01655 while (length && strchr(" \r\t\n",Comparison[length-1])) length --;
01656
01657 comp += rlength;
01658 EATWHITE(comp);
01659
01660 rlength = 0;
01661
01662
01663 if (*comp == '\'' || *comp == '\"')
01664 {
01665 rlength = StringLength(comp);
01666 if (!comp[rlength])
01667 return -1;
01668
01669 if (lastc) *lastc = comp + rlength +1;
01670 if (!eval) return 0;
01671 comp ++;
01672 rlength --;
01673 if (rlength == 0)
01674 isundef = 1;
01675 }
01676 else
01677 {
01678
01679
01680
01681
01682 while (comp[rlength] && !strchr("?:!&|) \r\t\n",comp[rlength]))
01683 {
01684 rlength++;
01685 }
01686 if (lastc) *lastc = comp + rlength;
01687
01688 if (!eval) return 0;
01689
01690 if (!strnicmp(comp,"undefined",rlength))
01691 isundef = 1;
01692 else if (!IsNumber(comp,rlength))
01693 {
01694 comp = freeme = EvaluateExpressionL(v,Var2,comp,rlength);
01695 if (comp) rlength = strlen(comp);
01696 else rlength = 0;
01697 }
01698 }
01699
01700 if (comp == NULL) comp = "";
01701
01702 if (ORsearch && length && Comparison[length-1]=='/') length --;
01703
01704
01705 if (Comparison[0] == '\'' || Comparison[0] == '\"')
01706 {
01707 char* field = strndup(Comparison + 1,length-1);
01708 result = ComparisonEvaluation(field,comp,rlength,op,isundef);
01709 CGIFREE(field);
01710 }
01711 else
01712 {
01713 char * x = EvaluateExpressionL(v,Var2,Comparison,length);
01714 result = ComparisonEvaluation(x,comp,rlength,op,isundef);
01715 CGIFREE(x);
01716 }
01717
01718 if (result) return bnot ^ 1;
01719 if (ORsearch)
01720 {
01721 CGINameValue* list = v;
01722 while (list)
01723 {
01724 size_t y=0;
01725 for (x=0; list[x].name; x++)
01726 {
01727 y=x;
01728
01729 if (strlen(list[x].name) < length)
01730 continue;
01731
01732 if (strnicmp(Comparison,list[x].name,length))
01733 continue;
01734
01735
01736 if (list[x].name[length] && list[x].name[length] != '_')
01737 continue;
01738
01739 result = ComparisonEvaluation(list[x].value,comp,rlength,op,isundef);
01740 if (result) return bnot ^ 1;
01741 }
01742 while (!list[y].last) y++;
01743 list = (CGINameValue*)list[y].value;
01744 }
01745 }
01746
01747 CGIFREE(freeme);
01748 return bnot;
01749 }
01750
01751 int EvaluateComparison(char* Comparison ,CGINameValue* v,CGINameValue* Var2,char** lastc)
01752 {
01753 return DoEvaluateComparison(Comparison ,v,Var2,lastc,1);
01754 }
01755
01756 int RenameField(CGINameValue*d, char* oldname, char* newname)
01757 {
01758 d = GetField(d,oldname);
01759 if (d == NULL) return 0;
01760 SetName(d,newname);
01761 return 1;
01762 }
01763
01774 void SetName(CGINameValue*d, char* name)
01775 {
01776 if (name == NULL)
01777 {
01778 if (d->name) d->name[0]=0;
01779 if (d->value) d->value[0]=0;
01780 }
01781 else
01782 {
01783 char *n = name;
01784 char *o = d->name;
01785 while (*n && *o) *o++ = *n++;
01786 if (*n == 0 && *o != 0) *o = 0;
01787 else if (*o == 0 && *n != 0)
01788 {
01789 CGIFREE(d->name);
01790 d->name = strdup(name);
01791 }
01792 }
01793 }
01794
01795 void SetValue(CGINameValue*d, char* value)
01796 {
01797 if (value == NULL)
01798 {
01799 if (d->value) d->value[0]=0;
01800 }
01801 else if (d->value == NULL)
01802 {
01803 goto set;
01804 }
01805 else
01806 {
01807 char *n = value;
01808 char *o = d->value;
01809 while (*n && *o) *o++ = *n++;
01810 if (*n == 0 && *o != 0) *o = 0;
01811 else if (*o == 0 && *n != 0)
01812 {
01813 CGIFREE(d->value);
01814 set:
01815 d->value = strdup(value);
01816 }
01817 }
01818 }
01819
01820 int SetFieldValue(CGINameValue *f,char * fieldname,char* value)
01821 {
01822 CGINameValue *d = GetField(f,fieldname);
01823 if (d == NULL)
01824 {
01825 d = GetField(f,"");
01826 if (d == NULL) return 0;
01827 SetName(d,fieldname);
01828 }
01829
01830 if (d == NULL) return 0;
01831
01832 SetValue(d,value);
01833 return 1;
01834 }
01835
01837 int GetFieldInt(CGINameValue *data,char * fieldname)
01838 {char * endptr;
01839 return strtol(GetFieldValue(data,fieldname),&endptr,10);
01840 }
01841
01842 double GetFieldFloat(CGINameValue*data,char * fieldname)
01843 {char * endptr;
01844 return strtod(GetFieldValue(data,fieldname),&endptr);
01845 }
01846
01850 CGINameValue* NewNVP(size_t count)
01851 {
01852 CGINameValue * v;
01853 size_t i;
01854 v = (CGINameValue*) CGIMALLOC((count + 1) * sizeof(CGINameValue));
01855 for (i = 0; i <= count; i++)
01856 {
01857 v[i].name = 0;
01858 v[i].value = 0;
01859 v[i].last = 0;
01860 }
01861 v[count].last = 1;
01862 return v;
01863 }
01864
01865 void DeleteNVP(CGINameValue* v)
01866 {
01867 int i,l;
01868 if (v == NULL) return;
01869 for (i=0; v[i].last == 0 ; i++)
01870 {
01871 if (v[i].name) CGIFREE(v[i].name);
01872 if (v[i].value) CGIFREE(v[i].value);
01873 l=i;
01874 }
01875 l++;
01876 if (v[l].last && v[l].value)
01877 {
01878 DeleteNVP((CGINameValue*)(void*)v[l].value);
01879 }
01880 CGIFREE(v);
01881 }
01882
01883 void ExtendNVP(CGINameValue * v, size_t count)
01884 {
01885 size_t i,l;
01886 if (v == NULL) return;
01887 for (i=0; v[i].last == 0 ; i++)
01888 {
01889 l=i;
01890 }
01891 l++;
01892 if (v[l].last)
01893 {
01894 if (v[l].value)
01895 ExtendNVP((CGINameValue*)(void*)v[l].value,count);
01896 else
01897 {
01898 CGINameValue* n = NewNVP(count);
01899 v[l].value = (char*)(void*)n;
01900 for (i=0; i<count; i++)
01901 {
01902 n[i].name = strdup(NULLSTR);
01903 }
01904 }
01905 }
01906 }
01907
01908 CGINameValue * GetField(CGINameValue * data, char * fieldname)
01909 {
01910 int x,i=0;
01911 if (data == NULL)
01912 return NULL;
01913
01914 for(x=0; data[x].last == 0; x++)
01915 {
01916 i = x;
01917 if (!data[x].name)
01918 continue;
01919
01920 if (!data[x].name[0] && !fieldname[0])
01921 return &data[x];
01922
01923 if (stricmp(fieldname,data[x].name)==0)
01924 return &data[x];
01925 }
01926
01927 i++;
01928
01929 if (data[i].last && data[i].value)
01930 return GetField((CGINameValue*)(void*)data[i].value,fieldname);
01931
01932 return NULL;
01933 }
01934
01935
01936 CGINameValue* CopyListJoin(CGINameValue* a,CGINameValue* b,size_t extra)
01937 {
01938 CGINameValue * v;
01939 size_t x=0;
01940 size_t y=0;
01941 if (b == NULL) return CopyList(a,extra);
01942
01943 while (a[x].name != NULL) x++;
01944
01945 while (b[y].name != NULL)
01946 {
01947 if (GetField(a,b[y].name)== NULL) x++;
01948 y++;
01949 }
01950
01951 v = NewNVP(x+extra);
01952
01953 for (x=0; x<extra; x++)
01954 {
01955 v[x].name = strdup("");
01956 }
01957 x=0;
01958 while (a[x].name != NULL)
01959 { v[x+extra].name = strdup(a[x].name);
01960 if (a[x].value)
01961 v[x+extra].value = strdup(a[x].value);
01962 x++;
01963 }
01964 y=0;
01965 while (b[y].name != NULL)
01966 {
01967 if (GetField(a,b[y].name)== NULL)
01968 {
01969 v[x+extra].name = strdup(b[y].name);
01970 if (b[y].value)
01971 v[x+extra].value = strdup(b[y].value);
01972 x++;
01973 }
01974 y++;
01975 }
01976 return v;
01977 }
01978
01979 CGINameValue* CopyListDeep(CGINameValue* header,size_t extra)
01980 {
01981 CGINameValue * v, *c=header;
01982
01983 size_t x=0;
01984 while (c)
01985 {
01986 size_t i=0;
01987 while (c[i].name != NULL) {if (c[i].name[0]) x++;i++; }
01988 if (!c[i].last) break;
01989 c = (CGINameValue*) c[i].value;
01990 }
01991
01992 v = NewNVP(x+extra);
01993 c = header;
01994 x=0;
01995 while (c)
01996 {
01997 size_t i=0;
01998 while (c[i].name)
01999 {
02000 if (!c[i].name[0]) {i++; continue;}
02001 v[x+extra].name = strdup(c[i].name);
02002 if (c[i].value)
02003 v[x+extra].value = strdup(c[i].value);
02004 i++;
02005 x++;
02006 }
02007 if (!c[i].last) break;
02008 c = (CGINameValue*) c[i].value;
02009 }
02010
02011 for (x=0;x<extra;x++)
02012 {
02013 v[x].name = strdup(NULLSTR);
02014 v[x].value = strdup(NULLSTR);
02015 }
02016 return v;
02017 }
02018
02019 size_t ListLength(CGINameValue*header)
02020 {
02021 size_t x = 0;
02022 if (header)
02023 while (header->name != NULL)
02024 {
02025 if (header->name[0])
02026 x++;
02027 header++;
02028 }
02029 return x;
02030 }
02031
02032 CGINameValue* CopyList(CGINameValue* header,size_t extra)
02033 {
02034 CGINameValue * v;
02035
02036 size_t x = ListLength(header);
02037 size_t y = 0;
02038 v = NewNVP(x+extra);
02039
02040 if (header)
02041 for (x=0;header[x].name != NULL;x++)
02042 {
02043 if (header[x].name[0])
02044 {
02045 v[y+extra].name = strdup(header[x].name);
02046 if (header[y].value)
02047 v[y+extra].value = strdup(header[x].value);
02048 y++;
02049 }
02050 }
02051
02052 for (x=0;x<extra;x++)
02053 {
02054 v[x].name = strdup(NULLSTR);
02055 v[x].value = strdup(NULLSTR);
02056 }
02057 return v;
02058 }
02059
02061 CGINameValue* CopyListN(CGINameValue* header,size_t extra,...)
02062 {
02063 va_list ap;
02064 CGINameValue * n;
02065 size_t x;
02066
02067 n = CopyList(header,extra);
02068 va_start(ap, extra);
02069
02070 for (x=0; extra > 0 && n[x].name != NULL; x++)
02071 {char *c;
02072 if (n[x].name[0]) continue;
02073
02074 c = va_arg(ap, char*);
02075 CGIFREE(n[x].name);
02076 n[x].name = strdup(c);
02077 extra--;
02078 }
02079
02080 va_end(ap);
02081 return n;
02082 }
02083
02084 #ifdef __WINCE__
02085 int FileSize(char * fname)
02086 {
02087 HANDLE h;
02088 int l;
02089 wchar_t fn[MAXPATH];
02090 fn[MultiByteToWideChar(CP_UTF8,0,fname,strlen(fname),fn,MAXPATH)] = 0;
02091 h = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
02092 if (h == INVALID_HANDLE_VALUE ) return 0;
02093 l = GetFileSize(h,NULL);
02094 CloseHandle(h);
02095 return l;
02096 }
02097 #else
02098 int FileSize(char * fname)
02099 {
02100 struct stat StatBuf;
02101 if (!fname) return 0;
02102 if (!*fname) return 0;
02103 if (stat(fname, & StatBuf) != 0) return 0;
02104 return StatBuf.st_size;
02105 }
02106 #endif
02107
02108 #if 0
02109
02110
02112 CGINameValue* ReadINIFileSection(char * file, char * section,int reserve)
02113 {
02114 CGINameValue* v;
02115 char * c, *d;
02116 int maxsize = FileSize(file);
02117 char * str;
02118 int i,length;
02119 if (maxsize <= 0) return NULL;
02120 str = CGIMALLOC(maxsize+1);
02121 if (!str) return NULL;
02122 str[maxsize]=0;
02123
02124 #ifdef UNICODE
02125 GetPrivateProfileSectionA(section,str,maxsize,file);
02126 #else
02127 GetPrivateProfileSection(section,str,maxsize,file);
02128 #endif
02129
02130 length = reserve;
02131 c = str;
02132 while (*c)
02133 {
02134 while (*c) c++;
02135 c++;
02136 length++;
02137 }
02138
02139 c = str;
02140 if (length == 0) {CGIFREE(str); return NULL;}
02141
02142 v = NewNVP(length);
02143
02144 for (i=0; i<reserve; i++)
02145 {
02146 v[i].name = strdup(NULLSTR);
02147 v[i].value = strdup(NULLSTR);
02148 }
02149
02150 if (length == reserve) {CGIFREE(str); return v;}
02151
02152 i = reserve;
02153 while (*c)
02154 {
02155 d = c;
02156 length=0;
02157 while (*c && *c != '=') {c++;length++;}
02158 c++;
02159 v[i].name=strndup(d,length);
02160
02161 d = c;
02162 length = 0;
02163 while (*c) {c++;length++;}
02164 c++;
02165 v[i].value=strndup(d,length);
02166 i++;
02167 }
02168 CGIFREE(str);
02169 return v;
02170 }
02171 #else
02172
02173 void killchar(char*c, char kill)
02174 {
02175 int i=0,j=0;
02176 while (c[j])
02177 {
02178 if (c[j] != kill)
02179 c[i++] = c[j++];
02180 else
02181 j++;
02182 }
02183 c[i]=0;
02184 }
02185
02186 CGINameValue* ReadINIFileSection(char * filename, char * section,int reserve)
02187 {
02188 CGINameValue* ret = NULL;
02189 int d;
02190 int maxsize = FileSize(filename);
02191 char * str;
02192 FILE * file= NULL;
02193 if (maxsize <= 0) return NULL;
02194 str = CGIMALLOC(maxsize+1);
02195 if (str == NULL) return NULL;
02196 str[maxsize]=0;
02197
02198 file = CGIFOPEN(filename,"rt");
02199 if (file != NULL)
02200 while (1)
02201 {
02202 d = ReadUntilChar(file,0,0,"[",'\r');
02203 if (d < 0) break;
02204 d = ReadUntilChar(file,str,maxsize,"]\n",'\r');
02205 if (d == ']')
02206 {
02207 if (stricmp(str,section)==0)
02208 {
02209 ReadUntilWord(file,str,maxsize,"\n[");
02210 killchar(str,'\r');
02211 ret = ReadPairedString(str,'\n',reserve);
02212 break;
02213 }
02214 }
02215 }
02216 CGIFCLOSE(file);
02217 CGIFREE(str);
02218 return ret;
02219 }
02220 #endif
02221
02222 CGINameValue* ReadPairedValues(int argc, char ** argv,int reserve)
02223 {
02224 CGINameValue* v;
02225 char * c;
02226 int i,length,max;
02227 max = argc + reserve;
02228 if (max <= 0) return NULL;
02229
02230 v = NewNVP(max);
02231
02232 for (i=0; i<reserve; i++)
02233 {
02234 v[i].name = strdup(NULLSTR);
02235 v[i].value = strdup(NULLSTR);
02236 }
02237
02238 for (i = 0 ; i < argc ; i++ )
02239 {
02240 c = argv[i];
02241 length=0;
02242 while (*c && *c != '=') {c++;length++;}
02243 if (*c) c++;
02244 v[i+reserve].name=strndup(argv[i],length);
02245 v[i+reserve].value=strdup(c);
02246 }
02247 return v;
02248 }
02249
02251 CGINameValue* ReadPairedString(char * str,char delim,int reserve)
02252 {
02253 CGINameValue *v;
02254 char *c;
02255 int i,j,count,done;
02256 if (!str) return NULL;
02257 count = reserve;
02258 if (str[0]) count++;
02259
02260 for (i=1; str[i]; i++)
02261 {
02262 if (str[i] == delim) count++;
02263 }
02264
02265 if (count == 0 && reserve == 0)
02266 {
02267 if (str[0])
02268 count = 1;
02269 else
02270 return NULL;
02271 }
02272
02273 v = NewNVP(count);
02274
02275 c = str;
02276 done =0;
02277 for (i=0; i<reserve; i++)
02278 {
02279 v[i].name = strdup(NULLSTR);
02280 v[i].value = strdup(NULLSTR);
02281 }
02282
02283 if (count == reserve) return v;
02284
02285 i = reserve;
02286 while(!done && *c)
02287 {
02288 int x=1;
02289
02290 while (*c == delim) c++;
02291 if (isalnum(*c) || *c == '_')
02292 {
02293 for (j=1; c[j] != '=' && c[j] != delim && c[j]; j++){x++;}
02294 v[i].name = strndup(c, x);
02295 if (c[x] == '=')
02296 {
02297 c = c + x + 1;
02298 x=0;
02299 for (j=0; c[j] != delim && c[j]; j++) {x++;}
02300 v[i].value = strndup(c, x);
02301 }
02302 else
02303 {
02304 v[i].value = strdup("");
02305 }
02306 if (*c)
02307 c = c + x + 1;
02308 i++;
02309 }
02310 else if (*c == '=')
02311 while (*c && *c != delim) c++;
02312 else c++;
02313 if (i >= count) done = 1;
02314 }
02315
02316 return v;
02317 }
02318