Exemple #1
0
static int crack(char_t *buf, char_t **key, char_t **val)
{
    char_t	*ptr;

    if ((ptr = gstrrchr(buf, '\n')) != NULL ||
            (ptr = gstrrchr(buf, '\r')) != NULL) {
        *ptr = '\0';
    }

    /*
     *	Find the = sign. It must exist.
     */
    if ((ptr = gstrstr(buf, T("="))) == NULL) {
        return -1;
    }

    *ptr++ = '\0';
    *key = trim(buf);
    *val = trim(ptr);

    return 0;
}
Exemple #2
0
/*
 *	Process a form request. Returns 1 always to indicate it handled the URL
 */
int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 
		char_t *url, char_t *path, char_t* query)
{
	cgiRec		*cgip;
	sym_t		*s;
	char_t		cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
	char_t		*cp, *cgiName, *cgiPath, **argp, **envp, **ep;
	int			n, envpsize, argpsize, pHandle, cid;
	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path && *path == '/');
	websStats.cgiHits++;
/*
 *	Extract the form name and then build the full path name.  The form
 *	name will follow the first '/' in path.
 */
	gstrncpy(cgiBuf, path, TSZ(cgiBuf));
	if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
		websError(wp, 200, T("Missing CGI name"));
		return 1;
	}
	cgiName++;
	if ((cp = gstrchr(cgiName, '/')) != NULL) {
		*cp = '\0';
	}
	fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
		CGI_BIN, cgiName);
#ifndef VXWORKS
/*
 *	See if the file exists and is executable.  If not error out.
 *	Don't do this step for VxWorks, since the module may already
 *	be part of the OS image, rather than in the file system.
 */
	{
		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 (defined (WIN) || defined (CE))
		if (gstrstr(cgiPath, T(".exe")) == NULL &&
			gstrstr(cgiPath, T(".bat")) == NULL) {
#elif (defined (NW))
			if (gstrstr(cgiPath, T(".nlm")) == NULL) {
#else
		if (gaccess(cgiPath, X_OK) != 0) {
#endif /* WIN || CE */
			websError(wp, 200, T("CGI process file is not executable"));
			bfree(B_L, cgiPath);
			return 1;
		}
	}
#endif /* ! VXWORKS */

         
/*
 *	Get the CWD for resetting after launching the child process CGI
 */
	ggetcwd(cwd, FNAMESIZE);
/*
 *	Retrieve the directory of the child process CGI
 */
	if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
		*cp = '\0';
		gchdir(cgiPath);
		*cp = '/';
	}

/*
 *	Build command line arguments.  Only used if there is no non-encoded
 *	= character.  This is indicative of a ISINDEX query.  POST separators
 *	are & and others are +.  argp will point to a balloc'd array of 
 *	pointers.  Each pointer will point to substring within the
 *	query string.  This array of string pointers is how the spawn or 
 *	exec routines expect command line arguments to be passed.  Since 
 *	we don't know ahead of time how many individual items there are in
 *	the query string, the for loop includes logic to grow the array 
 *	size via brealloc.
 */

	argpsize = 10;
	argp = balloc(B_L, argpsize * sizeof(char_t *));
	*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 *));

			}
			cp = gstrtok(NULL, T(" "));

		}
	}
	*(argp+n) = NULL;

/*
 *	Add all CGI variables to the environment strings to be passed
 *	to the spawned CGI process.  This includes a few we don't 
 *	already have in the symbol table, plus all those that are in
 *	the cgiVars symbol table.  envp will point to a balloc'd array of 
 *	pointers.  Each pointer will point to a balloc'd string containing
 *	the keyword value pair in the form keyword=value.  Since we don't
 *	know ahead of time how many environment strings there will be the
 *	for loop includes logic to grow the array size via brealloc.
 */

	envpsize = WEBS_SYM_INIT;
	envp = balloc(B_L, envpsize * sizeof(char_t *));
	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 (wp->flags & WEBS_CGI_UPLOAD){
		// set filename into enviornment variables 
		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), wp->cgiStdin);
		n++;
	}


	*(envp+n) = NULL;
/*
 *	Create temporary file name(s) for the child's stdin and stdout.
 *	For POST data the stdin temp file (and name) should already exist.
 */

	if (wp->cgiStdin == NULL) {
		wp->cgiStdin = websGetCgiCommName(wp);
	} 
	stdIn = wp->cgiStdin;
	stdOut = websGetCgiCommName(wp);

/*
 *	Now launch the process.  If not successful, do the cleanup of resources.
 *	If successful, the cleanup will be done after the process completes.
 */
	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 {
/*
 *		If the spawn was successful, put this wp on a queue to be
 *		checked for completion.
 */
		cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
		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);
	}
/*
 *	Restore the current working directory after spawning child CGI
 */
 	gchdir(cwd);
	return 1;
}



/******************************************************************************/
/*
 *	Any entry in the cgiList need to be checked to see if it has
 */
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 );
/*
 *		Check to see if any data is available in the
 *		output file and send its contents to the socket.
 */
		if (fdout >= 0) {
			webs_t	wp = cgip->wp;
			int		nRead;
/*
 *			Write the HTTP header on our first pass
 */
			if (cgip->fplacemark == 0) {
				websWrite(wp, T("HTTP/1.0 200 OK\r\n"));
			}
			glseek(fdout, cgip->fplacemark, SEEK_SET);
			while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
				websWriteBlock(wp, cgiBuf, nRead);
				cgip->fplacemark += nRead;
			}
			gclose(fdout);
		}
	}
}


/******************************************************************************/
/*
 *	Any entry in the cgiList need to be checked to see if it has
 *	completed, and if so, process its output and clean up.
 */
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) {
/*
 *				We get here if the CGI process has terminated.  Clean up.
 */
				nTries = 0;
/*				
 *				Make sure we didn't miss something during a task switch.
 *				Maximum wait is 100 times 10 msecs (1 second).
 */
				while ((cgip->fplacemark == 0) && (nTries < 100)) {
					websCgiGatherOutput(cgip);
/*					
 *					There are some cases when we detect app exit 
 *					before the file is ready. 
 */
					if (cgip->fplacemark == 0) {
#ifdef WIN
						Sleep(10);
#endif /* WIN*/
					}
					nTries++;
				}
				if (cgip->fplacemark == 0) {
					websError(wp, 200, T("CGI generated no output"));
				} else {
					websDone(wp, 200);
				}
/*
 *				Remove the temporary re-direction files
 */
				gunlink(cgip->stdIn);
				gunlink(cgip->stdOut);
/*
 *				Free all the memory buffers pointed to by cgip.
 *				The stdin file name (wp->cgiStdin) gets freed as
 *				part of websFree().
 */
				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 0 //DAVIDM - we do not want this, netflash does it for us
				if(wp->has_firmware_upload_clean){
					if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) != 0)
						return;
					sync();
					doSystem("sleep 3 && reboot &");
				}
#endif
			}
		}
	}
}
Exemple #3
0
int websAspRequest(webs_t wp, char_t *lpath)
{
	websStatType	sbuf;
	char			*rbuf;
	char_t			*token, *lang, *result, *path, *ep, *cp, *buf, *nextp;
	char_t			*last;
	int				rc, engine, len, ejid;

	a_assert(websValid(wp));
	a_assert(lpath && *lpath);

	rc = -1;
	buf = NULL;
	rbuf = NULL;
	engine = EMF_SCRIPT_EJSCRIPT;
	wp->flags |= WEBS_HEADER_DONE;
	path = websGetRequestPath(wp);

/*
 *	Create Ejscript instance in case it is needed
 */
	ejid = ejOpenEngine(wp->cgiVars, websAspFunctions);
	if (ejid < 0) {
		websError(wp, 200, T("Can't create Ejscript engine"));
		goto done;
	}
	ejSetUserHandle(ejid, (int) wp);

	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
		websError(wp, 200, T("Can't stat %s"), lpath);
		goto done;
	}

/*
 *	Create a buffer to hold the ASP file in-memory
 */
	len = sbuf.size * sizeof(char);
	if ((rbuf = balloc(B_L, len + 1)) == NULL) {
		websError(wp, 200, T("Can't get memory"));
		goto done;
	}
	rbuf[len] = '\0';

	if (websPageReadData(wp, rbuf, len) != len) {
		websError(wp, 200, T("Cant read %s"), lpath);
		goto done;
	}
	websPageClose(wp);

/*
 *	Convert to UNICODE if necessary.
 */
	if ((buf = ballocAscToUni(rbuf, len)) == NULL) {
		websError(wp, 200, T("Can't get memory"));
		goto done;
	}

/*
 *	Scan for the next "<%"
 */
	last = buf;
	rc = 0;
	while (rc == 0 && *last && ((nextp = gstrstr(last, T("<%"))) != NULL)) {
		websWriteBlock(wp, last, (nextp - last));
		nextp = skipWhite(nextp + 2);

/*
 *		Decode the language
 */
		token = T("language");

		if ((lang = strtokcmp(nextp, token)) != NULL) {
			if ((cp = strtokcmp(lang, T("=javascript"))) != NULL) {
				engine = EMF_SCRIPT_EJSCRIPT;
			} else {
				cp = nextp;
			}
			nextp = cp;
		}

/*
 *		Find tailing bracket and then evaluate the script
 */
		if ((ep = gstrstr(nextp, T("%>"))) != NULL) {

			*ep = '\0';
			last = ep + 2;
			nextp = skipWhite(nextp);
/*
 *			Handle backquoted newlines
 */
			for (cp = nextp; *cp; ) {
				if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) {
					*cp++ = ' ';
					while (*cp == '\r' || *cp == '\n') {
						*cp++ = ' ';
					}
				} else {
					cp++;
				}
			}

/*
 *			Now call the relevant script engine. Output is done directly
 *			by the ASP script procedure by calling websWrite()
 */
			if (*nextp) {
				result = NULL;
				if (engine == EMF_SCRIPT_EJSCRIPT) {
					rc = scriptEval(engine, nextp, &result, ejid);
				} else {
					rc = scriptEval(engine, nextp, &result, (int) wp);
				}
				if (rc < 0) {
/*
 *					On an error, discard all output accumulated so far
 *					and store the error in the result buffer. Be careful if the
 *					user has called websError() already.
 */
					if (websValid(wp)) {
						if (result) {
							websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"), 
								result);
							websWrite(wp, T("<pre>%s</pre>"), nextp);
							bfree(B_L, result);
						} else {
							websWrite(wp, T("<h2><b>ASP Error</b></h2>\n%s\n"),
								nextp);
						}
						websWrite(wp, T("</body></html>\n"));
						rc = 0;
					}
					goto done;
				}
			}

		} else {
			websError(wp, 200, T("Unterminated script in %s: \n"), lpath);
			rc = -1;
			goto done;
		}
	}
/*
 *	Output any trailing HTML page text
 */
	if (last && *last && rc == 0) {
		websWriteBlock(wp, last, gstrlen(last));
	}
	rc = 0;

/*
 *	Common exit and cleanup
 */
done:
	if (websValid(wp)) {
		websPageClose(wp);
		if (ejid >= 0) {
			ejCloseEngine(ejid);
		}
	}
	bfreeSafe(B_L, buf);
	bfreeSafe(B_L, rbuf);
	return rc;
}