00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "cgi.h"
00015 #include <dirent.h>
00074 static char* systemFields = "DIRECTORY,PAGE,NAME,SECTION";
00075
00076 typedef struct
00077 {
00078 char* argv0;
00079 CGINameValue* Config;
00080 CGINameValue* Params;
00081 STREAM htmlout;
00082 } AdminInfo;
00083
00084 int WriteINIFileSection(char* fname,char* section, CGINameValue* ini)
00085 {
00086 int size = FileSize(fname);
00087 char* c;
00088 char *d, *e;
00089 char* lastname="";
00090 char* start;
00091 size_t i;
00092 FILE * f = fopen(fname,"rt");
00093 if (!f) return 0;
00094
00095 start = strdup3("[",section,"]");
00096 c = CGIMALLOC(size + 2);
00097 size = fread(c,1,size,f);
00098 c[size]=0;
00099 fclose(f);
00100
00101 d = stristr(c,start);
00102 if (d) e = stristr(d+1,"\n[");
00103 else e = 0;
00104
00105 f = fopen(fname,"wt");
00106 if (!f)
00107 {
00108 CGIFREE(c);
00109 return 0;
00110 }
00111
00112 fwrite(c,1,d ? (d-c) : size,f);
00113 fprintf(f,"%s",start);
00114
00115 for (i=0; ini[i].name; i++)
00116 {
00117 if (!ini[i].name[0]) continue;
00118 if (!strcmp(ini[i].name,lastname))
00119 fprintf(f,",%s",ini[i].value);
00120 else
00121 fprintf(f,"\n%s=%s",ini[i].name,ini[i].value);
00122 lastname = ini[i].name;
00123 }
00124 fwrite("\n",1,1,f);
00125
00126 if (e)
00127 fwrite(e,1,strlen(e),f);
00128
00129 fclose(f);
00130 CGIFREE(c)
00131 CGIFREE(start);
00132 return 1;
00133 }
00134
00135 void DoSetValue(CGINameValue* Variables, char*name, char* value)
00136 {
00137 if (!SetFieldValue(Variables,name,value))
00138 {
00139 ExtendNVP(Variables,128);
00140 SetFieldValue(Variables,name,value);
00141
00142 }
00143 }
00144
00145 int GetRespcount(char* argv0, char* dbname)
00146 {
00147 char filename[MAXPATH];
00148 int i = 0;
00149 FILE * f;
00150
00151 ExpandLocalPath(argv0,filename,dbname,".respcount");
00152 f = CGIFOPEN(filename,"rb");
00153 if (f)
00154 {
00155 fread(&i,sizeof(i),1,f);
00156 fclose(f);
00157 }
00158 return i;
00159 }
00160
00161 int SetRespcount(char* argv0, char* dbname, int i)
00162 {
00163 char filename[MAXPATH];
00164
00165 FILE * f;
00166 ExpandLocalPath(argv0,filename,dbname,".respcount");
00167 f = CGIFOPEN(filename,"wb");
00168 if (f)
00169 {
00170 fwrite(&i,sizeof(i),1,f);
00171 fclose(f);
00172 return 1;
00173 }
00174 return 0;
00175 }
00176
00177 FILE* OpenPage(char* argv0,char* page)
00178 {
00179 char fname[MAXPATH];
00180 FILE* f=0;
00181 if (!page) return 0;
00182 if (!*page) return 0;
00183 ExpandLocalPath(argv0,fname,"admin" SLASH,page);
00184 f = fopen(fname,"rt");
00185 return f;
00186 }
00187
00188 void Login(AdminInfo* self)
00189 {
00190 FILE* source = OpenPage(self->argv0,"login.html");
00191 if (source)
00192 {
00193 RunReport(self->argv0,self->htmlout,source,self->Params,0,0,1,0);
00194 fclose(source);
00195 }
00196 }
00197
00198
00251 int VerifyPassword(AdminInfo* self,char* directory, char* password)
00252 {
00253 char fname[MAXPATH];
00254 CGINameValue* ini;
00255 int ret;
00256 char* c;
00257 if (!*directory) directory = ".";
00258 ExpandLocalPath(self->argv0,fname,directory,SLASH "cgi.ini");
00259 ini = ReadINIFileSection(fname,"admin",0);
00260 c = GetFieldValue(ini,"PASSWORD");
00261 ret = *c && HasToken(password,c,0);
00262 DeleteNVP(ini);
00263 return ret;
00264 }
00265
00266 int VerifyUser(AdminInfo* self,char* directory, char* username, char* session, char* password)
00267 {
00268 char * verify;
00269 char fname[MAXPATH];
00270 CGINameValue* ini;
00271 int ret;
00272 ret = strcspn(username,"\\/.");
00273 if (username[ret]) return 0;
00274 if (ret > 32) return 0;
00275 ExpandLocalPath(self->argv0,fname,"admin" SLASH, username);
00276 strcat(fname,".ini");
00277 ini = ReadINIFileSection(fname,"USER",1);
00278 if (!ini) return 0;
00279
00280 ret = atoi(GetFieldValue(ini,"ACTIVE"));
00281 if (ret)
00282 {
00283
00284 if (*password && !strcmp(password,GetFieldValue(ini,"PASSWORD")))
00285 {
00286 ret = 1;
00287
00288 SetFieldValue(ini,"SESSION",session);
00289 WriteINIFileSection(fname,"USER",ini);
00290 }
00291
00292 else if (*session && atoi(session) && !strcmp(session,GetFieldValue(ini,"SESSION")))
00293 ret = 1;
00294 else
00295 ret = 0;
00296
00297 if (ret)
00298 {
00299 char* home = GetFieldValue(ini,"HOME");
00300 if (!*home && !*directory)
00301 ret = 1;
00302 else if (*home && !*directory)
00303 {
00304 SetFieldValue(self->Params,"DIRECTORY",home);
00305 ret = 2;
00306 }
00307 else
00308 {
00309 ret = HasTokenI(GetFieldValue(ini,"SPACES"),directory,0);
00310 if (!ret)
00311 ret = HasTokenI(GetFieldValue(ini,"SPACES"),"admin",0);
00312 }
00313
00314 }
00315
00316 }
00317
00318 DeleteNVP(ini);
00319 return ret;
00320 }
00321
00323 int Authenticate(AdminInfo* self,char* directory, char** cookie)
00324 {
00325 CGINameValue *clist=0;
00326
00327 int ret = 0;
00328 char * password = GetFieldValue(self->Params,"AUTHENTICATION");
00329 char * username = GetFieldValue(self->Params,"USER");
00330
00331 int authUser = atoi(GetFieldValue(self->Config,"AUTHUSER"));
00332 int authSpace = atoi(GetFieldValue(self->Config,"AUTHSPACE"));
00333
00334 if (cookie)
00335 {
00336 if (*cookie)
00337 clist = ReadPairedString(*cookie,';',0);
00338
00339 *cookie = 0;
00340 }
00341
00342 if (!strcmp(directory,".")) directory = "";
00343
00344 if (*username && authUser)
00345 {
00346 char s[32];
00347 int i = time(0) ^ 0x5a5a5a5a;
00348
00349 i = (i&0x00ffff00) | ((i & 0xff000000) >> 24) | ((i & 0x000000ff) << 24);
00350 sprintf(s,"%u",i);
00351
00352 ret = VerifyUser(self,directory, username, s, password);
00353 if (ret && cookie)
00354 {
00355 char x[128];
00356 sprintf(x,"Set-Cookie: USER=%s;\nSet-Cookie: SESSION=%s;\nSet-Cookie: PASSWORD=;",username,s);
00357 *cookie = strdup(x);
00358 }
00359 }
00360
00361 if (!ret && *password && authSpace)
00362 {
00363 ret = VerifyPassword(self, directory, password);
00364 if (ret && cookie)
00365 {
00366 char x[128], *y, *z;
00367
00368 sprintf(x,"Set-Cookie: USER=%s;\nSet-Cookie: SESSION=%s;\nSet-Cookie: PASSWORD=",
00369 GetFieldValue(clist,"USER"),
00370 GetFieldValue(clist,"SESSION"));
00371 y = strdup3(x,password,",");
00372 z = GetFieldValue(clist,"PASSWORD");
00373 if (HasToken(z,password,0))
00374 {
00375 *cookie = y;
00376 }
00377 else
00378 {
00379 z = strdup3(y,z,"");
00380 *cookie = z;
00381 }
00382 free(y);
00383 }
00384 }
00385
00386 RenameField(self->Params, "AUTHENTICATION",0);
00387 if (ret) return ret;
00388
00389 if (clist)
00390 {
00391 if (authUser)
00392 {
00393 ret = VerifyUser(self, directory, GetFieldValue(clist,"USER"), GetFieldValue(clist,"SESSION"), "");
00394 if (ret && !*username)
00395 SetFieldValue(self->Params,"USER",GetFieldValue(clist,"USER"));
00396 }
00397 if (!ret && authSpace)
00398 ret = VerifyPassword(self, directory, GetFieldValue(clist,"PASSWORD"));
00399 }
00400
00401 DeleteNVP(clist);
00402 return ret;
00403 }
00404
00405 char* RelativeName(char* directory,char* name)
00406 {
00407 if (*directory)
00408 return strdup3(directory,"/",name);
00409 else
00410 return strdup(name);
00411 }
00412
00413 void ProjectUpdate(AdminInfo *self,char* directory,char* project)
00414 {
00415 CGINameValue* ini, *Params = self->Params;
00416 char iniName[MAXPATH+5];
00417 char* name=RelativeName(directory,project);
00418 char* section=GetSetting(self->Params,"SECTION","DATABASE");
00419
00420 ExpandLocalPath(self->argv0,iniName,name,".ini");
00421 ini = ReadINIFileSection(iniName,section,ListLength(Params));
00422 if (ini)
00423 {
00424 size_t x;
00425 for (x=0; Params[x].name; x++)
00426 {
00427 if (Params[x].name)
00428 if (!HasTokenI(systemFields,Params[x].name,0))
00429 SetFieldValue(ini,Params[x].name,Params[x].value);
00430 }
00431 }
00432
00433 WriteINIFileSection(iniName,section,ini);
00434
00435 CGIFREE(name);
00436 DeleteNVP(ini);
00437 }
00438
00439 void RecurseDirectories(char* directory,STREAM htmlout,char* format, char* replace)
00440 {
00441 DIR* d;
00442 struct stat info;
00443 char* name, *c;
00444
00445 name = directory;
00446 if (!*name) name = ".";
00447 d = opendir(name);
00448 while (d)
00449 {
00450 struct dirent* f = readdir(d);
00451 if (!f) break;
00452 if (f->d_name[0] == '.') continue;
00453 name = RelativeName(directory,f->d_name);
00454
00455 if (stat(name,&info))
00456 {
00457 free(name);
00458 continue;
00459 }
00460
00461 if (info.st_mode & S_IFREG)
00462 {
00463 free(name);
00464 continue;
00465 }
00466
00467 c = strdup3(name,SLASH,"cgi.ini");
00468 if (stat(c,&info))
00469 {
00470 free(c);
00471 continue;
00472 }
00473 free(c);
00474 c = format;
00475 while (c)
00476 {
00477 char* d = (char*)stristr(c,replace);
00478 if (d)
00479 {
00480 HTMLWriteL(htmlout,c,(d-c));
00481 HTMLWrite(htmlout,name);
00482 d += strlen(replace);
00483 }
00484 else
00485 {
00486 HTMLWrite(htmlout,c);
00487 d=0;
00488 }
00489
00490 c=d;
00491 }
00492 RecurseDirectories(name,htmlout,format,replace);
00493 free(name);
00494 }
00495
00496 if (d) closedir(d);
00497 }
00498
00500 static char* JSListWorkspaces(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00501 {
00502 char* f ="$";
00503 char* g ="$";
00504 if (argc) f = argv[0];
00505 if (argc > 2) g = argv[1];
00506 RecurseDirectories("",Env->htmlout,f,g);
00507 return 0;
00508 }
00509
00511 static char* JSSendMail(ScriptEnvironment* Env, char* cmd, int argc, char** argv, CGINameValue* Params)
00512 {
00513 if (!Env->config) return 0;
00514 if (argc < 3) return 0;
00515 {
00516 char* server = GetSetting(Env->config,"EMAILSERVER","");
00517 char* profile = GetSetting(Env->config,"EMAILPROFILE","Windows Messaging Settings");
00518 char* name = GetSetting(Env->config,"EMAILNAME","");
00519 char* password = GetSetting(Env->config,"EMAILPWD","");
00520
00521 SendMail(argv[0],argv[1],argv[2], server, profile, name, password);
00522 }
00523 return 0;
00524 }
00525
00526
00527 static ScriptFunction AdminFunctions[] =
00528 {
00529 {"listDirectories",2,(ScriptFunctionCall)*JSListWorkspaces},
00530 {0,0,0}
00531 };
00532
00533 void AdminPrintPage(AdminInfo* self,char* iniName,FILE* source)
00534 {
00535 char section[MAXPATH];
00536 CGINameValue* ini=0;
00537
00538 while (!feof(source))
00539 {
00540 *section = 0;
00541
00542 if (ini)
00543 RunReportF(self->argv0,self->htmlout,source,ini,self->Params,0,1,"%load",section,AdminFunctions);
00544 else
00545 RunReportF(self->argv0,self->htmlout,source,self->Params,0,0,1,"%load",section,AdminFunctions);
00546
00547 if (ini) DeleteNVP(ini);
00548
00549 swapchars(section,'%',0);
00550
00551 if (*section)
00552 ini = ReadINIFileSection(iniName,section,0);
00553 else
00554 ini = 0;
00555 }
00556 }
00557
00558 int AdminRunScript(AdminInfo *self,CGINameValue* data,char* page)
00559 {
00560 if (page)
00561 if (*page)
00562 {
00563 int ret;
00564 FILE* script = OpenPage(self->argv0,page);
00565 ScriptFunction Functions[] =
00566 {
00567 {"print",10,(ScriptFunctionCall)*JSPrint},
00568 {"write",10,(ScriptFunctionCall)*JSPrint},
00569 {"eval",1,(ScriptFunctionCall)*JSEval},
00570 {"tofixed",2,(ScriptFunctionCall)*JStoFixed},
00571 {"sendmail",3,(ScriptFunctionCall)*JSSendMail},
00572 {"runReport",8,(ScriptFunctionCall)*JSReport},
00573 {"number",1,(ScriptFunctionCall)*JSToNumber},
00574 {"toNumber",1,(ScriptFunctionCall)*JSToNumber},
00575 {"random",1,(ScriptFunctionCall)*JSRandom},
00576 {"subStr",3,(ScriptFunctionCall)*JSsubstr},
00577 {"indexOf",4,(ScriptFunctionCall)*JSIndexOf},
00578 {"length",1,(ScriptFunctionCall)*JSstrlen},
00579 {"listDirectories",2,(ScriptFunctionCall)*JSListWorkspaces},
00580 {0,0,0}};
00581
00582 ScriptEnvironment Global;
00583 memset(&Global,0,sizeof(Global));
00584 Global.htmlout = self->htmlout;
00585 Global.Functions = Functions;
00586 Global.argv0 = self->argv0;
00587 Global.config = self->Config;
00588 if (script == NULL) return 1;
00589
00590 ret = RunScript(&Global,script,data?data:self->Config);
00591
00592 CGIFCLOSE(script);
00593 return ret;
00594 }
00595 return 0;
00596 }
00597
00598 int UserAdd(AdminInfo* self,char* user)
00599 {
00600 FILE *f;
00601 char fname[MAXPATH];
00602 CGINameValue* ini;
00603 struct stat info;
00604
00605 ExpandLocalPath(self->argv0,fname,"admin" "/", user);
00606 strcat(fname,".ini");
00607 if (!stat(fname,&info))
00608 return 0;
00609
00610 f = fopen(fname,"wt");
00611 if (f)
00612 {
00613 fwrite("[USER]\nACTIVE=0\n",1,7,f);
00614 fclose(f);
00615 return 1;
00616 }
00617 return 0;
00618 }
00619
00620 void UserUpdate(AdminInfo* self,char* user,char * fields,char* page)
00621 {
00622 FILE *f;
00623 char fname[MAXPATH];
00624 CGINameValue* ini;
00625 size_t x;
00626
00627 ExpandLocalPath(self->argv0,fname,"admin" "/", user);
00628 strcat(fname,".ini");
00629 ini = ReadINIFileSection(fname,"USER",16);
00630
00631 if (!ini)
00632 return;
00633
00634 for (x=0; self->Params[x].name; x++)
00635 {
00636 if (!*self->Params[x].name)
00637 continue;
00638
00639 if (HasTokenI(systemFields,self->Params[x].name,0))
00640 continue;
00641
00642 if (fields)
00643 if (!HasTokenI(fields,self->Params[x].name,0))
00644 continue;
00645
00646 SetFieldValue(ini,self->Params[x].name,self->Params[x].value);
00647 }
00648
00649 AdminRunScript(self,ini,page);
00650 if (!atoi(GetFieldValue(self->Params,"ERROR")))
00651 {
00652 WriteINIFileSection(fname,"USER",ini);
00653 }
00654
00655 DeleteNVP(ini);
00656 }
00657
00658 void UserAddSpace(AdminInfo* self,char* user,char * directory)
00659 {
00660 FILE *f;
00661 char fname[MAXPATH];
00662 CGINameValue* ini;
00663 char* x;
00664 ExpandLocalPath(self->argv0,fname,"admin" "/", user);
00665 strcat(fname,".ini");
00666 ini = ReadINIFileSection(fname,"USER",16);
00667
00668 if (!ini)
00669 return;
00670
00671 x = GetFieldValue(ini,"SPACES");
00672 x = strdup3(x,",",directory);
00673 SetFieldValue(ini,"SPACES",x);
00674 free(x);
00675
00676 WriteINIFileSection(fname,"USER",ini);
00677 DeleteNVP(ini);
00678 }
00679 void User(AdminInfo* self,char* user, char* page)
00680 {
00681 char fname[MAXPATH];
00682 CGINameValue* ini;
00683 FILE* source = OpenPage(self->argv0,page);
00684 if (!source) return;
00685
00686 ExpandLocalPath(self->argv0,fname,"admin" "/", user);
00687 strcat(fname,".ini");
00688 AdminPrintPage(self,fname,source);
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 }
00703
00704 int SpaceAdd(AdminInfo* self,char* directory, char* name, char* page)
00705 {
00706 FILE *f;
00707 char fname[MAXPATH];
00708 CGINameValue* ini;
00709 struct stat info;
00710 int ret = 0;
00711 char* pwd = GetFieldValue(self->Params,"PASSWORD");
00712 if (!*pwd)
00713 {
00714 FILE* source = OpenPage(self->argv0,page);
00715 if (source)
00716 {
00717 RunReportF(self->argv0,self->htmlout,source,self->Params,0,0,1,0,0,AdminFunctions);
00718 fclose(source);
00719 }
00720 return 2;
00721 }
00722
00723 directory = RelativeName(directory,name);
00724 ExpandLocalPath(self->argv0,fname,directory,"/" "cgi.ini");
00725
00726 if (stat(fname,&info))
00727 {
00728 mkdir(directory);
00729 f = fopen(fname,"wt");
00730 if (f)
00731 {
00732 fwrite("[admin]\nLOGLEVEL=0\nPASSWORD=\n",1,29,f);
00733 fclose(f);
00734 ret = 1;
00735 }
00736 }
00737 free(directory);
00738 return ret;
00739 }
00740
00741 void Space(AdminInfo* self,char* directory,char* page)
00742 {
00743 char fname[MAXPATH];
00744 FILE* source = OpenPage(self->argv0,page);
00745 if (!source) return;
00746
00747 if (!*directory) directory=".";
00748 ExpandLocalPath(self->argv0,fname,directory, "/" "cgi.ini");
00749
00750 AdminPrintPage(self,fname,source);
00751
00752 fclose(source);
00753 }
00754
00755 void SpaceUpdate(AdminInfo* self,char* directory,char * fields,char* page)
00756 {
00757 FILE *f;
00758 char fname[MAXPATH];
00759 CGINameValue* ini;
00760 char* pwd;
00761 size_t x;
00762 char* section=GetSetting(self->Params,"SECTION","admin");
00763
00764
00765 if (!*directory) directory=".";
00766 ExpandLocalPath(self->argv0,fname,directory, "/" "cgi.ini");
00767 ini = ReadINIFileSection(fname,section,16);
00768
00769 if (!ini)
00770 return;
00771
00772 for (x=0; self->Params[x].name; x++)
00773 {
00774 if (!*self->Params[x].name)
00775 continue;
00776
00777 if (HasTokenI(systemFields,self->Params[x].name,0))
00778 continue;
00779
00780 if (fields)
00781 if (!HasTokenI(fields,self->Params[x].name,0))
00782 continue;
00783
00784 SetFieldValue(ini,self->Params[x].name,self->Params[x].value);
00785 }
00786
00787 AdminRunScript(self,ini,page);
00788 if (!atoi(GetFieldValue(self->Params,"ERROR")))
00789 {
00790 WriteINIFileSection(fname,section,ini);
00791 }
00792
00793 DeleteNVP(ini);
00794 }
00795
00796 void Project(AdminInfo *self,char* directory,char* project)
00797 {
00798 char fname[MAXPATH+5];
00799 FILE* source = OpenPage(self->argv0,"project.html");
00800 char* name;
00801 if (!source) return;
00802
00803 name=RelativeName(directory,project);
00804 ExpandLocalPath(self->argv0,fname,name,".ini");
00805 free(name);
00806
00807 AdminPrintPage(self,fname,source);
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 fclose(source);
00818 }
00819
00820 int GetProjectExtra(AdminInfo* self,char* name)
00821 {
00822 char rName[MAXPATH];
00823 struct stat info;
00824 char* dbname = strdup(name);
00825 char* c = (char*)stristr(dbname,".ini");
00826 if (c)
00827 {
00828 char temp[32];
00829 *c =0;
00830 ExpandLocalPath(self->argv0,rName,dbname,".respcount");
00831 if (!stat(rName,&info))
00832 DoSetValue(self->Params,"LASTSAVEDATE",ctime(&info.st_mtime));
00833 sprintf(temp,"%d",GetRespcount(self->argv0,dbname));
00834 DoSetValue(self->Params,"RESPONSES",temp);
00835 }
00836 free(dbname);
00837 return (c != NULL);
00838 }
00839
00840 void Index(AdminInfo *self,char* directory)
00841 {
00842 DIR* d;
00843 struct stat info;
00844 char* name;
00845 CGINameValue* ini;
00846 char iniName[MAXPATH];
00847 int dirstart=-1,filestart=-1,footerstart=0;
00848
00849 FILE* source = OpenPage(self->argv0,"projects.html");
00850 if (!source) return;
00851
00852 RunReportF(self->argv0,self->htmlout,source,self->Params,0,0,1,"directory",0,AdminFunctions);
00853 dirstart = ftell(source);
00854 ReadUntilWordS(source,0,"<file>");
00855 filestart= ftell(source);
00856 ReadUntilWordS(source,0,"</file>");
00857 footerstart = ftell(source);
00858
00859 name = directory;
00860 if (!name || !*name) name = ".";
00861 d = opendir(name);
00862
00863 while (d)
00864 {
00865 struct dirent* f = readdir(d);
00866 if (!f) break;
00867 if (f->d_name[0] == '.') continue;
00868
00869 name = RelativeName(directory,f->d_name);
00870
00871 ExpandLocalPath(self->argv0,iniName,name,0);
00872 if (!stat(iniName,&info))
00873 {
00874 if (!(info.st_mode & S_IFREG) && dirstart > 0)
00875 {
00876 ExpandLocalPath(self->argv0,iniName,name,"/" "cgi.ini");
00877 ini = ReadINIFileSection(iniName,"admin",0);
00878 if (ini)
00879 {
00880 DoSetValue(self->Params, "NAME", name);
00881 fseek(source,dirstart,0);
00882 RunReportF(self->argv0,self->htmlout,source,ini,self->Params,0,1,"/directory",0,AdminFunctions);
00883 DeleteNVP(ini);
00884 }
00885 }
00886 else if (stristr(f->d_name,".ini") && filestart > 0)
00887 {
00888 ExpandLocalPath(self->argv0,iniName,name,0);
00889
00890 if (info.st_ctime)
00891 DoSetValue(self->Params,"CREATIONDATE",ctime(&info.st_ctime));
00892
00893 ini = ReadINIFileSection(iniName,"DATABASE",0);
00894 if (ini)
00895 {
00896 fseek(source,filestart,0);
00897 GetProjectExtra(self,name);
00898 name=strdup(f->d_name);
00899 *stristr(name,".ini") = 0;
00900 DoSetValue(self->Params, "NAME", name);
00901 RunReportF(self->argv0,self->htmlout,source,ini,self->Params,0,1,"/file",0,AdminFunctions);
00902 DeleteNVP(ini);
00903 }
00904 }
00905 }
00906 free(name);
00907 }
00908
00909 fseek(source,footerstart,0);
00910 RunReportF(self->argv0,self->htmlout,source,self->Params,0,0,0,0,0,AdminFunctions);
00911 fclose(source);
00912
00913 if (d) closedir(d);
00914 }
00915
00916 void UserList(AdminInfo *self)
00917 {
00918 DIR* d;
00919 struct stat info;
00920 char* name=0, *c;
00921 CGINameValue* ini;
00922 char iniName[MAXPATH];
00923 int pos;
00924
00925 FILE* source = OpenPage(self->argv0,"users.html");
00926
00927 if (!source)
00928 return;
00929
00930 RunReportF(self->argv0,self->htmlout,source,self->Params,0,0,1,"user",0,AdminFunctions);
00931 pos = ftell(source);
00932 d = opendir("admin");
00933
00934 while (d)
00935 {
00936 struct dirent* f = readdir(d);
00937 if (!f) break;
00938 if (f->d_name[0] == '.') continue;
00939
00940 if (stristr(f->d_name,".ini"))
00941 {
00942
00943 ExpandLocalPath(self->argv0,iniName,"admin" "/",f->d_name);
00944 ini = ReadINIFileSection(iniName,"USER",16);
00945 if (ini)
00946 {
00947 name = strdup(f->d_name);
00948 *stristr(name,".ini") = 0;
00949 DoSetValue(self->Params, "NAME", name);
00950
00951 if (!stat(iniName,&info))
00952 {
00953 if (info.st_ctime)
00954 DoSetValue(self->Params,"CREATIONDATE",ctime(&info.st_ctime));
00955 if (info.st_mtime)
00956 DoSetValue(self->Params,"LASTSAVEDATE",ctime(&info.st_mtime));
00957 }
00958
00959 RunReportF(self->argv0,self->htmlout,source,ini,self->Params,0,1,"/user",0,AdminFunctions);
00960 fseek(source,pos,0);
00961 DeleteNVP(ini);
00962 free(name);
00963 }
00964
00965 }
00966 }
00967 if (source)
00968 {
00969 ReadUntilWordS(source,0,"</user>");
00970 RunReportF(self->argv0,self->htmlout,source,self->Params,0,0,1,0,0,AdminFunctions);
00971 fclose(source);
00972 }
00973 if (d) closedir(d);
00974 }
00975
00976 int SendImage(AdminInfo *self,char* image)
00977 {
00978 char fname[MAXPATH];
00979 char header[1024];
00980 if (image[strcspn(image,"\\/")] || strstr(image,".."))
00981 return 0;
00982
00983 ExpandLocalPath(self->argv0,fname,"admin" "/",image);
00984
00985 if (stristr(image,".png"))
00986 SendCGIHeader(self->htmlout,"Content-Type: image/png\n\n");
00987 else if (stristr(image,".gif"))
00988 SendCGIHeader(self->htmlout,"Content-Type: image/gif\n\n");
00989 else if (stristr(image,".ico"))
00990 SendCGIHeader(self->htmlout,"Content-Type: image/x-icon\n\n");
00991 else
00992 return 0;
00993
00994 return HTMLWriteFile(self->htmlout,fname);
00995 }
00996
00997 int ShowAdmin(AdminInfo *self,char*name,char*page)
00998 {
00999
01000 if (!strnicmp(page,"USER",4))
01001 {
01002 int i = strcspn(name,"\\/.");
01003 if (name[i] || i > 32)
01004 return 4;
01005 }
01006
01007 if (!stricmp(page,"USER") && *name)
01008 {
01009 User(self,name,"user.html");
01010 return 3;
01011 }
01012
01013 if (!stricmp(page,"USERADD"))
01014 {
01015 if (UserAdd(self,name))
01016 {
01017 UserUpdate(self,name,0,0);
01018 User(self,name,"user.html");
01019 return 3;
01020 }
01021 }
01022 else if (!stricmp(page,"USERUPDATE"))
01023 {
01024 UserUpdate(self,name,0,"user.js");
01025 return 2;
01026 }
01027
01028 return 0;
01029 }
01030
01031
01038 int ShowPage(AdminInfo *self,char*directory,char*name,char*page)
01039 {
01040 char * user = GetFieldValue(self->Params,"USER");
01041 int i = strcspn(user,"\\/.");
01042 if (user[i] || i > 32)
01043 return 4;
01044
01045 if (!strnicmp(page,"PASSWORD",8))
01046 {
01047 if (!*user)
01048 return 4;
01049
01050 if (!stricmp(page,"PASSWORD"))
01051 {
01052 User(self,user,"password.html");
01053 return 3;
01054 }
01055 else if (!stricmp(page,"PASSWORDUPDATE"))
01056 {
01057 UserUpdate(self,user,"DISPLAY,PASSWORD,EMAIL","user.js");
01058 SetFieldValue(self->Params,"DIRECTORY",0);
01059 return 1;
01060 }
01061 }
01062
01063 if (!stricmp(page,"PROJECT") && *name)
01064 {
01065 Project(self,directory,name);
01066 return 3;
01067 }
01068 else if (!stricmp(page,"PROJECTUPDATE")&& *name)
01069 {
01070 ProjectUpdate(self,directory,name);
01071 return 1;
01072 }
01073 else if (!stricmp(page,"SPACE"))
01074 {
01075 Space(self,directory,"space.html");
01076 return 3;
01077 }
01078 else if (!stricmp(page,"SPACEADD"))
01079 {
01080 if (!strnicmp(directory,"admin",5))
01081 return 4;
01082
01083 switch (SpaceAdd(self,directory,name,"spaceadd.html"))
01084 {
01085 case 1:
01086 {
01087 char * c = RelativeName(directory,name);
01088 SetFieldValue(self->Params,"DIRECTORY",c);
01089 SpaceUpdate(self,c,"LOGLEVEL,PASSWORD,DISPLAY","space.js");
01090 Space(self,c,"space.html");
01091 if (*user)
01092 UserAddSpace(self,user,c);
01093 else
01094 SetFieldValue(self->Params,"AUTHENTICATION",GetFieldValue(self->Params,"PASSWORD"));
01095 free(c);
01096 }
01097 case 2: return 3;
01098 }
01099 }
01100 else if (!stricmp(page,"SPACEUPDATE"))
01101 {
01102 SpaceUpdate(self,directory,"LOGLEVEL,PASSWORD,DISPLAY","space.js");
01103 return 1;
01104 }
01105
01106
01107 return 0;
01108 }
01109
01110 void Error(AdminInfo* self)
01111 {
01112 HTMLWrite(self->htmlout,"<HTML><body><h1>Error</h1><hr><pre>");
01113 DebugShowNVP(self->htmlout,self->Params);
01114 }
01115
01116 int CGImain(char * argv0,CGINameValue* Params,STREAM htmlout)
01117 {
01118 char * directory = GetFieldValue(Params,"DIRECTORY");
01119 char * name = GetFieldValue(Params,"NAME");
01120 char * page = GetFieldValue(Params,"PAGE");
01121 char * image = GetFieldValue(Params,"IMAGE");
01122 char * cookie = GetEnvironment(htmlout,"HTTP_COOKIE");
01123 char fname[MAXPATH];
01124 int ret, r2;
01125 AdminInfo Self;
01126 Self.argv0 = argv0;
01127 Self.Config = 0;
01128 Self.Params = Params;
01129 Self.htmlout= htmlout;
01130
01131 if (strchr(name,'/') || strchr(name,'\\')
01132 || stristr(name,".ini") ||
01133 !stricmp(page,"LOGOUT"))
01134 {
01135 SendCGIHeader(htmlout,"Set-Cookie: USER=;\nSet-Cookie: SESSION=;\nSet-Cookie: PASSWORD=;\n" CGI_DEFAULT_HEADER);
01136 Self.Params = 0;
01137 Login(&Self);
01138 return 0;
01139 }
01140
01141 if (!strnicmp(page,"USER",4) && !*directory)
01142 directory = "admin";
01143
01144 if (*image)
01145 {
01146 SendImage(&Self,image);
01147 return 0;
01148 }
01149
01150 ExpandLocalPath(argv0,fname,"admin",SLASH "cgi.ini");
01151 Self.Config= ReadINIFileSection(fname,"admin",0);
01152
01153 ret = Authenticate(&Self,directory,&cookie);
01154 if (ret == 2 && !*page && !*directory)
01155 directory = GetFieldValue(Params,"DIRECTORY");
01156
01157 if (ret)
01158 {
01159 if (cookie)
01160 {
01161 char* header = strdup3(cookie, "\n", CGI_DEFAULT_HEADER);
01162 SendCGIHeader(htmlout,header);
01163 free(header);
01164 free(cookie);
01165 }
01166 else
01167 SendCGIHeader(htmlout,0);
01168 }
01169 else
01170 {
01171 if (*directory) SetFieldValue(Self.Params,"DIRECTORY",directory);
01172 SendCGIHeader(htmlout,0);
01173 Login(&Self);
01174 goto atexit;
01175 }
01176
01177
01178 ret = 0;
01179 r2 = 0;
01180 if (!stricmp(directory,"admin"))
01181 {
01182 ret = ShowAdmin(&Self,name,page);
01183 r2 = 2;
01184 }
01185
01186 if (!ret)
01187 {
01188 ret =ShowPage(&Self,directory,name,page);
01189 if (!ret) ret = r2;
01190 }
01191
01192 switch (ret)
01193 {
01194 case 0:
01195 case 1: Index(&Self,directory); break;
01196 case 2: UserList(&Self);
01197 case 3: break;
01198 default: Error(&Self);
01199 }
01200
01201 atexit:
01202 DeleteNVP(Self.Config);
01203 return 0;
01204 }
01205
01206
01207