summaryrefslogtreecommitdiffstats
path: root/c/src/libnetworking/rtems_webserver/cgi.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/libnetworking/rtems_webserver/cgi.c')
-rw-r--r--c/src/libnetworking/rtems_webserver/cgi.c331
1 files changed, 0 insertions, 331 deletions
diff --git a/c/src/libnetworking/rtems_webserver/cgi.c b/c/src/libnetworking/rtems_webserver/cgi.c
deleted file mode 100644
index c2328eab6e..0000000000
--- a/c/src/libnetworking/rtems_webserver/cgi.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * cgi.c -- CGI processing (for the GoAhead Web server
- *
- * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
- *
- * See the file "license.txt" for usage and redistribution license requirements
- *
- * $Id$
- */
-
-/********************************** Description *******************************/
-/*
- * This module implements the /cgi-bin handler. CGI processing differs from
- * goforms processing in that each CGI request is executed as a separate
- * process, rather than within the webserver process. For each CGI request the
- * environment of the new process must be set to include all the CGI variables
- * and its standard input and output must be directed to the socket. This
- * is done using temporary files.
- */
-
-/*********************************** Includes *********************************/
-#include "wsIntrn.h"
-#ifdef UEMF
- #include "uemf.h"
-#else
- #include "basic/basicInternal.h"
-#endif
-
-/************************************ Locals **********************************/
-typedef struct { /* Struct for CGI tasks which have completed */
- webs_t wp; /* pointer to session websRec */
- char_t *stdIn; /* file desc. for task's temp input fd */
- char_t *stdOut; /* file desc. for task's temp output fd */
- char_t *cgiPath; /* path to executable process file */
- char_t **argp; /* pointer to buf containing argv tokens */
- char_t **envp; /* pointer to array of environment strings */
- int handle; /* process handle of the task */
- long fplacemark; /* seek location for CGI output file */
-} cgiRec;
-static cgiRec **cgiList; /* hAlloc chain list of wp's to be closed */
-static int cgiMax; /* Size of hAlloc list */
-
-/************************************* Code ***********************************/
-
-/*
- * 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 *));
- }
- }
- }
- *(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();
- }
- stdIn = wp->cgiStdin;
- stdOut = websGetCgiCommName();
-/*
- * 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) {
- wp = cgip->wp;
- websCgiGatherOutput (cgip);
- if (websCheckCgiProc(cgip->handle) == 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);
- }
- }
- }
-}
-/******************************************************************************/