// WFM HTML Dialog Routines #include "wfm.h" // // Prompt for delete / move operation // void multiprompt_ui(char *m_action) { int i; int res; int level; char **responses; struct stat fileinfo; char M_action[64]={0}; res=cgiFormStringMultiple("multiselect_filename", &responses); // pre-check for filenames so, that if there is an error, HTML is not yet out, allowing error dialog to be rendered if(res == cgiFormNotFound) { checkfilename(NULL); } else { for(i=0; responses[i]; i++) checkfilename(responses[i]); } cgiHeaderContentType("text/html"); snprintf(M_action, sizeof(M_action), "%c%s Confirmation", toupper(m_action[0]), m_action+1); html_title(M_action); fprintf(cgiOut, "\n" "\n" "\n" "
\n" "
\n\n", cgiScriptName); fprintf(cgiOut, "\n" " \n" " \n" " \n" "
  %s
 \n" "  
\n" " About to %s following items:

    \n", M_action, m_action); if(res == cgiFormNotFound) { checkfilename(NULL); if(stat(wp.phys_filename, &fileinfo)==0) { fprintf(cgiOut, "\n", wp.virt_filename); fprintf(cgiOut, "
  • %s", wp.virt_filename); if(S_ISDIR(fileinfo.st_mode)) fprintf(cgiOut, " [directory %s]\n", buprintf(du(wp.phys_filename), FALSE)); else fprintf(cgiOut, " [file %s]\n", buprintf(fileinfo.st_size, FALSE)); } } else { for(i=0; responses[i]; i++) { checkfilename(responses[i]); if(stat(wp.phys_filename, &fileinfo)==0) { fprintf(cgiOut, "\n", wp.virt_filename); fprintf(cgiOut, "
  • %s", wp.virt_filename); if(S_ISDIR(fileinfo.st_mode)) fprintf(cgiOut, "/ [directory %s]\n", buprintf(du(wp.phys_filename), FALSE)); else fprintf(cgiOut, " [file %s]\n", buprintf(fileinfo.st_size, FALSE)); } } } fprintf(cgiOut, "
"); // move needs a destination... if(strcmp(m_action, "move")==0) { fprintf(cgiOut, "

Source: %s

Destination: \n\n

\n"); } fprintf(cgiOut, "

\n" "

\n" " \n" " \n" " \n" " \n" " \n" "

\n" "
\n\n" "
\n" "\n\n", m_action, wp.virt_dirname, rt.token); cgiStringArrayFree(responses); } // // Single Prompt // Used for rename, mkfile, mkdir // void singleprompt_ui(char *m_action) { char M_action[64]={0}; snprintf(M_action, sizeof(M_action), "%c%s", toupper(m_action[0]), m_action+1); if(strcmp(m_action, "move")==0) { checkfilename(NULL); snprintf(M_action, sizeof(M_action), "Rename"); } cgiHeaderContentType("text/html"); html_title(M_action); fprintf(cgiOut, "\n" "\n" "\n" "
\n" "
\n\n" "\n" " \n" " \n" " \n" "
  %s
 \n" "  
\n", (rt.js) ? "ONLOAD=\"document.wfm.inp1.focus();\"" : "", cgiScriptName, M_action); if(strcmp(m_action, "move")==0) fprintf(cgiOut, " Current Name: %s

\n" " Enter new name:

\n" " \n" " \n", wp.virt_filename, wp.virt_filename, wp.virt_filename); else if(strcmp(m_action, "mkfile")==0) fprintf(cgiOut, " Enter name of the new text file:

\n" " \n"); else if(strcmp(m_action, "mkdir")==0) fprintf(cgiOut, "  
Enter name of the new directory:

\n" " \n"); else if(strcmp(m_action, "mkurl")==0) fprintf(cgiOut, "  
Name of the shortcut file:

\n" " \n" "

\n" "  
The shortcut URL:

\n" " \n"); fprintf(cgiOut, "

\n" "

\n" " \n" " \n" " \n" " \n" " \n" "

\n" "
\n\n" "
\n" "\n\n", m_action, wp.virt_dirname, rt.token); } // // Error message - note that strerror() is already passed by the caller // void error(char *msg, ...) { va_list ap; char buff[1024]={0}; if(msg) { va_start(ap, msg); vsnprintf(buff, sizeof(buff), msg, ap); va_end(ap); cgiHeaderContentType("text/html"); html_title("ERROR"); fprintf(cgiOut, "\n"\ "\n"\ "
\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "
\n" " ERROR:\n" "
\n" " 
\n" "
\n" " 
\n" "%s
\n" " 

\n" " 

\n" "

\n" " \n" "
\n" "
\n" "\n" "\n" "\n" "
\n
 
\n" "
\n\n", buff, cgiScriptName, wp.virt_dirname, rt.token); } else { cgiHeaderContentType("text/plain"); fprintf(cgiOut, "FATAL ERROR\n"); } exit(0); } // // About message // void about(void) { struct utsname ut; memset(&ut, 0, sizeof(ut)); uname(&ut); cgiHeaderContentType("text/html"); html_title("About"); fprintf(cgiOut, "\n" "\n" "
\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "
\n" "\"wfm About: %s\n" "
\n" " 
\n" "
\n" " 
\n" "WFM Implemented by Antoni Sawicki
\n" "CGIC Library by Thomas Boutell
\n" "Server Side RFC 1321 implementation by L. Peter Deutsch
\n" "Client Side RFC 1321 implementation by Paul Johnston
\n" "Icons by Yusuke Kamiyamane
\n" #ifdef WFMGIT "Uses libgit2 library
\n" #endif "URL Encoding routines by Fred Bulback
\n" "Copyright © 1994-2018 by Antoni Sawicki
\n" "Copyright © 2018-2019 by Google LLC
\n" "Copyright © 1996-2011 by Thomas Boutell and Boutell.Com, Inc.
\n" "Copyright © 2002 by Aladdin Enterprises
\n" "Copyright © 1999-2009 by Paul Johnston
\n" "Copyright © 2010 by Yusuke Kamiyamane
\n" "
\n" "WFM: %s (build %s / %s)
\n" "GCC: %s
\n" "Server: %s
\n" "OS: %s %s %s %s %s
\n" "NAME_MAX: %d
\n" "PATH_MAX: %d
\n" #ifdef CGIMAXTEMPFILESIZE "Max Temp File Size: "STRINGIFY(CGIMAXTEMPFILESIZE)"
\n" #endif "User Agent: %s
\n" "JavaScript Level: %d
\n" "Auth: %d
\n" "Change Control: %s (%s)
\n" " 

\n" " 

\n" "

\n" " \n" "
\n" "
\n" "\n" "\n" "\n" "
\n
 
\n" "
\n\n", rt.iconsurl, cfg.tagline, VERSION, __DATE__, __TIME__, __VERSION__, cgiServerSoftware, ut.sysname, ut.nodename, ut.release, ut.version, ut.machine, NAME_MAX, PATH_MAX, cgiUserAgent, rt.js, rt.auth_method, #ifdef WFMGIT "Git" #else "None" #endif , (repo_check()) ? "No Repo Present" : "Repo OK", cgiScriptName, wp.virt_dirname, rt.token); } // // Prompt for username and password // void login_ui(void) { cgiHeaderContentType("text/html"); html_title("Login"); if(rt.js>=2) fputs( "\n", cgiOut); fputs("\n", cgiOut); if(rt.js>=2) fputs("\n", cgiOut); else fputs("\n", cgiOut); fprintf(cgiOut, "
\n" "
\n" "\n" " \n" " \n" " \n" "
  Authentication Required
 \n" "  
Enter your login credentials:

\n" " \n" " \n" " \n" "
Username:
Password:

\n" "

\n" "

\n" " \n" " \n" " =2) fprintf(cgiOut, "onClick=\"self.location='%s?directory=%s&login=client&token=' + hex_md5('%s:' + hex_md5(document.wfm.username.value + ':' + document.wfm.password.value)); return false;\"", cgiScriptName, wp.virt_dirname_urlencoded, cgiRemoteAddr); fputs( ">\n" "

\n" "
\n\n" "
\n" "\n\n", cgiOut); } // // Text Area File Editor // void edit_ui(void) { FILE *input; char *buff; char backup[4]={0}; #ifndef WFMGIT char *bkcolor; #endif int size; checkfilename(NULL); #ifndef WFMGIT cgiFormString("backup", backup, sizeof(backup)); if(strcmp("yes", backup)==0) bkcolor="background-color:#404040; color:#FFFFFF;"; else bkcolor="background-color:#EEEEEE; color:#000000;"; #endif input=fopen(wp.phys_filename, "r"); if(input==NULL) error("Unable to open file.
%s", strerror(errno)); fseek(input, 0, SEEK_END); size=ftell(input); fseek(input, 0, SEEK_SET); if(size>=5*1024*1024) error("The file is too large for online editing.
"); buff=(char *) malloc(size+1); if(buff==NULL) error("Unable to allocate memory."); memset(buff, 0, size+1); fread(buff, size, 1, input); fclose(input); cgiHeaderContentType("text/html"); html_title("Editor"); if (rt.js) fprintf(cgiOut, "\n"); fprintf(cgiOut, "\n" "\n" "\n" "
\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "
\n" "\"EDIT\"\n" "File Editor: %s\n" "", cgiScriptName, (strncmp(cgiUserAgent, "Mozilla/4.0 (compatible; MSIE 6", 31)==0) ? "80" : "100", rt.iconsurl, wp.virt_filename); #ifndef WFMGIT if(rt.js) fprintf(cgiOut, " \n", bkcolor); #else fprintf(cgiOut, "%s\n", (repo_check()) ? "No GIT Repo Present" : "GIT Backed    "); #endif if(rt.js) fprintf(cgiOut, "\n"); fprintf(cgiOut, "
\n" "\n" "
\n" "\n" "\n" "
\n" "\n" "\n" "\n" "\n" "\n" "
\n", wp.virt_filename, wp.virt_dirname, rt.token, backup); free(buff); }