00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "cgi.h"
00015
00017 int ODBCRunScript(char* argv0,STREAM result,char* dbname,
00018 CGINameValue* config,
00019 CGINameValue* Params,
00020 char* search);
00021
00083 #ifdef VPWSCGI
00084 extern char hostRoot[MAXPATH];
00085 #endif
00086
00087 char * itos (unsigned int value, char *p)
00088 {
00089 int i,j;
00090 char c;
00091
00092 j=0;
00093 for (i=0;value && i<34;i++)
00094 {
00095 c = (char)(value % 32);
00096 p[j++]= (c < 10) ? c + '0' : c + 'a' - 10;
00097 value = value / 32;
00098 }
00099 p[j]=0;
00100 return p+j;
00101 }
00102
00103
00112 void GenerateSessionID(char* session,unsigned int i)
00113 {
00114 #ifdef XP_WIN
00115 SYSTEMTIME tb;
00116 unsigned int a,b,c;
00117 GetSystemTime(&tb);
00118
00119 a = (tb.wMonth - 1); a = a << 4;
00120 a |= (tb.wDay - 1); a = a << 5;
00121 a |= (tb.wHour); a = a << 5;
00122 a |= (tb.wMinute); a = a << 6;
00123 a |= (tb.wSecond);
00124
00125 b = (i & 0xAA55AA55)|(a&0x55AA55AA);
00126 c = (i & 0x55AA55AA)|(a&0xAA55AA55);
00127 *session = 'X';
00128 session = itos(tb.wYear-2000,session+1);
00129 session = itos(b,session);
00130 *session = 'Y';
00131 session++;
00132 session = itos(c,session);
00133 #else
00134 time_t timer;
00135 struct tm *tb;
00136 unsigned int a,b,c;
00137
00138 time(&timer);
00139 tb = gmtime(&timer);
00140
00141 a = (tb->tm_mon); a = a << 4;
00142 a |= (tb->tm_mday - 1); a = a << 5;
00143 a |= (tb->tm_hour); a = a << 5;
00144 a |= (tb->tm_min); a = a << 6;
00145 a |= (tb->tm_sec);
00146
00147 b = ((i) & 0xAA55AA55)|(a&0x55AA55AA);
00148 c = ((i) & 0x55AA55AA)|(a&0xAA55AA55);
00149 *session = 'x';
00150 session = itos(tb->tm_year-100,session+1);
00151 session = itos(b,session);
00152 *session = 'Z';
00153 session++;
00154 session = itos(c,session);
00155 #endif
00156 }
00157
00158 void GenerateUniqueID(char* newsession,char* hash)
00159 {
00160 unsigned int j, i = 0;
00161 #ifdef XP_WIN
00162 HKEY key;
00163 #ifdef UNICODE
00164 HANDLE Mutex = CreateMutex(0,FALSE,L"EZS.CGI.RANDOM");
00165 #else
00166 HANDLE Mutex = CreateMutex(0,FALSE,"EZS.CGI.RANDOM");
00167 #endif
00168 WaitForSingleObject(Mutex,20000);
00169 #ifdef UNICODE
00170 if (RegOpenKeyEx(HKEY_CURRENT_USER,L"SOFTWARE\\Raosoft\\EZSurvey",0,0,&key) == ERROR_SUCCESS)
00171 {
00172 DWORD type,length = sizeof(i);
00173 RegQueryValueEx(key,L"RANDOM",0,&type,(unsigned char*)&i,&length);
00174 RegCloseKey(key);
00175 }
00176 #else
00177 if (RegOpenKeyEx(HKEY_CURRENT_USER,"SOFTWARE\\Raosoft\\EZSurvey",0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS)
00178 {
00179 DWORD type,length = sizeof(i);
00180 RegQueryValueEx(key,"RANDOM",0,&type,(unsigned char*)&i,&length);
00181 RegCloseKey(key);
00182 }
00183 #endif
00184 #else
00185 FILE* f = CGIFOPEN("random.seed","rb");
00186 if (f) { fread(&i,sizeof(i),1,f); CGIFCLOSE(f);}
00187 #endif
00188
00189 j = i >> 16;
00190 if (hash) while (*hash) j += *hash++;
00191 #ifdef XP_WIN
00192 j += GetTickCount();
00193 #else
00194 #endif
00195 #ifndef __WINCE__
00196 i += getpid();
00197 #endif
00198 i = (j << 16) | (i & 0x0000ffff);
00199 GenerateSessionID(newsession,i);
00200
00201 #ifdef XP_WIN
00202 #ifdef UNICODE
00203 if (RegOpenKeyEx(HKEY_CURRENT_USER,L"SOFTWARE\\Raosoft\\EZSurvey",0,0,&key) == ERROR_SUCCESS)
00204 {
00205 RegSetValueEx(key,L"RANDOM",0,REG_DWORD,(unsigned char*)&i,sizeof(i));
00206 RegCloseKey(key);
00207 }
00208 #else
00209 if (RegOpenKeyEx(HKEY_CURRENT_USER,"SOFTWARE\\Raosoft\\EZSurvey",0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS)
00210 {
00211 RegSetValueEx(key,"RANDOM",0,REG_DWORD,(unsigned char*)&i,sizeof(i));
00212 RegCloseKey(key);
00213 }
00214 #endif
00215 ReleaseMutex(Mutex);
00216 CloseHandle(Mutex);
00217 #else
00218 f = CGIFOPEN("random.seed","wb");
00219 if (f) { fwrite(&i,sizeof(i),1,f); CGIFCLOSE(f);}
00220 #endif
00221 }
00222
00223 int CheckFileName(char* Name, char* AllowedEndings)
00224 {
00225 char * c = strrchr(Name,'.');
00226 if (!c) return 0;
00227 return HasToken(AllowedEndings,c+1,0);
00228 }
00229
00230 int DeleteOldRecords(DATABASE * database,
00231 CGINameValue* header,
00232 CGINameValue* Params)
00233 {
00234 CGINameValue Userid[2];
00235 int previous = 0;
00236
00237 Userid[0].name="_SESSION"; Userid[0].value=GetFieldValue(Params,"_SESSION");
00238 Userid[1].name=0;
00239
00240 if (Userid[0].value[0] == 0) return 0;
00241
00242 while(1)
00243 {
00244 int current;
00245 if (DatabaseFindFast(database, header,Userid,¤t)==0) break;
00246 if (previous)
00247 {
00248 int ptr = ftell(database);
00249 if (fseek(database,previous,SEEK_SET) == 0)
00250 {
00251 fwrite("#",1,1,database);
00252 if (fseek(database,ptr,SEEK_SET) != 0) return 1;
00253 }
00254 if (ptr == -1) break;
00255 }
00256 previous = current;
00257 }
00258
00259 return 0;
00260 }
00261
00266 int FindUserRecordASC(char* idfields,
00267 DATABASE * database,
00268 CGINameValue* header,
00269 CGINameValue* Params)
00270 {
00271 CGINameValue * Userid;
00272 CGINameValue * Current = NULL;
00273 int i;
00274 int ret = 0;
00275
00276 Userid = ReadPairedString(idfields,',',0);
00277
00278 for (i=0; Userid[i].name; i++)
00279 {
00280 Userid[i].value = strdup(GetFieldValue(Params,Userid[i].name));
00281 if (Userid[i].value[0]) ret = 1;
00282 }
00283
00284 if (ret)
00285 {
00286 ret = 0;
00287 while(1)
00288 {
00289 if (DatabaseFindFast(database, header,Userid,NULL)==0)
00290 break;
00291
00292 ret = 1;
00293 DeleteNVP(Current);
00294 Current = CopyList(header,0);
00295 }
00296
00297 if (Current != NULL)
00298 {
00299 CGINameValue* x;
00300 char*c;
00301
00302 for(i=0; header[i].name; i++)
00303 {
00304 if (!header[i].name[0]) continue;
00305 x = GetField(Current,header[i].name);
00306 if (!x) continue;
00307
00308 c = x->value;
00309 x->value = header[i].value;
00310 header[i].value = c;
00311 }
00312 }
00313 }
00314
00315 DeleteNVP(Current);
00316 DeleteNVP(Userid);
00317 return ret;
00318 }
00319
00320 CGINameValue* LoadUserDataASC(CGINameValue* config,char* argv0,char*dbname,CGINameValue*Params,int* err)
00321 {
00322 FILE * db;
00323 CGINameValue * header;
00324 char dbfile[MAXPATH];
00325 int ret = 0;
00326 char *c = GetSetting(config,"SAVEDATANAME",NULLSTR);
00327 char *index = GetSetting(config,"SAVEINDEXNAME",NULLSTR);
00328 char *idfields = GetSetting(config,"IDFIELDS","IFMUID,IFMUID1,IFMUID2,IFMUID3,IFMUID4");
00329
00330 if (!*idfields) idfields = "_SESSION";
00331
00332 if (*c)
00333 {
00334 if (strlen(c) > 1000) c[1000]=0;
00335 ExpandLocalPath(argv0,dbfile,c,NULLSTR);
00336 }
00337 else
00338 {
00339 ExpandLocalPath(argv0,dbfile,dbname,".asc");
00340 }
00341
00342 if (!DatabaseOpen(dbfile,&db,&header,0,0))
00343 {
00344 if (err) *err = 2;
00345 return NULL;
00346 }
00347
00348 if (*index)
00349 {
00350 FILE * indexdb;
00351 CGINameValue * indexheader;
00352 char indexfile[MAXPATH];
00353 int pos;
00354 if (strlen(index) > 1000) index[1000]=0;
00355 ExpandLocalPath(argv0,indexfile,index,NULLSTR);
00356 if (DatabaseOpen(indexfile,&indexdb,&indexheader,0,0))
00357 {
00358 if (FindUserRecordASC(idfields,indexdb,indexheader,Params))
00359 {
00360 pos = atoi(GetFieldValue(indexheader,"_POS"));
00361 if (pos > 0)
00362 if (fseek(db,pos,0) == 0)
00363 ret = DatabaseReadRecord(db,header,0);
00364
00365
00366 if (ret)
00367 {
00368 int i;
00369 CGINameValue* c ;
00370 for (i=0; ret && indexheader[i].name; i++)
00371 {
00372 if (!stricmp(indexheader[i].name,"_POS")) continue;
00373 c = GetField(header,indexheader[i].name);
00374 if (c)
00375 if (strcmp(indexheader[i].value,c->value))
00376 ret = 0;
00377 }
00378 }
00379 }
00380 DatabaseClose(indexdb,indexheader);
00381 }
00382 }
00383
00384 if (!ret)
00385 ret = FindUserRecordASC(idfields,db,header,Params);
00386
00387 if (ret)
00388 {
00389 DatabaseClose(db,NULL);
00390 return header;
00391 }
00392 else
00393 {
00394 DatabaseClose(db,header);
00395 return 0;
00396 }
00397 }
00398 #ifdef CGI_ODBC
00399 CGINameValue* LoadUserDataSQL(CGINameValue* config,char* argv0,char*dbname,CGINameValue*Params,int* err)
00400 {
00401 SQLDB* db = 0;
00402 CGINameValue* x = 0;
00403 EZSSTREAM result;
00404 char *c;
00405 int ret;
00406
00407
00408 db = ODBCConnect( GetSetting(config,"ODBCSERVICE",""),
00409 GetSetting(config,"ODBCNAME",""),
00410 GetSetting(config,"ODBCPASSWORD",""),0);
00411 if (!db)
00412 {
00413 LogError("\nODBCOpen() failed");
00414 if (err) *err = 52;
00415 return 0;
00416 }
00417
00418
00419 memset(&result,0,sizeof(result));
00420 result.t = NewBuffer(1024);
00421
00422 ret = ODBCRunScript(argv0,&result,dbname,config,Params,"<SCRIPT NAME=\"LOADODBC\"");
00423 c = CopyBuffer(result.t);
00424 DeleteBuffer(result.t);
00425 if (ret && *c)
00426 {
00427 char s[128];
00428 sprintf(s,"\nODBCRunScript error %d for LOADODBC ",ret);
00429 LogError(s);
00430 }
00431
00432 if (!ret)
00433 {
00434 x = ODBCQuery(db,c,0);
00435
00436 if (x)
00437 {
00438 EZSSTREAM result;
00439 CGINameValue* y;
00440 memset(&result,0,sizeof(result));
00441 result.t = NewBuffer(1024);
00442 ret = ODBCRunScript(argv0,&result,dbname,config,x,"<SCRIPT NAME=\"READODBC\"");
00443 CGIFREE(c);
00444 c = CopyBuffer(result.t);
00445 DeleteBuffer(result.t);
00446 if (ret && *c)
00447 {
00448 char s[128];
00449 sprintf(s,"\nODBCRunScript error %d for READODBC ",ret);
00450 LogError(s);
00451 }
00452 y = CopyListDeep(x,0);
00453 DeleteNVP(x);
00454 x=y;
00455 }
00456 }
00457
00458 if (ret && *c)
00459 {
00460 LogError(c);
00461 }
00462
00463 CGIFREE(c);
00464 ODBCDisconnect(db);
00465 return x;
00466 }
00467 #endif
00468
00469 CGINameValue* LoadUserData(CGINameValue* config,char* argv0,char*dbname,CGINameValue*Params,int* err)
00470 {
00471 char* order = GetSetting(config,"LOGINSEQUENCE","ASC");
00472 CGINameValue* x = 0;
00473 while (*order && !x)
00474 {
00475 if (strchr(" ;,",*order)) order++;
00476 else if (!strnicmp(order,"ASC",3))
00477 {
00478 x = LoadUserDataASC(config,argv0,dbname,Params,err);
00479 order += 3;
00480 }
00481 #ifdef CGI_ODBC
00482 else if (!strnicmp(order,"ODBC",4))
00483 {
00484 x = LoadUserDataSQL(config,argv0,dbname,Params,err);
00485 order += 4;
00486 }
00487 #endif
00488 }
00489 return x;
00490 }
00491
00492
00493 static char* JSShowPage(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00494 {
00495 char* pageskip;
00496 if (argc < 1) return 0;
00497 pageskip = GetFieldValue(Params,"_PAGESKIP");
00498 if (*pageskip)
00499 {
00500 if (!HasToken(pageskip,argv[0],0))
00501 {
00502 char*x = strdup3(pageskip,",",argv[0]);
00503 SetFieldValue(Params,"_PAGESKIP",x);
00504 CGIFREE(x);
00505 }
00506 }
00507 else
00508 {
00509 SetFieldValue(Params,"_PAGESKIP",argv[0]);
00510 }
00511 return 0;
00512 }
00513
00514 static char* JSUniqueId(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00515 {
00516 char datetime[32];
00517 GenerateUniqueID(datetime,argc?argv[0]:0);
00518 return strdup(datetime);
00519 }
00520
00521 static char* JSTimeDate(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00522 {
00523 char datetime[16];
00524 GetTime(datetime,0,0);
00525 return strdup(datetime);
00526 }
00527 static char* JSTimeTime(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00528 {
00529 char datetime[16];
00530 GetTime(0,datetime,0);
00531 return strdup(datetime);
00532 }
00534 static char* JSSendMail(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00535 {
00536 if (!Env->config) return 0;
00537 if (argc < 3) return 0;
00538 {
00539 char* server = GetSetting(Env->config,"EMAILSERVER","");
00540 char* profile = GetSetting(Env->config,"EMAILPROFILE","Windows Messaging Settings");
00541 char* name = GetSetting(Env->config,"EMAILNAME","");
00542 char* password = GetSetting(Env->config,"EMAILPWD","");
00543
00544 SendMail(argv[0],argv[1],argv[2], server, profile, name, password);
00545 }
00546 return 0;
00547 }
00548
00549 static int SortFunction(const void *a0, const void *b0)
00550 {
00551 CGINameValue* a = (CGINameValue*)a0;
00552 CGINameValue* b = (CGINameValue*)b0;
00553 int x=0,y=0;
00554 if (a->value) x = atoi(a->value);
00555 if (b->value) y = atoi(b->value);
00556 return x - y;
00557 };
00558
00559 void SortNVP(CGINameValue* list)
00560 {
00561 size_t x= 0;
00562 while (list[x].name != NULL) x++;
00563 qsort(list,x,sizeof(CGINameValue),*SortFunction);
00564 }
00565
00570 static char* JSRankSort(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00571 {
00572 CGINameValue* list;
00573 int i;
00574 int length;
00575 char* ret;
00576 if (argc == 0) return NULL;
00577 if (argc == 1)
00578 list = ReadPairedString(argv[0],',',0);
00579 else
00580 list = ReadPairedValues(argc,argv,0);
00581
00582 SortNVP(list);
00583 length = 0;
00584 for (i=0; list[i].name; i++)
00585 {
00586 length += strlen(list[i].name);
00587 length ++;
00588 }
00589 if (!length) return NULL;
00590 ret = CGIMALLOC(1+length);
00591 length = 0;
00592 for (i=0; list[i].name; i++)
00593 {
00594 if (!list[i].value) continue;
00595 if (!list[i].value[0]) continue;
00596 strcpy(ret+length,list[i].name);
00597 length += strlen(list[i].name);
00598 strcpy(ret+length,",");
00599 length ++;
00600 }
00601 if (length) ret[length-1] = 0;
00602 else ret[0]=0;
00603 return ret;
00604 }
00605
00609 static char* JSRankIndex(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00610 {
00611 if (argc > 1 )
00612 {
00613 char temp[64];
00614 int i=0;
00615 if (HasToken(argv[0], argv[1],&i))
00616 {
00617 sprintf(temp,"%d",i);
00618 return strdup(temp);
00619 }
00620 }
00621 return NULL;
00622 }
00623
00627 #ifdef CGI_ODBC
00628 static char* JSSQLEscape(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00629 {
00630 size_t i=0,j=0;
00631 char *in;
00632 char *out;
00633 char *extra = NULL;;
00634 if (argc == 0) return NULL;
00635
00636 in = argv[0];
00637 out = CGIMALLOC(1 + (strlen(in) * 2));
00638 if (argc > 1) extra = argv[1];
00639
00640 while (in[i])
00641 {
00642 if (in[i] == '\'')
00643 {
00644 out[j++] = '\'';
00645 out[j++] = '\'';
00646 }
00647 else if (strchr("\t\r\n",in[i]))
00648 {
00649 out[j++] = ' ';
00650 }
00651 else if (extra && strchr(extra,in[i]))
00652 {
00653 out[j++] = '\\';
00654 out[j++] = in[i];
00655 }
00656 else out[j++] = in[i];
00657
00658 i++;
00659 }
00660
00661 out[j]=0;
00662 return out;
00663 }
00664 #endif
00665
00666 #ifdef CGI_SOAP
00667 #endif
00668
00691 int ValidatePage(char* argv0,STREAM htmlout,char* dbname,
00692 CGINameValue* Config,
00693 CGINameValue* Params,
00694 char* page)
00695 {
00696 char *check;
00697 int ret;
00698 FILE* script;
00699 ScriptFunction Functions[] =
00700 {
00701 {"print",10,(ScriptFunctionCall)*JSPrint},
00702 {"write",10,(ScriptFunctionCall)*JSPrint},
00703 {"eval",1,(ScriptFunctionCall)*JSEval},
00704 {"timestamp",0,(ScriptFunctionCall)*JSTimeStamp},
00705 {"timedate",0,(ScriptFunctionCall)*JSTimeDate},
00706 {"timetime",0,(ScriptFunctionCall)*JSTimeTime},
00707 {"uniqueid",1,(ScriptFunctionCall)*JSUniqueId},
00708 {"tofixed",2,(ScriptFunctionCall)*JStoFixed},
00709 {"sendmail",3,(ScriptFunctionCall)*JSSendMail},
00710 {"showpage",1,(ScriptFunctionCall)*JSShowPage},
00711 {"ranksort",128,(ScriptFunctionCall)*JSRankSort},
00712 {"rankindex",2,(ScriptFunctionCall)*JSRankIndex},
00713 {"runReport",8,(ScriptFunctionCall)*JSReport},
00714 {"number",1,(ScriptFunctionCall)*JSToNumber},
00715 {"environment",1,(ScriptFunctionCall)*JSGetEnv},
00716 {"toNumber",1,(ScriptFunctionCall)*JSToNumber},
00717 {"random",1,(ScriptFunctionCall)*JSRandom},
00718 {"subStr",3,(ScriptFunctionCall)*JSsubstr},
00719 {"indexOf",4,(ScriptFunctionCall)*JSIndexOf},
00720 {"length",1,(ScriptFunctionCall)*JSstrlen},
00721 {0,0,0}};
00722
00723 ScriptEnvironment Global;
00724 memset(&Global,0,sizeof(Global));
00725 Global.htmlout = htmlout;
00726 Global.Functions = Functions;
00727 Global.argv0 = argv0;
00728 Global.config = Config;
00729 if (!page || !*page) return 0;
00730
00731 script = FileOpen(argv0,dbname,".val");
00732 if (script == NULL) return 1;
00733
00734 check = strdup3("<PAGE NAME=\"",page,"\"");
00735
00736 if (!ReadUntilWordS(script,0,check)) {CGIFCLOSE(script);script=NULL;CGIFREE(check); return 0; }
00737
00738 CGIFREE(check);
00739
00740 if (!ReadUntilWordS(script,0,"<SCRIPT")) {CGIFCLOSE(script);script=NULL; return 0; }
00741 if (!ReadUntilWordS(script,0,">")) {CGIFCLOSE(script);script=NULL; return 0; }
00742 if (!GetField(Params,"_PAGEWARN"))
00743 RenameField(Params,"","_PAGEWARN");
00744 if (!GetField(Params,"_PAGENEXT"))
00745 RenameField(Params,"","_PAGENEXT");
00746 if (!GetField(Params,"_PAGESKIP"))
00747 RenameField(Params,"","_PAGESKIP");
00748
00749 ret = RunScript(&Global,script,Params);
00750 if (ret > 0)
00751 {
00752 PrintScriptError(htmlout,&Global, script, ret);
00753 }
00754 CGIFCLOSE(script);
00755 return 0;
00756 }
00757
00758
00759 int ValidateBack(char* argv0,STREAM htmlout,char* dbname,
00760 CGINameValue* Config,
00761 CGINameValue* Params,
00762 char* page)
00763 {
00764 char *check;
00765 int ret;
00766 FILE* script;
00767 ScriptFunction Functions[] =
00768 {
00769 {"print",10,(ScriptFunctionCall)*JSPrint},
00770 {"write",10,(ScriptFunctionCall)*JSPrint},
00771 {"eval",1,(ScriptFunctionCall)*JSEval},
00772 {"timestamp",0,(ScriptFunctionCall)*JSTimeStamp},
00773 {"timedate",0,(ScriptFunctionCall)*JSTimeDate},
00774 {"timetime",0,(ScriptFunctionCall)*JSTimeTime},
00775 {"uniqueid",1,(ScriptFunctionCall)*JSUniqueId},
00776 {"toFixed",2,(ScriptFunctionCall)*JStoFixed},
00777 {"sendMail",3,(ScriptFunctionCall)*JSSendMail},
00778 {"showpage",1,(ScriptFunctionCall)*JSShowPage},
00779 {"runReport",8,(ScriptFunctionCall)*JSReport},
00780 {"number",1,(ScriptFunctionCall)*JSToNumber},
00781 {"environment",1,(ScriptFunctionCall)*JSGetEnv},
00782 {"toNumber",1,(ScriptFunctionCall)*JSToNumber},
00783 {"random",1,(ScriptFunctionCall)*JSRandom},
00784 {"subStr",3,(ScriptFunctionCall)*JSsubstr},
00785 {"indexOf",4,(ScriptFunctionCall)*JSIndexOf},
00786 {"length",1,(ScriptFunctionCall)*JSstrlen},
00787 {0,0,0}};
00788
00789 ScriptEnvironment Global;
00790 memset(&Global,0,sizeof(Global));
00791 Global.htmlout = htmlout;
00792 Global.Functions = Functions;
00793 Global.argv0 = argv0;
00794 Global.config = Config;
00795
00796 if (!page || !*page) return 0;
00797
00798 script = FileOpen(argv0,dbname,".val");
00799 if (script == NULL) return 1;
00800
00801 check = strdup3("<PAGE NAME=\"",page,"\"");
00802
00803 if (!ReadUntilWordS(script,0,check)) {CGIFCLOSE(script);script=NULL;CGIFREE(check); return 0; }
00804
00805 CGIFREE(check);
00806
00807 if (!ReadUntilWordS(script,0,"<SCRIPT TYPE=BACK>")) {CGIFCLOSE(script);script=NULL; return 0; }
00808
00809 if (!GetField(Params,"_PAGEWARN"))
00810 RenameField(Params,"","_PAGEWARN");
00811 if (!GetField(Params,"_PAGENEXT"))
00812 RenameField(Params,"","_PAGENEXT");
00813 if (!GetField(Params,"_PAGESKIP"))
00814 RenameField(Params,"","_PAGESKIP");
00815
00816 ret = RunScript(&Global,script,Params);
00817 if (ret > 0)
00818 {
00819 PrintScriptError(htmlout,&Global, script, ret);
00820 }
00821 CGIFCLOSE(script);
00822 return 0;
00823 }
00824
00825 int ShowForm(char* argv0,STREAM htmlout,char* formname,CGINameValue*Params)
00826 {
00827 FILE * f = NULL;
00828 if (!formname) return 2;
00829 if (!*formname) return 2;
00830
00831 if (CheckFileName(formname,"html,htm"))
00832 f = FileOpen(argv0,formname,"");
00833
00834 if (!f)
00835 f = FileOpen(argv0,formname,".html");
00836
00837 if (!f) return 2;
00838
00839 RunReport(argv0,htmlout,f,Params,NULL,NULL,1,NULL);
00840
00841 fclose(f);
00842 return 0;
00843 }
00844
00845 int ShowFormPage(char* argv0, STREAM htmlout, char* dbname, CGINameValue*Params,
00846 char* history, char* curpage)
00847 {
00848 char dbdir[MAXPATH];
00849 char filename[MAXPATH];
00850 char temp[1024];
00851 int i, p;
00852 FILE * config;
00853 FILE * script;
00854
00855 CGINameValue * Options = NULL;
00856 CGINameValue * unused = CopyList(Params,0);
00857
00858
00859
00860 if (curpage[0] == 'P') curpage[0] = 'p';
00861
00862
00863 i = strcspn(curpage,"/.\\*?$|'\"<>~");
00864 if (curpage[i] != 0) return 104;
00865
00866
00867
00868
00869
00870 if (history && *history)
00871 {
00872 char * x = history;
00873 char * y = history;
00874 while (*x)
00875 {
00876 if (!strncmp(x,"page",4))
00877 x += 4;
00878 else
00879 *y++ = *x++;
00880 }
00881 *y = 0;
00882 }
00883
00884 ExpandLocalPath(argv0,dbdir,dbname,SLASH);
00885
00886
00887 strcpy(filename,dbdir);
00888 strcat(filename,curpage);
00889 config = CGIFOPEN(filename,"rb");
00890
00891 if (!config && !strstr(curpage,"page"))
00892 {
00893 strcpy(filename,dbdir);
00894 strcat(filename,"page");
00895 strcat(filename,curpage);
00896 config = CGIFOPEN(filename,"rb");
00897 }
00898
00899
00900
00901 if (!config)
00902 {
00903 HTMLWrite(htmlout,"<P>Error: page data missing for page");
00904 HTMLEscape(htmlout,curpage);
00905 HTMLWrite(htmlout," ");
00906 HTMLEscape(htmlout,filename);
00907 LogError("\nCould not open page data file ");
00908 LogError(filename);
00909 return 2;
00910 }
00911
00912 script = FileOpen(argv0,dbname,".val");
00913 if (script != NULL)
00914 {
00915
00916
00917
00918 char* check ;
00919 if (!strnicmp(curpage,"page",4)) curpage += 4;
00920 check = strdup3("<PAGE NAME=\"page",curpage,"\"");
00921 if (ReadUntilWordS(script,0,check))
00922 Options = ReadHTMLAttributes(script,32);
00923 CGIFCLOSE(script);
00924 CGIFREE(check);
00925 }
00926
00927 temp[0]=0;
00928 if (!Options || !GetField(Options,"ACTION"))
00929 {
00930
00931 strcpy(filename,dbdir);
00932 strcat(filename,"header");
00933
00934 HTMLWriteFile(htmlout,filename);
00935
00936
00937 ReadUntilChar(config,temp,sizeof(temp),"\n",'\r');
00938 Options = ReadPairedString(temp,'&',0);
00939
00940 ReadUntilChar(config,0,0,"\n",'\r');
00941
00942
00943 ReadUntilChar(config,temp,sizeof(temp),"\n",'\r');
00944 }
00945
00946
00947 RunReport(argv0,htmlout,config,Params,0,unused,1,"FORM");
00948
00949
00950
00951
00952
00953
00954
00955 HTMLWrite(htmlout,
00956 "<FORM NAME=F onSubmit=\"return ezsOnSubmit(this);\" ACCEPT-CHARSET=\"UTF-8\"");
00957
00958 #ifdef __WINCE__
00959 HTMLWrite(htmlout," ACTION=/ezs METHOD=POST");
00960 #else
00961 if (GetField(Options,"ACTION"))
00962 {
00963 HTMLWrite(htmlout," ACTION=\"");
00964 HTMLWrite(htmlout,GetFieldValue(Options,"ACTION"));
00965 HTMLWrite(htmlout,"\"");
00966 }
00967
00968 if (GetField(Options,"AUTOCOMPLETE"))
00969 {
00970 HTMLWrite(htmlout," AUTOCOMPLETE=\"");
00971 HTMLWrite(htmlout,GetFieldValue(Options,"AUTOCOMPLETE"));
00972 HTMLWrite(htmlout,"\"");
00973 }
00974
00975 if (GetField(Options,"METHOD"))
00976 {
00977 HTMLWrite(htmlout," METHOD=\"");
00978 HTMLWrite(htmlout,GetFieldValue(Options,"METHOD"));
00979 HTMLWrite(htmlout,"\"");
00980 }
00981 else HTMLWrite(htmlout," METHOD=POST");
00982 #endif
00983
00984 HTMLWrite(htmlout,">\n");
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999 #if 0
01000 if (*pagenext)
01001 {
01002 if (HasToken(pagenext,next,0))
01003 {
01004 }
01005 else
01006 {
01007
01008
01009
01010 char * x = strdup3(pagenext," ",next);
01011 SetFieldValue(Params,"_PAGENEXT",x);
01012 CGIFREE(x);
01013 }
01014 }
01015 else
01016 {
01017 RenameField(Params,"_PAGENEXT",0);
01018 }
01019 #endif
01020
01021 HTMLWrite(htmlout,"<INPUT TYPE=HIDDEN NAME=DATABASE VALUE=\"");
01022 HTMLWrite(htmlout,dbname);
01023 HTMLWrite(htmlout,"\">\n");
01024
01025 HTMLWrite(htmlout,"<INPUT TYPE=HIDDEN NAME=_PAGEBACK VALUE=\"");
01026 HTMLWrite(htmlout,history);
01027 HTMLWrite(htmlout,"\">\n");
01028
01029 RenameField(Params,"_PAGEBACK",0);
01030 RenameField(Params,"_PAGE",0);
01031 RenameField(Params,"_PAGESKIP",0);
01032
01033
01034
01035
01036
01037
01038 if(*temp)
01039 {
01040 strcpy(filename,dbdir);
01041 strcat(filename,temp);
01042 HTMLWriteFile(htmlout,filename);
01043 }
01044
01045 p = ftell(config);
01046 RunReport(argv0,0,config,Params,NULL,unused,1,"/FORM");
01047
01048
01049 for (i = 0; unused[i].name; i++)
01050 {
01051 if (!unused[i].name[0]) continue;
01052
01053
01054
01055 if (!HasTokenI("HOST,DATE,TIME",unused[i].name,0) &&
01056 strncmp("_PAGE",unused[i].name,5) )
01057 {
01058 HTMLWrite(htmlout,"<INPUT TYPE=HIDDEN NAME=\"");
01059 HTMLEscape(htmlout,unused[i].name);
01060 HTMLWrite(htmlout,"\" VALUE=\"");
01061 HTMLEscape(htmlout,unused[i].value);
01062 HTMLWrite(htmlout,"\">\n");
01063 }
01064 }
01065
01066
01067 fseek(config,p,SEEK_SET);
01068 RunReport(argv0,htmlout,config,Params,NULL,unused,1,0);
01069
01070 CGIFCLOSE(config);
01071 DeleteNVP(unused);
01072 DeleteNVP(Options);
01073
01074
01075
01076
01077
01078
01079 return 0;
01080 }
01081
01082 int CalcCountSummary(CGINameValue* Params,char* fieldname)
01083 {
01084 CGINameValue* start;
01085 start = GetField(Params,fieldname);
01086
01087
01088 if (start)
01089 if (start->value)
01090 return *start->value ? 1 : 0;
01091
01092 if (strchr(fieldname,'_'))
01093 {
01094 char* name = strdup(fieldname);
01095 char* code = strchr(name,'_');
01096 size_t l;
01097 *code=0;
01098 l = strlen(name);
01099 start = GetField(Params,name);
01100 if (!start) {CGIFREE(name); return 0; }
01101 while (start->name)
01102 {
01103 if (strncmp(start->name,name,l))
01104 break;
01105
01106 if (start->value)
01107 if ((start->name[l] == '_' || start->name[l] == 0) && *start->value)
01108 if (HasToken(start->value,code+1,0))
01109 {CGIFREE(name); return 1;}
01110
01111 start++;
01112 }
01113 CGIFREE(name);
01114 }
01115 else
01116 {
01117 start = GetField(Params,fieldname);
01118 if (!start)
01119 {
01120 size_t l = strlen(fieldname);
01121 start = Params;
01122 while (start->name)
01123 {
01124 if (!strncmp(start->name,fieldname,l))
01125 if (start->value)
01126 if ((start->name[l] == '_' || start->name[l] == 0) && *start->value)
01127 return 1;
01128
01129 start++;
01130 }
01131 }
01132 }
01133
01134 return 0;
01135 }
01136
01137 #ifdef CGI_ODBC
01138 int ODBCRunScript(char* argv0,STREAM result,char* dbname,
01139 CGINameValue* config,
01140 CGINameValue* Params,
01141 char* search)
01142 {
01143 int ret;
01144 FILE* script;
01145 ScriptFunction Functions[] =
01146 {{"escape",2,(ScriptFunctionCall)*JSSQLEscape},
01147 {"print",16,(ScriptFunctionCall)*JSPrint},
01148 {"write",16,(ScriptFunctionCall)*JSPrint},
01149 {"eval",1,(ScriptFunctionCall)*JSEval},
01150 {"timestamp",0,(ScriptFunctionCall)*JSTimeStamp},
01151 {"timedate",0,(ScriptFunctionCall)*JSTimeDate},
01152 {"timetime",0,(ScriptFunctionCall)*JSTimeTime},
01153 {"uniqueid",1,(ScriptFunctionCall)*JSUniqueId},
01154 {"toFixed",2,(ScriptFunctionCall)*JStoFixed},
01155 {"ranksort",128,(ScriptFunctionCall)*JSRankSort},
01156 {"rankindex",2,(ScriptFunctionCall)*JSRankIndex},
01157 {"runReport",8,(ScriptFunctionCall)*JSReport},
01158 {"environment",1,(ScriptFunctionCall)*JSGetEnv},
01159 {"number",1,(ScriptFunctionCall)*JSToNumber},
01160 {"toNumber",1,(ScriptFunctionCall)*JSToNumber},
01161 {"random",1,(ScriptFunctionCall)*JSRandom},
01162 {"subStr",3,(ScriptFunctionCall)*JSsubstr},
01163 {"indexOf",4,(ScriptFunctionCall)*JSIndexOf},
01164 {"length",1,(ScriptFunctionCall)*JSstrlen},
01165 {0,0,0}};
01166
01167 ScriptEnvironment Global;
01168
01169 memset(&Global,0,sizeof(Global));
01170 Global.htmlout = result;
01171 Global.Functions = Functions;
01172 Global.argv0 = argv0;
01173 Global.config = config;
01174
01175 script = FileOpen(argv0,dbname,".val");
01176 if (script == NULL) return 1;
01177
01178 if (!ReadUntilWordS(script,0,search))
01179 {
01180 ret = 57;
01181 goto end;
01182 }
01183
01184 ReadUntilChar(script,0,0,">",0);
01185
01186 ret = RunScript(&Global,script,Params);
01187 if (ret > 0)
01188 {
01189 PrintScriptError(result,&Global, script, ret);
01190 }
01191
01192 end:
01193 CGIFCLOSE(script);
01194 return ret;
01195 }
01196
01197 int TryODBC(SQLDB* db, char * argv0, char* dbname, CGINameValue* config, CGINameValue* Params, char* script)
01198 {
01199 char *c;
01200 int ret;
01201 EZSSTREAM result;
01202 int rowsUpdated = 0;
01203
01204 memset(&result,0,sizeof(result));
01205 result.t = NewBuffer(1024);
01206
01207 ret = ODBCRunScript(argv0,&result,dbname,config,Params,script);
01208 if (ret)
01209 {
01210 char s[128];
01211 sprintf(s,"ODBCRunScript error %d for ",ret);
01212 LogError(s);
01213 LogError(script);
01214 }
01215
01216 c = CopyBuffer(result.t);
01217 DeleteBuffer(result.t);
01218
01219 if (ret)
01220 {
01221 LogError(c);
01222 CGIFREE(c);
01223 return ret;
01224 }
01225
01226 if (*c)
01227 ret = ODBCExec(db,c,&rowsUpdated);
01228
01229 if (ret)
01230 {
01231 char s[128];
01232 sprintf(s,"\nODBCRunScript error %d",ret);
01233 LogError(s);
01234 }
01235
01236
01237 CGIFREE(c);
01238 if (ret) return ret;
01239 if (rowsUpdated == 0) return -1;
01240 return 0;
01241 }
01242 #endif
01243
01244 int GetRespcount(char* argv0, char* dbname)
01245 {
01246 char filename[MAXPATH];
01247 int i = 0;
01248 FILE * f;
01249
01250 ExpandLocalPath(argv0,filename,dbname,".respcount");
01251 f = CGIFOPEN(filename,"rb");
01252 if (f)
01253 {
01254 fread(&i,sizeof(i),1,f);
01255 fclose(f);
01256 }
01257 return i;
01258 }
01259
01260 int SetRespcount(char* argv0, char* dbname, int i)
01261 {
01262 char filename[MAXPATH];
01263
01264 FILE * f;
01265 ExpandLocalPath(argv0,filename,dbname,".respcount");
01266 f = CGIFOPEN(filename,"wb");
01267 if (f)
01268 {
01269 fwrite(&i,sizeof(i),1,f);
01270 fclose(f);
01271 return 1;
01272 }
01273 return 0;
01274 }
01275
01276 int SaveData(char* argv0,char* dbname,
01277 CGINameValue* Params, CGINameValue* config,
01278 int SubtractOldStats)
01279 {
01280 int ret = 0;
01281 int respcount = GetRespcount(argv0,dbname);
01282
01283 if ( atoi( GetSetting(config,"LOGDATETIME","1")) == 0)
01284 {
01285 RenameField(Params,"HOST","_HOST");
01286 RenameField(Params,"DATE","_DATE");
01287 RenameField(Params,"TIME","_TIME");
01288 }
01289
01290 if (atoi(GetSetting(config,"SAVEEMAIL","0")))
01291 {
01292 char* form = GetSetting(config,"EMAILREPORT","");
01293 char* address = GetSetting(config,"SAVEEMAILNAME","");
01294 char* server = GetSetting(config,"EMAILSERVER","");
01295 char* profile = GetSetting(config,"EMAILPROFILE","Windows Messaging Settings");
01296 char* name = GetSetting(config,"EMAILNAME","");
01297 char* password = GetSetting(config,"EMAILPWD","");
01298
01299 {
01300 EZSSTREAM result;
01301 char*c;
01302 FILE* script = NULL;
01303
01304 memset(&result,0,sizeof(result));
01305 result.t = NewBuffer(1024);
01306
01307 if (*form)
01308 script = FileOpen(argv0,form,0);
01309 if (script)
01310 {
01311 RunReport(argv0,&result,script,Params,NULL,NULL,0,NULL);
01312 CGIFCLOSE(script);script=NULL;
01313 }
01314 else
01315 {
01316 int i;
01317 HTMLWrite(&result,"EZSurvey web data from: ");
01318 HTMLWrite(&result,GetFieldValue(Params,"HOST"));
01319 HTMLWrite(&result,"\r\nX-DATABASE: ");
01320 HTMLWrite(&result,dbname);
01321 HTMLWrite(&result,"\r\n");
01322
01323 for (i=0; Params[i].name; i++)
01324 {
01325 if (Params[i].name[0] == '_' || Params[i].name[0] == 0) continue;
01326 HTMLWrite(&result,Params[i].name);
01327 HTMLWrite(&result,": ");
01328 HTMLWrite(&result,Params[i].value);
01329 HTMLWrite(&result,"\r\n");
01330 }
01331 }
01332
01333 c = CopyBuffer(result.t);
01334 ret = SendMail(address,"EZSurvey form submission report",c, server, profile, name, password);
01335 CGIFREE(c);
01336 DeleteBuffer(result.t);
01337 }
01338 if (ret) return ret;
01339 }
01340
01341 #if defined(XP_WIN) && !defined(__WINCE__)
01342 #define USE_MUTEX
01343 #endif
01344 if (atoi(GetSetting(config,"SAVESTAT","0")))
01345 {
01346 char statfile[MAXPATH];
01347 char *c = GetSetting(config,"SAVESTATNAME",NULLSTR);
01348 CGINameValue* count;
01349 CGINameValue* sum;
01350 CGINameValue* old;
01351 #ifdef USE_MUTEX
01352 HANDLE Mutex;
01353 char Mutex_name[MAXPATH+1];
01354 strncpy(Mutex_name,statfile,MAXPATH);
01355 Mutex_name[MAXPATH] = 0;
01356 swapchars(Mutex_name, '\\', '/');
01357 Mutex = CreateMutex(0,FALSE,statfile);
01358 if (Mutex) WaitForSingleObject(Mutex,20000);
01359 #else
01360 FILE* out;
01361 #endif
01362
01363 old = NULL;
01364 if (SubtractOldStats) old = LoadUserData(config,argv0,dbname,Params,&ret);
01365
01366 if (ret) return ret;
01367
01368 ExpandLocalPath(argv0,statfile,c,NULLSTR);
01369 count = ReadINIFileSection(statfile, "COUNT",0);
01370 sum = ReadINIFileSection(statfile, "SUM",0);
01371 #ifndef USE_MUTEX
01372 out = CGIFOPEN(statfile,"wt");
01373
01374 if (out)
01375 #endif
01376 {
01377 int i;
01378 if (count)
01379 {
01380 #ifndef USE_MUTEX
01381 fwrite("[COUNT]\n",1,8,out);
01382 #endif
01383 for(i=0; count[i].name; i++)
01384 {
01385 int x = atoi(count[i].value);
01386 int d = CalcCountSummary(Params,count[i].name);
01387 if (old != NULL) d -= CalcCountSummary(old,count[i].name);
01388 x += d;
01389
01390 #ifdef USE_MUTEX
01391 if (d)
01392 {
01393 char temp[32];
01394 sprintf(temp,"%d",x);
01395 #ifdef UNICODE
01396 WritePrivateProfileStringA("COUNT",count[i].name,temp,statfile);
01397 #else
01398 WritePrivateProfileString("COUNT",count[i].name,temp,statfile);
01399 #endif
01400 }
01401 #else
01402 fprintf(out,"%s=%d\n",count[i].name,x);
01403 #endif
01404 }
01405 }
01406 if (sum)
01407 {
01408 #ifndef USE_MUTEX
01409 fwrite("[SUM]\n",1,6,out);
01410 #endif
01411 for(i=0; sum[i].name; i++)
01412 {
01413 double x = strtod(sum[i].value,0);
01414 double d = strtod(GetFieldValue(Params,sum[i].name),0);
01415 if (x < 10E16 && x > -10E16 && d < 10E16 && d > -10E16)
01416 {
01417 if (old) d -= strtod(GetFieldValue(old,sum[i].name),0);
01418 if (d < 10E16 && d > -10E16)
01419 x += d;
01420 }
01421
01422 #ifdef USE_MUTEX
01423 if (d != 0.0)
01424 {
01425 char temp[64];
01426 sprintf(temp,"%f",x);
01427 #ifdef UNICODE
01428 WritePrivateProfileStringA("SUM",sum[i].name,temp,statfile);
01429 #else
01430 WritePrivateProfileString("SUM",sum[i].name,temp,statfile);
01431 #endif
01432 }
01433 #else
01434 fprintf(out,"%s=%f\n",sum[i].name,x);
01435 #endif
01436 }
01437 }
01438 #ifndef USE_MUTEX
01439 CGIFCLOSE(out);
01440 #endif
01441 }
01442 #ifdef USE_MUTEX
01443 if (Mutex)
01444 {
01445 ReleaseMutex(Mutex);
01446 CloseHandle(Mutex);
01447 }
01448 #endif
01449 if (old) DeleteNVP(old);
01450 DeleteNVP(count);
01451 DeleteNVP(sum);
01452 }
01453 #undef USE_MUTEX
01454
01455 if (atoi(GetSetting(config,"SAVEDATA","0")))
01456 {
01457 char dbfile[MAXPATH];
01458 char *c = GetSetting(config,"SAVEDATANAME",NULLSTR);
01459 char *index = GetSetting(config,"SAVEINDEXNAME",NULLSTR);
01460 int pos = 0;
01461
01462 if (strlen(c) > 1000) c[1000]=0;
01463 if (strlen(index) > 1000) index[1000]=0;
01464
01465 ExpandLocalPath(argv0,dbfile,c,NULLSTR);
01466
01467 ret = SaveDataToASC(Params,dbfile,&pos);
01468 if (ret)
01469 {
01470 char s[128];
01471 sprintf(s,"\nSaveDataToASC error %d for ",ret);
01472 LogError(dbfile);
01473 }
01474 else
01475 {
01476 FILE * db;
01477 CGINameValue * header;
01478 if (DatabaseOpen(dbfile,&db,&header,0,1))
01479 {
01480 DeleteOldRecords(db,header,Params);
01481 DatabaseClose(db,header);
01482 }
01483 }
01484
01485 if (pos && *index && ret == 0)
01486 {
01487 char indexfile[MAXPATH];
01488
01489 ExpandLocalPath(argv0,indexfile,index,NULLSTR);
01490 ret = DatabaseSaveIndex(indexfile,Params,pos);
01491 }
01492 if (ret) return ret;
01493 }
01494
01495 if (atoi(GetSetting(config,"SAVEXML","0")))
01496 {
01497 char dbfile[MAXPATH];
01498 char *c = GetSetting(config,"SAVEXMLNAME",NULLSTR);
01499
01500 if (strlen(c) > 1000) c[1000]=0;
01501
01502 ExpandLocalPath(argv0,dbfile,c,NULLSTR);
01503
01504 ret = SaveDataToXML(Params,dbfile,0);
01505 if (ret)
01506 {
01507 char s[128];
01508 sprintf(s,"\nSaveDataToXML error %d for ",ret);
01509 LogError(dbfile);
01510 }
01511
01512 if (ret) return ret;
01513 }
01514
01515 #ifdef CGI_SOAP
01516 if (atoi(GetSetting(config,"SAVESOAP","0")))
01517 {
01518 char* c;
01519 FILE* script;
01520 EZSSTREAM result;
01521 ScriptFunction Functions[] =
01522 {{"escape",1,(ScriptFunctionCall)*JSHTMLEscape},
01523 {"print",16,(ScriptFunctionCall)*JSPrint},
01524 {"write",16,(ScriptFunctionCall)*JSPrint},
01525 {"eval",1,(ScriptFunctionCall)*JSEval},
01526 {"toFixed",2,(ScriptFunctionCall)*JStoFixed},
01527 {"ranksort",128,(ScriptFunctionCall)*JSRankSort},
01528 {"runReport",8,(ScriptFunctionCall)*JSReport},
01529 {"random",1,(ScriptFunctionCall)*JSRandom},
01530 {"timestamp",0,(ScriptFunctionCall)*JSTimeStamp},
01531 {"timedate",0,(ScriptFunctionCall)*JSTimeDate},
01532 {"timetime",0,(ScriptFunctionCall)*JSTimeTime},
01533 {"uniqueid",1,(ScriptFunctionCall)*JSUniqueId},
01534 {"subStr",3,(ScriptFunctionCall)*JSsubstr},
01535 {"indexOf",4,(ScriptFunctionCall)*JSIndexOf},
01536 {"length",1,(ScriptFunctionCall)*JSstrlen},
01537 {0,0,0}};
01538
01539 ScriptEnvironment Global;
01540 memset(Global,0,sizeof(Global));
01541 Global.htmlout = &result;
01542 Global.Functions = Functions;
01543 Global.argv0 = argv0;
01544 Global.config = Config;
01545
01546 char* host = GetSetting(config,"SOAPHOST","127.0.0.1");
01547 char* port = GetSetting(config,"SOAPPORT","80");
01548 char* function = GetSetting(config,"SOAPFUNCTION","");
01549 char* soapaction = GetSetting(config,"SOAPACTION","SUBMIT");
01550
01551 if (!*function) return 66;
01552
01553
01554 script = FileOpen(argv0,dbname,".val");
01555
01556 if (!ReadUntilWordS(script,0,"<SCRIPT NAME=\"SAVESOAP\""))
01557 {
01558 rewind(script);
01559
01560 if (!ReadUntilWordS(script,0,"<SCRIPT NAME=SAVESOAP"))
01561 {
01562 CGIFCLOSE(script);script=NULL;
01563 return 65;
01564 }
01565 }
01566 ReadUntilChar(script,0,0,">");
01567
01568 memset(&result,0,sizeof(result));
01569 result.t = NewBuffer(1024);
01570
01571 ret = RunScript(&Global,script,Params,Plugins,0);
01572 if (ret > 0)
01573 {
01574 PrintScriptError(htmlout,&Env, script, ret);
01575 }
01576 CGIFCLOSE(script);
01577
01578 if (ret)
01579 return ret;
01580
01581 c = CopyBuffer(result.t);
01582
01583 if (SOAPExec(host, atoi(port), function, soapaction, c))
01584 ret = 68;
01585
01586 CGIFREE(c);
01587 DeleteBuffer(result.t);
01588 }
01589 #endif
01590
01591 #ifdef CGI_ODBC
01592 if (atoi(GetSetting(config,"SAVEODBC","0")))
01593 {
01594 SQLDB* db = 0;
01595 char* idfields = GetSetting(config,"IDFIELDS","IFMUID,IFMUID1,IFMUID2,IFMUID3,IFMUID4");
01596
01597
01598 db = ODBCConnect( GetSetting(config,"ODBCSERVICE",""),
01599 GetSetting(config,"ODBCNAME",""),
01600 GetSetting(config,"ODBCPASSWORD",""),0);
01601 if (!db)
01602 {
01603 LogError("\nODBCOpen() failed");
01604 return 52;
01605 }
01606
01607
01608
01609
01610 ret = -1;
01611
01612 if (*idfields)
01613 {
01614 CGINameValue* Userid = ReadPairedString(idfields,',',0);
01615 int i;
01616 int any = 0;
01617 for(i=0; any == 0 && Userid[i].name; i++)
01618 any = GetFieldValue(Params,Userid[i].name)[0];
01619
01620 DeleteNVP(Userid);
01621 if (any != 0)
01622 ret = TryODBC(db, argv0, dbname, config, Params, "<SCRIPT NAME=\"UPDATEODBC\"");
01623 }
01624
01625 if (ret)
01626 {
01627 ret = TryODBC(db, argv0, dbname, config, Params, "<SCRIPT NAME=\"SAVEODBC\"");
01628 }
01629
01630 if (ret == -1)
01631 {
01632 LogError("\nSQLExec Statement had no effect ");
01633 }
01634 else if (ret)
01635 {
01636 char*c;
01637 LogError("\nSQLExec Failure:\n------\n");
01638 c = CopyBuffer(db->ErrorMessage);
01639 LogError(c);
01640 LogError("\n------");
01641 CGIFREE(c);
01642 }
01643 else
01644 {
01645 ODBCCommit(db);
01646 }
01647
01648 ODBCDisconnect(db);
01649 if (ret) return ret;
01650 }
01651
01652 #endif
01653
01654 SetRespcount(argv0,dbname,respcount+1);
01655 return 0;
01656 }
01657
01658 int PrintFinish(char* argv0,STREAM htmlout,char* dbname,
01659 CGINameValue*config,CGINameValue*Params,int ret)
01660 {
01661 if (ret)
01662 {
01663 SendCGIHeader(htmlout,NULL);
01664 switch (ret)
01665 {
01666 case 2 : HTMLWrite(htmlout,"<P>Unable to read from the data file. ");
01667 #ifdef XP_WIN
01668 HTMLWrite(htmlout,"You probably need to configure your server to allow writing to ");
01669 HTMLWrite(htmlout,GetSetting(config,"SAVEDATANAME",dbname));
01670 #else
01671 HTMLWrite(htmlout,"You probably need to log into the server and run <tt>chmod a+w ");
01672 HTMLWrite(htmlout,GetSetting(config,"SAVEDATANAME",dbname));
01673 HTMLWrite(htmlout,"</tt>");
01674 #endif
01675 break;
01676
01677 case 6 : HTMLWrite(htmlout,"<P>Unable to write to the data file. ");
01678 #ifdef XP_WIN
01679 HTMLWrite(htmlout,"You probably need to configure your server to allow writing to ");
01680 HTMLWrite(htmlout,GetSetting(config,"SAVEDATANAME",dbname));
01681 #else
01682 HTMLWrite(htmlout,"You probably need to log into the server and run <tt>chmod a+w ");
01683 HTMLWrite(htmlout,GetSetting(config,"SAVEDATANAME",dbname));
01684 HTMLWrite(htmlout,"</tt>");
01685 #endif
01686 break;
01687
01688 case 9 : HTMLWrite(htmlout,"<P>Unable to write to the index file. ");
01689 #ifdef XP_WIN
01690 HTMLWrite(htmlout,"You probably need to configure your server to allow writing to ");
01691 HTMLWrite(htmlout,GetSetting(config,"SAVEINDEXNAME",dbname));
01692 #else
01693 HTMLWrite(htmlout,"You probably need to log into the server and run <tt>chmod a+w ");
01694 HTMLWrite(htmlout,GetSetting(config,"SAVEINDEXNAME",dbname));
01695 HTMLWrite(htmlout,"</tt>");
01696 #endif
01697 break;
01698
01699 case 8 : HTMLWrite(htmlout,"<P>Unable to write to the data file. ");
01700 #ifdef XP_WIN
01701 HTMLWrite(htmlout,"You probably need to configure your server to allow writing to ");
01702 HTMLWrite(htmlout,GetSetting(config,"SAVEXMLNAME",dbname));
01703 #else
01704 HTMLWrite(htmlout,"You probably need to log into the server and run <tt>chmod a+w ");
01705 HTMLWrite(htmlout,GetSetting(config,"SAVEXMLNAME",dbname));
01706 HTMLWrite(htmlout,"</tt>");
01707 #endif
01708 break;
01709
01710 case 4 : HTMLWrite(htmlout,"<P>A data file did not exist, and a new file could not be created. ");
01711 HTMLWrite(htmlout,"Please check the file acces permissions for ");
01712 HTMLWrite(htmlout,GetSetting(config,"SAVEDATANAME",dbname));
01713 break;
01714
01715 case 5 : HTMLWrite(htmlout,"<P>The database file does not match this form. "
01716 "Please download the current data and then republish the web site. ");
01717 LogMessage("\nezs: data file does not match the form: ");
01718 LogMessage(GetSetting(config,"SAVEDATANAME",dbname));
01719 HTMLWrite(htmlout,GetSetting(config,"SAVEDATANAME",dbname));
01720 HTMLWrite(htmlout,"<P>Data dump:<PRE>\n");
01721 DebugShowNVP(htmlout,Params);
01722 HTMLWrite(htmlout,"</PRE>\n");
01723 break;
01724
01725 case 23: HTMLWrite(htmlout,"<P>The server ran out of time waiting for a file lock.");
01726 HTMLWrite(htmlout,"<P>Data dump:<PRE>\n");
01727 DebugShowNVP(htmlout,Params);
01728 HTMLWrite(htmlout,"</PRE>\n");
01729 break;
01730 #ifdef XP_WIN
01731 case 31: HTMLWrite(htmlout,"<P>The mapi32.dll library is not available.");
01732 break;
01733
01734 case 32: HTMLWrite(htmlout,"<P>The mapi32.dll library does not support the CMC protocol.");
01735 break;
01736
01737 case 33: HTMLWrite(htmlout,"<P>The destination email address was invalid.");
01738 break;
01739
01740 case 34: HTMLWrite(htmlout,"<P>The email server refused to accept your message.");
01741 break;
01742
01743 #else
01744 case 36: HTMLWrite(htmlout,"<P>The sendmail program could not be found. ");
01745 break;
01746 #endif
01747
01748 case 52: HTMLWrite(htmlout,"<P>A connection could not be made to the database. See logerr.txt for details.");
01749 LogError("Service: ");
01750 LogError(GetSetting(config,"ODBCSERVICE","(undefined)"));
01751 LogError("Login: ");
01752 LogError(GetSetting(config,"ODBCNAME","(undefined)"));
01753 break;
01754
01755 #ifdef XP_WIN
01756 case 61: HTMLWrite(htmlout,"<P>Winsock 2.0 is not available.");
01757 break;
01758 #endif
01759
01760 case 62: HTMLWrite(htmlout,"<P>The server could not be found. Server:");
01761 HTMLWrite(htmlout,GetSetting(config,"EMAILSERVER",""));
01762 break;
01763 case 63: HTMLWrite(htmlout,"<P>An outgoing network connection could not be opened.");
01764 break;
01765 case 64: HTMLWrite(htmlout,"<P>Could not connect to the outgoing server.");
01766 break;
01767 case 66: HTMLWrite(htmlout,"<P>The SOAP transaction failed because the function name is missing.");
01768 break;
01769 case 68: HTMLWrite(htmlout,"<P>The SOAP connection to ");
01770 HTMLWrite(htmlout,GetSetting(config,"SOAPHOST","127.0.0.1"));
01771 HTMLWrite(htmlout,":");
01772 HTMLWrite(htmlout,GetSetting(config,"SOAPPORT","80"));
01773 HTMLWrite(htmlout,"/");
01774 HTMLWrite(htmlout,"failed.");
01775 break;
01776
01777 default: HTMLPrintf(htmlout,"<P>Error %d occurred. See logerr.txt for details. Data were not saved.",ret);
01778 }
01779 HTMLWrite(htmlout,"<hr>");
01780 }
01781 else
01782 {
01783
01784 if (atoi(GetSetting(config,"SHOWREDIRECT","0")) && *GetSetting(config,"REDIRECT",""))
01785 {
01786 char * c = GetSetting(config,"REDIRECT","");
01787 char * temp;
01788 if (c[0] == '/')
01789 {
01790 #ifndef VPWSCGI
01791 char * hostRoot = GetEnvironment(htmlout,"HTTP_HOST");
01792 if (!hostRoot) hostRoot = "";
01793 #endif
01794 temp= (char*)CGIMALLOC(strlen(c) + strlen(hostRoot) + 32);
01795 sprintf(temp,"Location: http://%s%s\r\n\r\n",hostRoot,c);
01796 }
01797 else
01798 {
01799 temp = (char*)CGIMALLOC(strlen(c) + 16);
01800 sprintf(temp,"Location: %s\r\n\r\n",c);
01801 }
01802 SendCGIHeader(htmlout,temp);
01803 CGIFREE(temp);
01804 }
01805 else
01806 {
01807 int isform = 0;
01808 SendCGIHeader(htmlout,NULL);
01809 HTMLWrite(htmlout,"<html>");
01810
01811 HTMLWrite(htmlout,"<head><title>");
01812 HTMLWrite(htmlout,GetSetting(config,"MESSAGE",""));
01813 HTMLWrite(htmlout,"</title></head><body>");
01814
01815 if (atoi(GetSetting(config,"DISPLAYMESSAGE","1")) )
01816 {
01817
01818 HTMLWrite(htmlout,GetSetting(config,"MESSAGE","<P>Thank you!"));
01819 }
01820
01821 if (atoi(GetSetting(config,"DISPLAYFORM","0")))
01822 isform = 1;
01823
01824 if (isform || atoi(GetSetting(config,"DISPLAYREPORT","0")))
01825 {
01826 char *c = GetSetting(config,isform ? "FORM" : "REPORT",NULLSTR);
01827
01828
01829 FILE *f = FileOpen(argv0,c,"");
01830
01831
01832 if (f)
01833 {
01834 RunReport(argv0,htmlout,f,Params,NULL,NULL,isform,NULL);
01835 CGIFCLOSE(f);
01836 }
01837 }
01838
01839 if (atoi(GetSetting(config,"DISPLAYHOTLINK","0")))
01840 {
01841
01842 HTMLWrite(htmlout,"<HR><A HREF=\"");
01843 HTMLWrite(htmlout,GetSetting(config,"HOTLINK","/index.html"));
01844 HTMLWrite(htmlout,"\">Click here to continue</A>\n");
01845 }
01846
01847 HTMLWrite(htmlout,"</body></html>\n");
01848 }
01849 }
01850 return 0;
01851 }
01852
01853 void ShowProgramStatus(STREAM htmlout,int Security)
01854 {
01855 if (Security == CGI_ALLOW_NONE)
01856 {
01857 HTMLWrite(htmlout,"<P>You are not permitted to use this server.");
01858 }
01859 else
01860 {
01861 HTMLWrite(htmlout,"<P>With this database, you may:<UL>");
01862 if (Security & CGI_ALLOW_READ)
01863 HTMLWrite(htmlout,"<LI>Read data\n");
01864 if (Security & CGI_ALLOW_WRITE)
01865 HTMLWrite(htmlout,"<LI>Edit records\n");
01866 if (Security & CGI_ALLOW_UPDATE)
01867 HTMLWrite(htmlout,"<LI>Update existing records\n");
01868 if (Security & CGI_ALLOW_APPEND)
01869 HTMLWrite(htmlout,"<LI>Append new records\n");
01870 if (Security & CGI_ALLOW_ADMIN)
01871 HTMLWrite(htmlout,"<LI>Administer the database\n");
01872 if (Security & CGI_ALLOW_DELETE)
01873 HTMLWrite(htmlout,"<LI>Delete records\n");
01874 HTMLWrite(htmlout,"</UL>");
01875 }
01876 }
01877
01878 int SecurityError(STREAM htmlout,CGINameValue* Params,char* dbname,char* action,int error)
01879 {
01880 int i;
01881 HTMLWrite(htmlout,"<H3>Permission denied</H3>\n");
01882 HTMLWrite(htmlout,"<P>Please enter your password to ");
01883
01884 if (error == CGI_ALLOW_UPDATE) HTMLWrite(htmlout,"update data in");
01885 else if (error == CGI_ALLOW_APPEND) HTMLWrite(htmlout,"append data to");
01886 else if (error == CGI_ALLOW_REPORT) HTMLWrite(htmlout,"view reports of");
01887 else HTMLWrite(htmlout,"use");
01888
01889 HTMLWrite(htmlout," this file.\n");
01890
01891 #ifdef __WINCE__
01892 HTMLWrite(htmlout,"<P><FORM ACTION=/ezs METHOD=POST ACCEPT-CHARSET=\"UTF-8\">");
01893 #else
01894 HTMLWrite(htmlout,"<P><FORM METHOD=POST ACCEPT-CHARSET=\"UTF-8\">");
01895 #endif
01896 HTMLWrite(htmlout,"\n<INPUT TYPE=HIDDEN NAME=DATABASE VALUE=\"");
01897 HTMLWrite(htmlout,dbname);
01898 HTMLWrite(htmlout,"\">\n<INPUT TYPE=HIDDEN NAME=_ACTION VALUE=\"");
01899 HTMLWrite(htmlout,action);
01900 HTMLWrite(htmlout,"\">\n");
01901
01902 for (i=0; Params[i].name; i++)
01903 {
01904 if (!Params[i].name[0]) continue;
01905 HTMLWrite(htmlout,"<INPUT TYPE=HIDDEN NAME=\"");
01906 HTMLEscape(htmlout,Params[i].name);
01907 HTMLWrite(htmlout,"\" VALUE=\"");
01908 HTMLEscape(htmlout,Params[i].value);
01909 HTMLWrite(htmlout,"\">\n");
01910 }
01911
01912 HTMLWrite(htmlout,"<INPUT TYPE=PASSWORD NAME=_PASSWORD> <INPUT TYPE=SUBMIT VALUE=\"Login\"></FORM><HR>");
01913
01914 return 101;
01915 }
01916
01917 int Login(STREAM htmlout,int Security,char* dbname,CGINameValue* Params,char* argv0,CGINameValue* config)
01918 {
01919 FILE * db = NULL;
01920 CGINameValue * header = NULL;
01921 char dbfile[MAXPATH];
01922 int i;
01923
01924 char *c = GetSetting(config,"SAVEDATANAME",NULLSTR);
01925
01926 if (*c)
01927 {
01928 if (strlen(c) > 1000) c[1000]=0;
01929 ExpandLocalPath(argv0,dbfile,c,NULLSTR);
01930 }
01931 else
01932 {
01933 ExpandLocalPath(argv0,dbfile,dbname,".asc");
01934 }
01935
01936 if (HasTokenI(GetSetting(config,"LOGINSEQUENCE","ASC"),"ASC",0) &&
01937 !DatabaseOpen(dbfile,&db,&header,0,0))
01938 {
01939 HTMLWrite(htmlout,"<head><title>Setup error</title></head>\n\n<BODY>\n");
01940 HTMLWrite(htmlout,"Sorry, I can't access the data file. Check the read/write permissions.");
01941 return 0;
01942 }
01943
01944 HTMLWrite(htmlout,"<head><title>Login</title></head>\n\n<BODY>\n");
01945
01946 if (Security & CGI_ALLOW_APPEND)
01947 {
01948 HTMLWrite(htmlout,"<H3>Start</H3>");
01949 #ifdef __WINCE__
01950 HTMLWrite(htmlout,"<FORM ACTION=\"/ezs\" METHOD=\"POST\" ACCEPT-CHARSET=\"UTF-8\">\n");
01951 #else
01952 HTMLWrite(htmlout,"<FORM METHOD=\"POST\" ACCEPT-CHARSET=\"UTF-8\">\n");
01953 #endif
01954 HTMLWrite(htmlout,"<INPUT TYPE=\"HIDDEN\" NAME=\"_ACTION\" VALUE=\"START\" />\n");
01955 HTMLWrite(htmlout,"<INPUT TYPE=\"HIDDEN\" NAME=\"DATABASE\" VALUE=\"");
01956 HTMLEscape(htmlout,dbname);
01957 HTMLWrite(htmlout,"\" />\n");
01958 HTMLWrite(htmlout,"<INPUT TYPE=\"SUBMIT\" VALUE=\" Start Survey \" /></FORM>");
01959
01960 }
01961 HTMLWrite(htmlout,"<H3>Please enter your login and password</H3>");
01962 #ifdef __WINCE__
01963 HTMLWrite(htmlout,"<FORM ACTION=\"/ezs\" METHOD=\"POST\" ACCEPT-CHARSET=\"UTF-8\">\n");
01964 #else
01965 HTMLWrite(htmlout,"<FORM METHOD=\"POST\" ACCEPT-CHARSET=\"UTF-8\">\n");
01966 #endif
01967 HTMLWrite(htmlout,"<INPUT TYPE=\"HIDDEN\" NAME=\"_ACTION\" VALUE=\"START\" />\n");
01968 HTMLWrite(htmlout,"<INPUT TYPE=\"HIDDEN\" NAME=\"DATABASE\" VALUE=\"");
01969 HTMLEscape(htmlout,dbname);
01970 HTMLWrite(htmlout,"\" />\n<tt>");
01971 {
01972 char* idfields = GetSetting(config,"IDFIELDS","IFMUID,IFMUID1,IFMUID2,IFMUID3,IFMUID4");
01973 CGINameValue *f = ReadPairedString(idfields,',',0);
01974 if (f)
01975 {
01976 HTMLWrite(htmlout,"<label for=\"N\">Login:</label> </tt>");
01977 HTMLWrite(htmlout,"<INPUT ID=\"N\" NAME=\"");
01978 HTMLEscape(htmlout,f[0].name);
01979 HTMLWrite(htmlout,"\" VALUE=\"");
01980 HTMLEscape(htmlout,GetFieldValue(Params,f[0].name));
01981 HTMLWrite(htmlout,"\" />\n<br>");
01982 }
01983 for (i=1; f[i].name; i++)
01984 {
01985 if (header && !GetField(header,f[i].name)) continue;
01986 if (i == 1)
01987 {
01988 HTMLWrite(htmlout,"<tt><label for=\"P\">Password:</label> ");
01989 HTMLWrite(htmlout,"</tt><INPUT ID=\"P\" TYPE=\"PASSWORD\" NAME=\"");
01990 }
01991 else
01992 {
01993 HTMLPrintf(htmlout,"<tt><label for=\"P%d\">Password%d:</label> ",i,i);
01994 HTMLPrintf(htmlout,"</tt><INPUT ID=\"P%d\" TYPE=\"PASSWORD\" NAME=\"",i);
01995 }
01996 HTMLEscape(htmlout,f[i].name);
01997 HTMLWrite(htmlout,"\" VALUE=\"");
01998 HTMLEscape(htmlout,GetFieldValue(Params,f[i].name));
01999 HTMLWrite(htmlout,"\" />\n<br>");
02000 }
02001 }
02002 HTMLWrite(htmlout,"<INPUT TYPE=\"SUBMIT\" VALUE=\" Login to the survey \" /></FORM></BODY>");
02003 DatabaseClose(db,header);
02004 return 0;
02005 }
02006
02007 int PrintInstructions(STREAM htmlout)
02008 {
02009 HTMLWrite(htmlout,"<head><title>EZSurvey CGI</title></head>\n");
02010
02011 #ifdef __WINCE__
02012 HTMLWrite(htmlout,"<FORM ACTION=/ezs METHOD=POST ACCEPT-CHARSET=\"UTF-8\">\n");
02013 #else
02014 HTMLWrite(htmlout,"<FORM METHOD=GET ACCEPT-CHARSET=\"UTF-8\">\n");
02015 #endif
02016 HTMLWrite(htmlout,
02017 "<H3>Start filling out a form</H3>"
02018 "<P><label for=D>Please type the name of the form:</label> <input ID=D name=DATABASE><BR>\n"
02019 "<input type=submit value=\" Click here to begin \"></FORM>");
02020
02021 HTMLWrite(htmlout,
02022 "<HR><P><A href=http://www.raosoft.com/products/ezsurvey>EZSurvey</A>® "
02023 RAOSOFT_CGI_VERSION ". " RAOSOFT_CGI_COPYRIGHT );
02024
02025 return 0;
02026 }
02027
02038 #ifdef VPWSCGI
02039 int CGImainEZS(char * argv0,CGINameValue* Params,STREAM htmlout)
02040 #else
02041 int CGImain(char * argv0,CGINameValue* Params,STREAM htmlout)
02042 #endif
02043 {
02044 char * dbname = GetFieldValue(Params,"DATABASE");
02045 char * password = GetFieldValue(Params,"_PASSWORD");
02046 char * action = GetFieldValue(Params,"_ACTION");
02047 char * page = GetFieldValue(Params,"_PAGE");
02048 char * session = GetFieldValue(Params,"_SESSION");
02049 char * ErrorMessage = "";
02050 char firstPW[64];
02051
02052 CGINameValue* config = NULL;
02053
02054 int ret = 0;
02055 int hasuid;
02056 int needslogin;
02057 int multipage;
02058 int hasSession;
02059
02060
02061 int Security = GetSecurityFlags(argv0,GetFieldValue(Params,"HOST"),dbname,password);
02062
02063 if (Security == CGI_ALLOW_NONE || !Params || !*dbname)
02064 {
02065 SendCGIHeader(htmlout,NULL);
02066 return PrintInstructions(htmlout);
02067 }
02068
02069
02070
02071
02072
02073
02074
02075 if (*page) if (strlen(page) < 5)
02076 {
02077 SendCGIHeader(htmlout,NULL);
02078 HTMLWrite(htmlout,"Bad page name: ");
02079 HTMLEscape(htmlout,page);
02080 return 103;
02081 }
02082
02083 if (!ret) if (strlen(dbname)>128) ret = 102;
02084 if (!ret) if (strlen(password)>128) ret = 102;
02085 if (!ret) if (strlen(action)>128) ret = 102;
02086 if (!ret) if (strlen(page)>128) ret = 102;
02087
02088 if (ret)
02089 {
02090 return ret;
02091 }
02092 else
02093 {
02094 char fn[MAXPATH];
02095 ExpandLocalPath(argv0,fn,dbname,".ini");
02096
02097
02098 config = ReadINIFileSection(fn,"DATABASE",0);
02099
02100 if (config == NULL)
02101 {
02102 SendCGIHeader(htmlout,NULL);
02103
02104 PrintInstructions(htmlout);
02105
02106 HTMLWrite(htmlout,argv0);
02107 HTMLWrite(htmlout,": A configuration file for the database \"<b>");
02108 HTMLEscape(htmlout,dbname);
02109 HTMLWrite(htmlout,"</b>\" was not found. Please check your spelling and server setup and try again.<P>\n");
02110 HTMLWrite(htmlout,"Cannot access file (");
02111 HTMLEscape(htmlout,dbname);
02112 HTMLWrite(htmlout,".ini)");
02113 LogError("\nCould not open config file ");
02114 LogError(fn);
02115 return 21;
02116 }
02117 }
02118
02119 dbname = strdup(dbname);
02120 action = strdup(action);
02121 password = strdup(password);
02122 page = strdup(page);
02123
02124
02125 RenameField(Params,"DATABASE",0);
02126 RenameField(Params,"_ACTION",0);
02127
02128
02129 if (!atoi(GetSetting(config,"ACTIVE","1")))
02130 {
02131 SendCGIHeader(htmlout,NULL);
02132 PrintInstructions(htmlout);
02133 }
02134
02135 needslogin = atoi(GetFieldValue(config,"HASUID"));
02136 hasSession = *GetFieldValue(config,"_SESSION");
02137 multipage = atoi(GetFieldValue(config,"MULTIPAGE"));
02138
02139 {
02140 char*c;
02141 firstPW[0]=0;
02142 strncpy(firstPW,GetSetting(config,"IDFIELDS","IFMUID"),sizeof(firstPW));
02143 firstPW[sizeof(firstPW)-1]=0;
02144 c = strchr(firstPW,',');
02145 if (c) *c=0;
02146 hasuid = (*GetFieldValue(Params,firstPW) != 0);
02147 }
02148
02149 if (!*session)
02150 {
02151 char newsession[48];
02152 GenerateUniqueID(newsession, GetFieldValue(config,"HOST"));
02153 SetFieldValue(Params,"_SESSION",newsession);
02154 }
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165 {
02166 int maxResponses = atoi(GetSetting(config,"MAXRESPONSES",""));
02167 if (maxResponses != 0)
02168 {
02169 char filename[MAXPATH];
02170 int i = 0;
02171
02172 #if defined(XP_WIN) &&!defined(__WINCE__)
02173 ExpandLocalPath(argv0,filename,"ezscounts.ini",0);
02174 #ifdef UNICODE
02175 i = GetPrivateProfileIntA("responses",dbname,0,filename);
02176 #else
02177 i = GetPrivateProfileInt("responses",dbname,0,filename);
02178 #endif
02179 #else
02180 ExpandLocalPath(argv0,filename,dbname,".respcount");
02181 {
02182 FILE * f;
02183 f = CGIFOPEN(filename,"rb");
02184 if (f) { fread(&i,sizeof(i),1,f); CGIFCLOSE(f);}
02185 }
02186 #endif
02187 if (i >= maxResponses)
02188 {
02189 ErrorMessage = GetSetting(config,"MAXMESSAGE","Sorry, this form is no longer available.");
02190 ret = 12;
02191 }
02192 }
02193 }
02194
02195 if (!ret)
02196 {
02197 char* stoptime = GetFieldValue(config,"STOPDATE");
02198 if (*stoptime)
02199 {
02200 char now[16];
02201 size_t l = strlen(stoptime);
02202 GetTime(now, now+8,0);
02203 if (l < sizeof(now)) now[l]=0;
02204 if (strcmp(now,stoptime)>0)
02205 ret = 13;
02206 }
02207 }
02208
02209 if (!ret)
02210 {
02211 char* active = GetFieldValue(config,"ACTIVE");
02212 if (*active)
02213 if (!atoi(active))
02214 ret = 13;
02215 }
02216
02217 if (!ret)
02218 {
02219 char* pwdfile = GetSetting(config,"PWDFILE","");
02220 if (*pwdfile)
02221 {
02222 char* userid = GetFieldValue(Params,firstPW);
02223
02224 if (!*userid)
02225 {
02226 ret = 11;
02227 }
02228 else
02229 {
02230 FILE* pwlist;
02231 char line[128];
02232
02233 pwlist = CGIFOPEN(pwdfile,"rt");
02234 ret = 11;
02235
02236 if (pwlist)
02237 {
02238 while (ReadUntilChar(pwlist,line,128," \t\r\n",0) > 0)
02239 {
02240 if (!stricmp(line,userid))
02241 {ret = 0; break;}
02242 }
02243 CGIFCLOSE(pwlist);
02244 }
02245 }
02246 }
02247 }
02248
02249 if (ret)
02250 {
02251 switch(ret)
02252 {
02253 case 11: ErrorMessage = GetSetting(config,"PWDMESSAGE","Sorry, you need a password to access this form."); break;
02254 case 12:
02255 case 13: ErrorMessage = GetSetting(config,"MAXMESSAGE","Sorry, this form is no longer available.");
02256 }
02257 }
02258 else
02259 {
02260 if (!stricmp(action,"REPORT"))
02261 {
02262 if (!(Security & CGI_ALLOW_REPORT))
02263 {
02264 SendCGIHeader(htmlout,NULL);
02265 ret = SecurityError(htmlout,Params,dbname,action,CGI_ALLOW_REPORT);
02266 }
02267 else
02268 {
02269 char *c;
02270 FILE *f;
02271
02272 c = GetSetting(config,"REPORT2",NULLSTR);
02273
02274
02275
02276 f = *c ? FileOpen(argv0,c,"") : 0;
02277
02278
02279 SendCGIHeader(htmlout,NULL);
02280 if (f)
02281 {
02282 RunReport(argv0,htmlout,f,Params,NULL,NULL,0,NULL);
02283 CGIFCLOSE(f);
02284 ret = 0;
02285 }
02286 else
02287 HTMLWrite(htmlout,"Report file not found");
02288 }
02289 }
02290 else if (!*action || !stricmp(action,"START"))
02291 {
02292 char* form = GetFieldValue(config,"FORM");
02293 SendCGIHeader(htmlout,NULL);
02294
02295 if (needslogin)
02296 {
02297 if (hasuid || (!stricmp(action,"START") && (Security &CGI_ALLOW_APPEND)))
02298
02299 {
02300 CGINameValue* userdata = NULL;
02301 if (hasuid)
02302 userdata = LoadUserData(config,argv0,dbname,Params,&ret);
02303
02304 if (!ret)
02305 {
02306 if (userdata != NULL)
02307 {
02308 char* next = "";
02309 char* pageback = "";
02310 if (atoi(GetFieldValue(config,"FORGETPAGES"))==0)
02311 {
02312 next = GetFieldValue(userdata,"_PAGE");
02313 pageback = GetFieldValue(userdata,"_PAGEBACK");
02314 }
02315 if (!*next) next = GetSetting(config,"STARTPAGE","page0");
02316
02317 if (Security & CGI_ALLOW_UPDATE)
02318 ret = multipage
02319 ? ShowFormPage(argv0,htmlout,dbname,userdata,pageback,next)
02320 : ShowForm(argv0,htmlout,form,userdata);
02321 else
02322 {
02323 ret = SecurityError(htmlout,Params,dbname,action,CGI_ALLOW_UPDATE);
02324 Login(htmlout,Security,dbname,Params,argv0,config);
02325 }
02326
02327 DeleteNVP(userdata);
02328 }
02329 else if (!ret)
02330 {
02331 if (Security & CGI_ALLOW_APPEND)
02332 ret = multipage
02333 ? ShowFormPage(argv0,htmlout,dbname,Params,"",GetSetting(config,"STARTPAGE","page0"))
02334 : ShowForm(argv0,htmlout,form,Params);
02335 else
02336 {
02337 ret = SecurityError(htmlout,Params,dbname,action,CGI_ALLOW_APPEND);
02338 Login(htmlout,Security,dbname,Params,argv0,config);
02339 }
02340 }
02341 }
02342 }
02343 else
02344 {
02345 Login(htmlout,Security,dbname,Params,argv0,config);
02346 }
02347 }
02348 else
02349 {
02350 ret = multipage
02351 ? ShowFormPage(argv0,htmlout,dbname,Params,"",GetSetting(config,"STARTPAGE","page0"))
02352 : ShowForm(argv0,htmlout,form,Params);
02353 }
02354 }
02355 else if (multipage && !stricmp(action,"NEXT"))
02356 {
02357 char* pagenext;
02358 char* pageback;
02359 char* skip;
02360
02361 skip = GetFieldValue(Params,"_PAGESKIP");
02362
02363 SendCGIHeader(htmlout,NULL);
02364
02365
02366
02367 if (atoi(GetFieldValue(config,"SAVEPAGE")) && stricmp(skip,"(save)"))
02368 SaveData(argv0, dbname, Params, config, hasSession);
02369
02370 if (*page) ValidatePage(argv0,htmlout,dbname,config,Params,page);
02371
02372 pagenext = GetFieldValue(Params,"_PAGENEXT");
02373 pageback = GetFieldValue(Params,"_PAGEBACK");
02374 skip = GetFieldValue(Params,"_PAGESKIP");
02375
02376
02377 while (HasToken(pagenext,page,0))
02378 ClearToken(pagenext,page);
02379
02380 if (*GetFieldValue(Params,"_PAGEWARN"))
02381 {
02382 ret = ShowFormPage(argv0,htmlout,dbname,Params,pageback,page);
02383 }
02384 else
02385 {
02386
02387 if (!strcmp(skip,"(save)"))
02388 goto atSaveData;
02389
02390 if (*skip && *pagenext)
02391 {
02392 char * p;
02393 if (HasToken(pagenext,skip,0))
02394 ClearToken(pagenext,skip);
02395 p = strdup3(skip," ",pagenext);
02396 SetFieldValue(Params,"_PAGENEXT",p);
02397 CGIFREE(p);
02398 }
02399 else if (*skip)
02400 SetFieldValue(Params,"_PAGENEXT",skip);
02401
02402
02403 pageback = strdup3(page,",",pageback);
02404
02405
02406 CGIFREE(page);
02407 page = strdup(PopList(Params,"_PAGENEXT",0));
02408
02409
02410
02411 if (strchr(skip,','))
02412 page[0] = 'P';
02413
02414
02415 ret = ShowFormPage(argv0,htmlout,dbname,Params,pageback,page);
02416 CGIFREE(pageback);
02417 }
02418 }
02419 else if (multipage && !stricmp(action,"BACK"))
02420 {
02421 char * pageback, * pagenext;
02422
02423 SendCGIHeader(htmlout,NULL);
02424
02425 ValidateBack(argv0,htmlout,dbname,config,Params,page);
02426
02427 pageback = GetFieldValue(Params,"_PAGEBACK");
02428 pagenext = GetFieldValue(Params,"_PAGENEXT");
02429
02430 if (*GetFieldValue(Params,"_PAGEWARN"))
02431 {
02432 ret = ShowFormPage(argv0,htmlout,dbname,Params,pageback,page);
02433 }
02434 else
02435 {
02436
02437
02438
02439
02440
02441
02442
02443 if (strchr(pagenext,' '))
02444 {
02445 if (toupper(page[0]) == 'P')
02446 PopList(Params,"_PAGENEXT",' ');
02447 else
02448 {
02449
02450 char * p = strdup3(page,",",pagenext);
02451 SetFieldValue(Params,"_PAGENEXT",p);
02452 CGIFREE(p);
02453 }
02454 }
02455
02456
02457 page = strdup(PopList2(pageback,0));
02458
02459 ret = ShowFormPage(argv0,htmlout,dbname,Params,pageback,page);
02460 }
02461 }
02462 else if (!stricmp(action,"SAVE") || !stricmp(action,"SUBMIT"))
02463 {
02464
02465 atSaveData:
02466 {
02467 int allowsave = 1;
02468
02469 if (!(Security & CGI_ALLOW_APPEND))
02470 {
02471
02472 if (!(Security & CGI_ALLOW_UPDATE))
02473 {
02474 SendCGIHeader(htmlout,NULL);
02475 ret = SecurityError(htmlout,Params,dbname,action,CGI_ALLOW_APPEND);
02476 }
02477 else
02478 {
02479 CGINameValue* userdata;
02480 userdata = LoadUserData(config,argv0,dbname,Params,&ret);
02481
02482 if (!userdata)
02483 {
02484 SendCGIHeader(htmlout,NULL);
02485 ret = SecurityError(htmlout,Params,dbname,action,CGI_ALLOW_APPEND);
02486 }
02487
02488 DeleteNVP(userdata);
02489 }
02490 }
02491
02492 if (!ret)
02493 {
02494
02495
02496 if (!GetField(Params,"_PAGEWARN"))
02497 {
02498 RenameField(Params,"","_PAGEWARN");
02499
02500 }
02501
02502 if (multipage)
02503 {
02504 if (!stricmp(action,"SUBMIT"))
02505 {
02506 ValidatePage(argv0,htmlout,dbname,config,Params,page);
02507 if (*GetFieldValue(Params,"_PAGEWARN")) allowsave = 0;
02508 if (allowsave) SetFieldValue(Params,"_FORMDONE","1");
02509 }
02510
02511 if (allowsave)
02512 ValidatePage(argv0,htmlout,dbname,config,Params,"SUBMIT");
02513 }
02514 else
02515 {
02516 ValidatePage(argv0,htmlout,dbname,config,Params,"SUBMIT");
02517 if (*GetFieldValue(Params,"_PAGEWARN")) allowsave = 0;
02518 if (allowsave) SetFieldValue(Params,"_FORMDONE","1");
02519 }
02520
02521 if (allowsave == 0)
02522 {
02523
02524 SendCGIHeader(htmlout,NULL);
02525 ret = multipage
02526 ? ShowFormPage(argv0,htmlout,dbname,Params,GetFieldValue(Params,"_PAGEBACK"),page)
02527 : ShowForm(argv0,htmlout,dbname,Params);
02528 }
02529 else
02530 {
02531
02532
02533 ret = SaveData(argv0,dbname, Params, config,
02534 (atoi(GetFieldValue(config,"SAVEPAGE")) && hasSession)
02535 || (hasuid && needslogin));
02536 PrintFinish(argv0,htmlout,dbname,config,Params,ret);
02537 }
02538 }
02539 }
02540 }
02541 }
02542
02543 if (ret)
02544 {
02545 if (ErrorMessage)
02546 {
02547 if (strnicmp(ErrorMessage,"http://",7) == 0)
02548 {
02549 char * temp = (char*)CGIMALLOC(strlen(ErrorMessage) + 16);
02550 sprintf(temp,"Location: %s\n\n",ErrorMessage);
02551 SendCGIHeader(htmlout,temp);
02552 CGIFREE(temp);
02553 }
02554 else
02555 {
02556 SendCGIHeader(htmlout,NULL);
02557 HTMLWrite(htmlout,ErrorMessage);
02558 }
02559 }
02560 else
02561 {
02562 SendCGIHeader(htmlout,NULL);
02563 HTMLWrite(htmlout,"<P>CGI error: unknown action<pre>");
02564 HTMLWrite(htmlout,"database: '");
02565 HTMLWrite(htmlout,dbname);
02566 HTMLWrite(htmlout,"'\npassword: '");
02567 HTMLWrite(htmlout,password);
02568 HTMLWrite(htmlout,"'\naction: '");
02569 HTMLWrite(htmlout,action);
02570 HTMLWrite(htmlout,"'\npage: '");
02571 HTMLWrite(htmlout,page);
02572 HTMLWrite(htmlout,"'\nsession: '");
02573 HTMLWrite(htmlout,session);
02574 HTMLWrite(htmlout,"'\nAll parameters: \n");
02575 DebugShowNVP(htmlout,Params);
02576 }
02577 }
02578
02579 if (ret > 100)
02580 {
02581 char * msg;
02582 char* email = GetFieldValue(config,"ADMINEMAIL");
02583 if (*email)
02584 {
02585 char temp[32];
02586 TextBuffer* m = NewBuffer(1024);
02587 sprintf(temp,"%d",ret);
02588 BufferWrite(m,"Database: ");
02589 BufferWrite(m,dbname);
02590 BufferWrite(m,"\r\nError code: ");
02591 BufferWrite(m,temp);
02592 BufferWrite(m,"\r\nRemote host: ");
02593 BufferWrite(m,GetFieldValue(config,"HOST"));
02594 BufferWrite(m,"\r\nPage file: ");
02595 BufferWrite(m,page);
02596 BufferWrite(m,"\r\nAction: ");
02597 BufferWrite(m,action);
02598 BufferWrite(m,"\r\n_PAGE: ");
02599 BufferWrite(m,GetFieldValue(config,"_PAGE"));
02600 BufferWrite(m,"\r\n_PAGEBACK: ");
02601 BufferWrite(m,GetFieldValue(config,"_PAGEBACK"));
02602 BufferWrite(m,"\r\n_PAGENEXT: ");
02603 BufferWrite(m,GetFieldValue(config,"_PAGENEXT"));
02604 BufferWrite(m,"\r\n_PASSWORD: ");
02605 BufferWrite(m,password);
02606 BufferWrite(m,"\r\n");
02607 msg = CopyBuffer(m);
02608 SendMail(email, "Web access security violation",
02609 msg,
02610 GetSetting(config,"EMAILSERVER",""),
02611 GetSetting(config,"EMAILPROFILE","Windows Messaging Settings"),
02612 GetSetting(config,"EMAILNAME",""),
02613 GetSetting(config,"EMAILPWD",""));
02614 CGIFREE(msg);
02615 DeleteBuffer(m);
02616 }
02617 ShowProgramStatus(htmlout,Security);
02618 }
02619
02620 DeleteNVP(config);
02621 if (dbname) CGIFREE(dbname);
02622 if (password) CGIFREE(password);
02623 if (action) CGIFREE(action);
02624 if (page) CGIFREE(page);
02625
02626 return ret;
02627 }