⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lycgi.c

📁 基于rtos开发的浏览器!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                   Lynx CGI support                              LYCgi.c**                   ================**** Authors**          GL      George Lindholm <George.Lindholm@ubc.ca>**** History**      15 Jun 95   Created as way to provide a lynx based service with**                  dynamic pages without the need for a http daemon. GL**      27 Jun 95   Added <index> (command line) support. Various cleanup**                  and bug fixes. GL**	04 Sep 97   Added support for PATH_INFO scripts.  JKT**** Bugs**      If the called scripts aborts before sending the mime headers then**      lynx hangs.****      Should do something about SIGPIPE, (but then it should never happen)****      No support for redirection. Or mime-types.****      Should try and parse for a HTTP 1.1 header in case we are "calling" a**      nph- script.*/ #include "HTUtils.h"#include "tcp.h"#include "HTTP.h"#include "HTParse.h"#include "HTTCP.h"#include "HTFormat.h"#include "HTFile.h"#include "HTAlert.h"#include "HTMIME.h"#include "HTAABrow.h"#include "LYGlobalDefs.h"#include "LYUtils.h"#include "HTML.h"#include "HTInit.h"#include "LYGetFile.h"#include "LYBookmark.h"#include "GridText.h"#include <ctype.h>#include "LYCgi.h"#include "LYSignal.h"#include "LYLocal.h"#include "LYLeaks.h"#define FREE(x) if (x) {free(x); x = NULL;}struct _HTStream {  HTStreamClass * isa;};PRIVATE char **env = NULL;  /* Environment variables */PRIVATE int envc_size = 0;  /* Slots in environment array */PRIVATE int envc = 0;	    /* Slots used so far */#ifdef LYNXCGI_LINKSPRIVATE char user_agent[64];PRIVATE char server_software[64];#endif /* LYNXCGI_LINKS */PRIVATE void add_environment_value PARAMS((char *env_value));/* * Simple routine for expanding the environment array and adding a value to * it */PRIVATE void add_environment_value ARGS1(	char *,	env_value){    if (envc == envc_size) {   /* Need some more slots */	envc_size += 10;	if (env)	    env = (char **)realloc(env,				   sizeof(env[0]) * (envc_size + 2));						/* + terminator and base 0 */	else	    env = (char **)malloc(sizeof(env[0]) * (envc_size + 2));						/* + terminator and base 0 */	if (env == NULL) {	    outofmem(__FILE__, "LYCgi");	}    }    env[envc++] = env_value;    env[envc] = NULL;      /* Make sure it is always properly terminated */}    /* * Add the value of an existing environment variable to those passed on to the * lynxcgi script. */PUBLIC void add_lynxcgi_environment ARGS1(	CONST char *,	variable_name){    char *env_value;    env_value = getenv(variable_name);    if (env_value != NULL) {	char *add_value = NULL;	add_value = (char *)malloc(strlen(variable_name) +				   strlen(env_value) + 2);	if (add_value == NULL) {	    outofmem(__FILE__, "LYCgi");	}	strcpy(add_value, variable_name);	strcat(add_value, "=");	strcat(add_value, env_value);	add_environment_value(add_value);    }}PRIVATE int LYLoadCGI ARGS4(	CONST char *, 		arg,	HTParentAnchor *,	anAnchor,	HTFormat,		format_out,	HTStream*,		sink){    int status;#ifdef LYNXCGI_LINKS#ifndef VMS    char *cp;    struct stat stat_buf;    char *pgm = NULL;		        /* executable */    char *pgm_args = NULL;	        /* and its argument(s) */    int statrv;    char *orig_pgm = NULL;		/* Path up to ? as given, URL-escaped*/    char *document_root = NULL;		/* Corrected value of DOCUMENT_ROOT  */    char *path_info = NULL;             /* PATH_INFO extracted from pgm      */    char *pgm_buff = NULL;		/* PATH_INFO extraction buffer       */    char *path_translated;		/* From document_root/path_info      */    if (!arg || !*arg || strlen(arg) <= 8) {	HTAlert(BAD_REQUEST);	status = -2;	return(status);    } else {	if (strncmp(arg, "lynxcgi://localhost", 19) == 0) {	    StrAllocCopy(pgm, arg+19);	} else {	    StrAllocCopy(pgm, arg+8);	}	if ((cp=strchr(pgm, '?')) != NULL) { /* Need to terminate executable */	    *cp++ = '\0';	    pgm_args = cp;	}    }    StrAllocCopy(orig_pgm, pgm);    if ((cp=strchr(pgm, '#')) != NULL) {	/*	 *  Strip a #fragment from path.  In this case any pgm_args	 *  found above will also be bogus, since the '?' came after	 *  the '#' and is part of the fragment.  Note that we don't	 *  handle the case where a '#' appears after a '?' properly	 *  according to URL rules. - kw	 */	*cp = '\0';	pgm_args = NULL;    }    HTUnEscape(pgm);    /* BEGIN WebSter Mods */    /* If pgm is not stat-able, see if PATH_INFO data is at the end of pgm */    if ((statrv = stat(pgm, &stat_buf)) < 0) {	StrAllocCopy(pgm_buff, pgm);	while (statrv < 0 || (statrv = stat(pgm_buff, &stat_buf)) < 0) {	    if ((cp=strrchr(pgm_buff, '/')) != NULL) {		*cp = '\0';		statrv = 999;	/* force new stat()  - kw */	    } else {		if (TRACE)		    perror("LYNXCGI: strrchr(pgm_buff, '/') returned NULL");	    	break;	    }        }	if (statrv < 0) {	    /* Did not find PATH_INFO data */	    if (TRACE) 		perror("LYNXCGI: stat() of pgm_buff failed");	} else {	    /* Found PATH_INFO data. Strip it off of pgm and into path_info. */	    StrAllocCopy(path_info, pgm+strlen(pgm_buff));	    strcpy(pgm, pgm_buff);	    if (TRACE)		fprintf(stderr,			"LYNXCGI: stat() of %s succeeded, path_info=\"%s\".\n",			pgm_buff, path_info);	}	FREE(pgm_buff);    }    /* END WebSter Mods */    if (statrv != 0) {	/*	 *  Neither the path as given nor any components examined by	 *  backing up were stat()able. - kw	 */	HTAlert("Unable to access cgi script");	if (TRACE) {	    perror("LYNXCGI: stat() failed");	}	status = -4;    } else if (!(S_ISREG(stat_buf.st_mode) &&		 stat_buf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) {	/*	 *  Not a runnable file, See if we can load it using "file:" code.	 */	char *new_arg = NULL;	/*	 *  But try "file:" only if the file we are looking at is the path	 *  as given (no path_info was extracted), otherwise it will be	 *  to confusing to know just what file is loaded. - kw	 */	if (path_info) {	    if (TRACE) {		fprintf(stderr,			"%s is not a file and %s not an executable, giving up.\n",			orig_pgm, pgm);	    }	    FREE(path_info);	    FREE(pgm);	    FREE(orig_pgm);	    status = -4;	    return(status);	}	    	StrAllocCopy(new_arg, "file://localhost");	StrAllocCat(new_arg, orig_pgm);	if (TRACE) {	    fprintf(stderr,		    "%s is not an executable file, passing the buck.\n", arg);	}	status = HTLoadFile(new_arg, anAnchor, format_out, sink);	FREE(new_arg);    } else if (path_info &&	       anAnchor != HTMainAnchor &&	       !(reloading && anAnchor->document) &&	       strcmp(arg, HTLoadedDocumentURL()) &&	       HText_AreDifferent(anAnchor, arg) &&	       HTUnEscape(orig_pgm) &&	       !exec_ok(HTLoadedDocumentURL(), orig_pgm,			CGI_PATH)) { /* exec_ok gives out msg. */	/*	 *  If we have extra path info and are not just reloading	 *  the current, check the full file path (after unescaping)	 *  now to catch forbidden segments. - kw	 */	status = HT_NOT_LOADED;    } else if (no_lynxcgi) {	_statusline(CGI_DISABLED);	sleep(MessageSecs);	status = HT_NOT_LOADED;    } else if (no_bookmark_exec &&	       anAnchor != HTMainAnchor &&	       !(reloading && anAnchor->document) &&	       strcmp(arg, HTLoadedDocumentURL()) &&	       HText_AreDifferent(anAnchor, arg) && 	       HTLoadedDocumentBookmark()) {	/*	 *  If we are reloading a lynxcgi document that had already been	 *  loaded, the various checks above should allow it even if	 *  no_bookmark_exec is TRUE an we are not now coming from a	 *  bookmark page. - kw	 */	_statusline(BOOKMARK_EXEC_DISABLED);	sleep(MessageSecs);	status = HT_NOT_LOADED;    } else if (anAnchor != HTMainAnchor &&	       !(reloading && anAnchor->document) &&	       strcmp(arg, HTLoadedDocumentURL()) &&	       HText_AreDifferent(anAnchor, arg) &&	       !exec_ok(HTLoadedDocumentURL(), pgm,			CGI_PATH)) { /* exec_ok gives out msg. */	/*	 *  If we are reloading a lynxcgi document that had already been	 *  loaded, the various checks above should allow it even if	 *  exec_ok() would reject it because we are not now coming from	 *  a document with a URL allowed by TRUSTED_LYNXCGI rules. - kw	 */	status = HT_NOT_LOADED;    } else {	HTFormat format_in;	HTStream *target  = NULL;		/* Unconverted data */	int fd1[2], fd2[2];	char buf[1024];	pid_t pid;#if HAVE_TYPE_UNIONWAIT	union wait wstatus;#else	int wstatus;#endif	if (anAnchor->isHEAD || keep_mime_headers) {	    /* Show output as plain text */	    format_in = WWW_PLAINTEXT;	} else {	    	    /* Decode full HTTP response */	    format_in = HTAtom_for("www/mime");	}			target = HTStreamStack(format_in,			       format_out,			       sink, anAnchor);			if (!target || target == NULL) {	    sprintf(buf, CANNOT_CONVERT_I_TO_O,		    HTAtom_name(format_in), HTAtom_name(format_out));	    _statusline(buf);	    sleep(AlertSecs);	    status = HT_NOT_LOADED;	} else if (anAnchor->post_data && pipe(fd1) < 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -