[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/goahead/server/cgi.c b/ap/app/goahead/server/cgi.c
new file mode 100755
index 0000000..c9286c6
--- /dev/null
+++ b/ap/app/goahead/server/cgi.c
@@ -0,0 +1,311 @@
+#include "wsIntrn.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "uemf.h"
+
+static int cgiMax;
+typedef struct {
+ webs_t wp;
+ long fplacemark;
+ int handle;
+ char_t **envp;
+ char_t **argp;
+ char_t *cgiPath;
+ char_t *stdOut;
+ char_t *stdIn;
+} cgiRec;
+static cgiRec **cgiList;
+
+int websCgiProcess(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path, char_t* query)
+{
+
+ int n, envpsize, argpsize, pHandle, cid;
+ char_t *cp, *cgiName, *cgiPath, **argp, **envp, **ep;
+ char_t cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
+ sym_t *s;
+ cgiRec *cgip;
+ a_assert(path && *path == '/');
+ a_assert(url && *url);
+ a_assert(websValid(wp));
+ websStats.cgiHits++;
+ char *cgipath_temp = NULL;
+ gstrncpy(cgiBuf, path, TSZ(cgiBuf)-1);
+ cgipath_temp = gstrchr(&cgiBuf[1], '/');
+ if(cgipath_temp!=NULL)
+ {
+ cgipath_temp++;
+ }else
+ {
+ websError(wp, 200, T("cgiBuf error,check path"));
+
+ return 1;
+ }
+ printf("[goahead]cgipath_temp->%s.\n",cgipath_temp);
+ //if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
+ if ((cgiName = gstrchr(cgipath_temp, '/')) == NULL) {
+
+ if((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL)
+ {
+ websError(wp, 200, T("Missing CGI name"));
+
+ return 1;
+ }
+ }
+ cgiName++;
+ printf("[goahead]cgiName->%s.\n",cgiName);
+ if ((cp = gstrchr(cgiName, '/')) != NULL) {
+ *cp = '\0';
+ }
+ // fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
+ // CGI_BIN, cgiName);
+ fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s"),"/etc_ro/cgi-bin", cgiName);
+ {
+ gstat_t sbuf;
+ if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
+ websError(wp, 200, T("CGI process file does not exist"));
+ bfree(B_L, cgiPath);
+ return 1;
+ }
+ if (gaccess(cgiPath, X_OK) != 0) {
+ websError(wp, 200, T("CGI process file is not executable"));
+ bfree(B_L, cgiPath);
+ return 1;
+ }
+ }
+ ggetcwd(cwd, FNAMESIZE);
+ if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
+ *cp = '\0';
+ gchdir(cgiPath);
+ *cp = '/';
+ }
+ argpsize = 10;
+ argp = balloc(B_L, argpsize * sizeof(char_t *));
+ if(argp == NULL){
+ bfreeSafe(B_L, cgiPath);
+ return 1;
+ }
+ *argp = cgiPath;
+ n = 1;
+ if (gstrchr(query, '=') == NULL) {
+ websDecodeUrl(query, query, gstrlen(query));
+ for (cp = gstrtok(query, T(" ")); cp != NULL; ) {
+ *(argp+n) = cp;
+ n++;
+ if (n >= argpsize) {
+ argpsize *= 2;
+ argp = brealloc(B_L, argp, argpsize * sizeof(char_t *));
+ if(argp == NULL){
+ bfreeSafe(B_L, cgiPath);
+ return 1;
+ }
+ }
+ cp = gstrtok(NULL, T(" "));
+ }
+ }
+ *(argp+n) = NULL;
+ envpsize = WEBS_SYM_INIT;
+ envp = balloc(B_L, envpsize * sizeof(char_t *));
+ if(envp == NULL){
+ bfreeSafe(B_L, cgiPath);
+ bfreeSafe(B_L, argp);
+ return 1;
+ }
+ n = 0;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("PATH_TRANSLATED"), cgiPath);
+ n++;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s/%s"),T("SCRIPT_NAME"),
+ CGI_BIN, cgiName);
+ n++;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("REMOTE_USER"), wp->userName);
+ n++;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("AUTH_TYPE"), wp->authType);
+ n++;
+ for (s = symFirst(wp->cgiVars); s != NULL; s = symNext(wp->cgiVars)) {
+ if (s->content.valid && s->content.type == string &&
+ gstrcmp(s->name.value.string, T("REMOTE_HOST")) != 0 &&
+ gstrcmp(s->name.value.string, T("HTTP_AUTHORIZATION")) != 0) {
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), s->name.value.string,
+ s->content.value.string);
+ n++;
+ if (n >= envpsize) {
+ envpsize *= 2;
+ envp = brealloc(B_L, envp, envpsize * sizeof(char_t *));
+ if(envp == NULL){
+ bfreeSafe(B_L, cgiPath);
+ bfreeSafe(B_L, argp);
+ return 1;
+ }
+ }
+ }
+ }
+ if (wp->flags & WEBS_CGI_UPLOAD)
+ {
+
+ if((wp->has_firmware_upload_clean)||(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD))
+ {
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), FIRMWARE_TMP_FILE);
+ }
+ else
+ {
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), wp->cgiStdin);
+ }
+ n++;
+ }
+ *(envp+n) = NULL;
+ if (wp->cgiStdin == NULL) {
+ wp->cgiStdin = websGetCgiCommName(wp);
+ }
+ stdIn = wp->cgiStdin;
+ stdOut = websGetCgiCommName(wp);
+ printf("[goahead]cgiPath->%s.\n",cgiPath);
+
+ if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut))
+ == -1) {
+ websError(wp, 200, T("failed to spawn CGI task"));
+ for (ep = envp; *ep != NULL; ep++) {
+ bfreeSafe(B_L, *ep);
+ }
+ bfreeSafe(B_L, cgiPath);
+ bfreeSafe(B_L, argp);
+ bfreeSafe(B_L, envp);
+ bfreeSafe(B_L, stdOut);
+ } else {
+ cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
+ if(cgiList){
+ cgip = cgiList[cid];
+ cgip->handle = pHandle;
+ cgip->stdIn = stdIn;
+ cgip->stdOut = stdOut;
+ cgip->cgiPath = cgiPath;
+ cgip->argp = argp;
+ cgip->envp = envp;
+ cgip->wp = wp;
+ cgip->fplacemark = 0;
+ websTimeoutCancel(wp);
+ }
+ else
+ {
+ bfreeSafe(B_L, cgiPath);
+ bfreeSafe(B_L, argp);
+ bfreeSafe(B_L, envp);
+ bfreeSafe(B_L, stdOut);
+ }
+ }
+ gchdir(cwd);
+ return 1;
+
+}
+
+int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path, char_t* query)
+{
+ if(!(wp->flags & WEBS_POST_REQUEST))
+ {
+ //websError(wp, 200, T("NOT POST REQUEST"));
+ printf("[goahead]NOT POST REQUEST.\n");
+ websDone(wp, 0);
+ return 1;
+ }
+
+ if (wp->flags & WEBS_CGI_HTTPSHARE_UPLOAD)
+ {
+ printf("[httpshare]call zte_process_cgi_end.\n");
+ return zte_process_cgi_end(wp);
+ }else if(wp->flags & WEBS_CGI_UPLOAD)
+ {
+ printf("[goahead]call upload cgi.\n");
+ return websCgiProcess(wp, urlPrefix, webDir, arg,url, path, query);
+ }else
+ {
+ //websError(wp, 200, T("NOT CGI OR HTTPSHARE,RETURN ERROR"));
+ printf("[goahead]wrong cgi request.\n");
+ websDone(wp, 0);
+ return 1;
+ }
+
+}
+
+void websCgiGatherOutput (cgiRec *cgip)
+{
+ gstat_t sbuf;
+ char_t cgiBuf[FNAMESIZE];
+ if ((gstat(cgip->stdOut, &sbuf) == 0) &&
+ (sbuf.st_size > cgip->fplacemark)) {
+ int fdout;
+ fdout = gopen(cgip->stdOut, O_RDONLY | O_BINARY, 0444 );
+ if (fdout >= 0) {
+ webs_t wp = cgip->wp;
+ int nRead;
+ int rc;
+ if (cgip->fplacemark == 0) {
+ websWrite(wp, T("HTTP/1.0 200 OK\n"));
+ }
+ if(glseek(fdout, cgip->fplacemark, SEEK_SET) < 0)
+ {
+ printf("[goahead]glseek fail.\n");
+ }
+ while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
+ rc = websWriteBlock(wp, cgiBuf, nRead);
+ if (rc < 0) {
+ //todo: cov m
+ }
+ cgip->fplacemark += nRead;
+ }
+ gclose(fdout);
+ }
+ }
+}
+
+void websCgiCleanup()
+{
+ cgiRec *cgip;
+ webs_t wp;
+ char_t **ep;
+ int cid, nTries;
+ for (cid = 0; cid < cgiMax; cid++) {
+ if ((cgip = cgiList[cid]) != NULL) {
+ int exit_status;
+ wp = cgip->wp;
+ websCgiGatherOutput (cgip);
+ if ( websCheckCgiProc(cgip->handle, &exit_status) == 0) {
+ nTries = 0;
+ while ((cgip->fplacemark == 0) && (nTries < 100)) {
+ websCgiGatherOutput(cgip);
+ if (cgip->fplacemark == 0) {
+ }
+ nTries++;
+ }
+ gunlink(cgip->stdIn);
+ gunlink(cgip->stdOut);
+ cgiMax = hFree((void***) &cgiList, cid);
+ for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) {
+ bfreeSafe(B_L, *ep);
+ }
+ bfreeSafe(B_L, cgip->cgiPath);
+ bfreeSafe(B_L, cgip->argp);
+ bfreeSafe(B_L, cgip->envp);
+ bfreeSafe(B_L, cgip->stdOut);
+ bfreeSafe(B_L, cgip);
+ if(wp->has_firmware_upload_clean){
+ if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) != 0) {
+ if (cgip->fplacemark == 0) { //cov h
+ websError(wp, 200, T("CGI generated no output"));
+ } else {
+ websDone(wp, 200);
+ }
+ return;
+ }
+ sync();
+ //doSystem("sleep 3 && reboot &");
+ }
+ if (cgip->fplacemark == 0) { //cov h
+ websError(wp, 200, T("CGI generated no output"));
+ } else {
+ websDone(wp, 200);
+ }
+ }
+ }
+ }
+}
+