|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* $LynxId: LYCgi.c,v 1.72 2018/03/18 18:56:05 tom Exp $
|
|
Packit |
f574b8 |
* Lynx CGI support LYCgi.c
|
|
Packit |
f574b8 |
* ================
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Authors
|
|
Packit |
f574b8 |
* GL George Lindholm <George.Lindholm@ubc.ca>
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* History
|
|
Packit |
f574b8 |
* 15 Jun 95 Created as way to provide a lynx based service with
|
|
Packit |
f574b8 |
* dynamic pages without the need for a http daemon. GL
|
|
Packit |
f574b8 |
* 27 Jun 95 Added <index> (command line) support. Various cleanup
|
|
Packit |
f574b8 |
* and bug fixes. GL
|
|
Packit |
f574b8 |
* 04 Sep 97 Added support for PATH_INFO scripts. JKT
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Bugs
|
|
Packit |
f574b8 |
* If the called scripts aborts before sending the mime headers then
|
|
Packit |
f574b8 |
* lynx hangs.
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Should do something about SIGPIPE, (but then it should never happen)
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* No support for redirection. Or mime-types.
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Should try and parse for a HTTP 1.1 header in case we are "calling" a
|
|
Packit |
f574b8 |
* nph- script.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#include <HTUtils.h>
|
|
Packit |
f574b8 |
#include <HTTP.h>
|
|
Packit |
f574b8 |
#include <HTParse.h>
|
|
Packit |
f574b8 |
#include <HTTCP.h>
|
|
Packit |
f574b8 |
#include <HTFormat.h>
|
|
Packit |
f574b8 |
#include <HTFile.h>
|
|
Packit |
f574b8 |
#include <HTAlert.h>
|
|
Packit |
f574b8 |
#include <HTMIME.h>
|
|
Packit |
f574b8 |
#include <HTAABrow.h>
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#include <LYGlobalDefs.h>
|
|
Packit |
f574b8 |
#include <LYUtils.h>
|
|
Packit |
f574b8 |
#include <HTML.h>
|
|
Packit |
f574b8 |
#include <HTInit.h>
|
|
Packit |
f574b8 |
#include <LYGetFile.h>
|
|
Packit |
f574b8 |
#include <LYBookmark.h>
|
|
Packit |
f574b8 |
#include <GridText.h>
|
|
Packit |
f574b8 |
#include <LYCgi.h>
|
|
Packit |
f574b8 |
#include <LYStrings.h>
|
|
Packit |
f574b8 |
#include <LYLocal.h>
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#include <LYLeaks.h>
|
|
Packit |
f574b8 |
#include <www_wait.h>
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static char **env = NULL; /* Environment variables */
|
|
Packit |
f574b8 |
static unsigned envc_size = 0; /* Slots in environment array */
|
|
Packit |
f574b8 |
static unsigned envc = 0; /* Slots used so far */
|
|
Packit |
f574b8 |
static HTList *alloced = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#if defined(LYNXCGI_LINKS) && !defined(__MINGW32__)
|
|
Packit |
f574b8 |
static char *user_agent = NULL;
|
|
Packit |
f574b8 |
static char *server_software = NULL;
|
|
Packit |
f574b8 |
static char *accept_language = NULL;
|
|
Packit |
f574b8 |
static char *post_len = NULL;
|
|
Packit |
f574b8 |
#endif /* LYNXCGI_LINKS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static void add_environment_value(const char *env_value);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#define PERROR(msg) CTRACE((tfp, "LYNXCGI: %s: %s\n", msg, LYStrerror(errno)))
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#define PUTS(buf) (*target->isa->put_block)(target, buf, strlen(buf))
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef LY_FIND_LEAKS
|
|
Packit |
f574b8 |
static void free_alloced_lynxcgi(void)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
void *ptr;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
while ((ptr = HTList_removeLastObject(alloced)) != NULL) {
|
|
Packit |
f574b8 |
FREE(ptr);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
FREE(alloced);
|
|
Packit |
f574b8 |
#ifdef LYNXCGI_LINKS
|
|
Packit |
f574b8 |
FREE(user_agent);
|
|
Packit |
f574b8 |
FREE(server_software);
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* LY_FIND_LEAKS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static void remember_alloced(void *ptr)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
if (!alloced) {
|
|
Packit |
f574b8 |
alloced = HTList_new();
|
|
Packit |
f574b8 |
#ifdef LY_FIND_LEAKS
|
|
Packit |
f574b8 |
atexit(free_alloced_lynxcgi);
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
HTList_addObject(alloced, ptr);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Simple routine for expanding the environment array and adding a value to
|
|
Packit |
f574b8 |
* it
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
static void add_environment_value(const char *env_value)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
if (envc == envc_size) { /* Need some more slots */
|
|
Packit |
f574b8 |
envc_size += 10;
|
|
Packit |
f574b8 |
if (env) {
|
|
Packit |
f574b8 |
env = (char **) realloc(env,
|
|
Packit |
f574b8 |
sizeof(env[0]) * (envc_size + 2));
|
|
Packit |
f574b8 |
/* + terminator and base 0 */
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
env = (char **) malloc(sizeof(env[0]) * (envc_size + 2));
|
|
Packit |
f574b8 |
/* + terminator and base 0 */
|
|
Packit |
f574b8 |
remember_alloced(env);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (env == NULL) {
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYCgi");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
env[envc++] = DeConst(env_value);
|
|
Packit |
f574b8 |
env[envc] = NULL; /* Make sure it is always properly terminated */
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Add the value of an existing environment variable to those passed on to the
|
|
Packit |
f574b8 |
* lynxcgi script.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void add_lynxcgi_environment(const char *variable_name)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
char *env_value;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
env_value = LYGetEnv(variable_name);
|
|
Packit |
f574b8 |
if (env_value != NULL) {
|
|
Packit |
f574b8 |
char *add_value = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&add_value, "%s=%s", variable_name, env_value);
|
|
Packit |
f574b8 |
add_environment_value(add_value);
|
|
Packit |
f574b8 |
remember_alloced(add_value);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef __MINGW32__
|
|
Packit |
f574b8 |
static int LYLoadCGI(const char *arg,
|
|
Packit |
f574b8 |
HTParentAnchor *anAnchor,
|
|
Packit |
f574b8 |
HTFormat format_out,
|
|
Packit |
f574b8 |
HTStream *sink)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
(void) arg;
|
|
Packit |
f574b8 |
(void) anAnchor;
|
|
Packit |
f574b8 |
(void) format_out;
|
|
Packit |
f574b8 |
(void) sink;
|
|
Packit |
f574b8 |
return -1;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
#ifdef LYNXCGI_LINKS
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Wrapper for exec_ok(), confirming with user if the link text is not visible
|
|
Packit |
f574b8 |
* in the status line.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
static BOOL can_exec_cgi(const char *linktext, const char *linkargs)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
const char *format = gettext("Do you want to execute \"%s\"?");
|
|
Packit |
f574b8 |
char *message = NULL;
|
|
Packit |
f574b8 |
char *command = NULL;
|
|
Packit |
f574b8 |
char *p;
|
|
Packit |
f574b8 |
BOOL result = TRUE;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (!exec_ok(HTLoadedDocumentURL(), linktext, CGI_PATH)) {
|
|
Packit |
f574b8 |
/* exec_ok gives out msg. */
|
|
Packit |
f574b8 |
result = FALSE;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
StrAllocCopy(command, linktext);
|
|
Packit |
f574b8 |
if (non_empty(linkargs)) {
|
|
Packit |
f574b8 |
HTSprintf(&command, " %s", linkargs);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
HTUnEscape(command);
|
|
Packit |
f574b8 |
for (p = command; *p; ++p)
|
|
Packit |
f574b8 |
if (*p == '+')
|
|
Packit |
f574b8 |
*p = ' ';
|
|
Packit |
f574b8 |
HTSprintf0(&message, format, command);
|
|
Packit |
f574b8 |
result = HTConfirm(message);
|
|
Packit |
f574b8 |
FREE(message);
|
|
Packit |
f574b8 |
FREE(command);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
return result;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* LYNXCGI_LINKS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static int LYLoadCGI(const char *arg,
|
|
Packit |
f574b8 |
HTParentAnchor *anAnchor,
|
|
Packit |
f574b8 |
HTFormat format_out,
|
|
Packit |
f574b8 |
HTStream *sink)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
int status = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef LYNXCGI_LINKS
|
|
Packit |
f574b8 |
#ifndef VMS
|
|
Packit |
f574b8 |
char *cp;
|
|
Packit |
f574b8 |
struct stat stat_buf;
|
|
Packit |
f574b8 |
char *pgm = NULL; /* executable */
|
|
Packit |
f574b8 |
char *pgm_args = NULL; /* and its argument(s) */
|
|
Packit |
f574b8 |
int statrv;
|
|
Packit |
f574b8 |
char *orig_pgm = NULL; /* Path up to ? as given, URL-escaped */
|
|
Packit |
f574b8 |
char *document_root = NULL; /* Corrected value of DOCUMENT_ROOT */
|
|
Packit |
f574b8 |
char *path_info = NULL; /* PATH_INFO extracted from pgm */
|
|
Packit |
f574b8 |
char *pgm_buff = NULL; /* PATH_INFO extraction buffer */
|
|
Packit |
f574b8 |
char *path_translated; /* From document_root/path_info */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (isEmpty(arg) || strlen(arg) <= 8) {
|
|
Packit |
f574b8 |
HTAlert(BAD_REQUEST);
|
|
Packit |
f574b8 |
status = -2;
|
|
Packit |
f574b8 |
return (status);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
if (StrNCmp(arg, "lynxcgi://localhost", 19) == 0) {
|
|
Packit |
f574b8 |
StrAllocCopy(pgm, arg + 19);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
StrAllocCopy(pgm, arg + 8);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if ((cp = StrChr(pgm, '?')) != NULL) { /* Need to terminate executable */
|
|
Packit |
f574b8 |
*cp++ = '\0';
|
|
Packit |
f574b8 |
pgm_args = cp;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
StrAllocCopy(orig_pgm, pgm);
|
|
Packit |
f574b8 |
if (trimPoundSelector(pgm) != NULL) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Strip a #fragment from path. In this case any pgm_args found above
|
|
Packit |
f574b8 |
* will also be bogus, since the '?' came after the '#' and is part of
|
|
Packit |
f574b8 |
* the fragment. Note that we don't handle the case where a '#'
|
|
Packit |
f574b8 |
* appears after a '?' properly according to URL rules. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
pgm_args = NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
HTUnEscape(pgm);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* BEGIN WebSter Mods */
|
|
Packit |
f574b8 |
/* If pgm is not stat-able, see if PATH_INFO data is at the end of pgm */
|
|
Packit |
f574b8 |
if ((statrv = stat(pgm, &stat_buf)) < 0) {
|
|
Packit |
f574b8 |
StrAllocCopy(pgm_buff, pgm);
|
|
Packit |
f574b8 |
while (statrv < 0 || (statrv = stat(pgm_buff, &stat_buf)) < 0) {
|
|
Packit |
f574b8 |
if ((cp = strrchr(pgm_buff, '/')) != NULL) {
|
|
Packit |
f574b8 |
*cp = '\0';
|
|
Packit |
f574b8 |
statrv = 1; /* force new stat() - kw */
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
PERROR("strrchr(pgm_buff, '/') returned NULL");
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (statrv < 0) {
|
|
Packit |
f574b8 |
/* Did not find PATH_INFO data */
|
|
Packit |
f574b8 |
PERROR("stat() of pgm_buff failed");
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
/* Found PATH_INFO data. Strip it off of pgm and into path_info. */
|
|
Packit |
f574b8 |
StrAllocCopy(path_info, pgm + strlen(pgm_buff));
|
|
Packit |
f574b8 |
/* The following is safe since pgm_buff was derived from pgm
|
|
Packit |
f574b8 |
by stripping stuff off its end and by HTUnEscaping, so we
|
|
Packit |
f574b8 |
know we have enough memory allocated for pgm. Note that
|
|
Packit |
f574b8 |
pgm_args may still point into that memory, so we cannot
|
|
Packit |
f574b8 |
reallocate pgm here. - kw */
|
|
Packit |
f574b8 |
strcpy(pgm, pgm_buff);
|
|
Packit |
f574b8 |
CTRACE((tfp,
|
|
Packit |
f574b8 |
"LYNXCGI: stat() of %s succeeded, path_info=\"%s\".\n",
|
|
Packit |
f574b8 |
pgm_buff, path_info));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
FREE(pgm_buff);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
/* END WebSter Mods */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (statrv != 0) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Neither the path as given nor any components examined by backing up
|
|
Packit |
f574b8 |
* were stat()able. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
HTAlert(gettext("Unable to access cgi script"));
|
|
Packit |
f574b8 |
PERROR("stat() failed");
|
|
Packit |
f574b8 |
status = -4;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else
|
|
Packit |
f574b8 |
#ifdef _WINDOWS /* 1998/01/14 (Wed) 09:16:04 */
|
|
Packit |
f574b8 |
#define isExecutable(mode) (mode & (S_IXUSR))
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
#define isExecutable(mode) (mode & (S_IXUSR|S_IXGRP|S_IXOTH))
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
if (!(S_ISREG(stat_buf.st_mode) && isExecutable(stat_buf.st_mode))) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Not a runnable file, See if we can load it using "file:" code.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
char *new_arg = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* But try "file:" only if the file we are looking at is the path as
|
|
Packit |
f574b8 |
* given (no path_info was extracted), otherwise it will be to
|
|
Packit |
f574b8 |
* confusing to know just what file is loaded. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (path_info) {
|
|
Packit |
f574b8 |
CTRACE((tfp,
|
|
Packit |
f574b8 |
"%s is not a file and %s not an executable, giving up.\n",
|
|
Packit |
f574b8 |
orig_pgm, pgm));
|
|
Packit |
f574b8 |
FREE(path_info);
|
|
Packit |
f574b8 |
FREE(pgm);
|
|
Packit |
f574b8 |
FREE(orig_pgm);
|
|
Packit |
f574b8 |
status = -4;
|
|
Packit |
f574b8 |
return (status);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
LYLocalFileToURL(&new_arg, orig_pgm);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
CTRACE((tfp, "%s is not an executable file, passing the buck.\n", arg));
|
|
Packit |
f574b8 |
status = HTLoadFile(new_arg, anAnchor, format_out, sink);
|
|
Packit |
f574b8 |
FREE(new_arg);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (path_info &&
|
|
Packit |
f574b8 |
anAnchor != HTMainAnchor &&
|
|
Packit |
f574b8 |
!(reloading && anAnchor->document) &&
|
|
Packit |
f574b8 |
strcmp(arg, HTLoadedDocumentURL()) &&
|
|
Packit |
f574b8 |
HText_AreDifferent(anAnchor, arg) &&
|
|
Packit |
f574b8 |
HTUnEscape(orig_pgm) &&
|
|
Packit |
f574b8 |
!can_exec_cgi(orig_pgm, "")) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If we have extra path info and are not just reloading the current,
|
|
Packit |
f574b8 |
* check the full file path (after unescaping) now to catch forbidden
|
|
Packit |
f574b8 |
* segments. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (no_lynxcgi) {
|
|
Packit |
f574b8 |
HTUserMsg(CGI_DISABLED);
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (no_bookmark_exec &&
|
|
Packit |
f574b8 |
anAnchor != HTMainAnchor &&
|
|
Packit |
f574b8 |
!(reloading && anAnchor->document) &&
|
|
Packit |
f574b8 |
strcmp(arg, HTLoadedDocumentURL()) &&
|
|
Packit |
f574b8 |
HText_AreDifferent(anAnchor, arg) &&
|
|
Packit |
f574b8 |
HTLoadedDocumentBookmark()) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If we are reloading a lynxcgi document that had already been loaded,
|
|
Packit |
f574b8 |
* the various checks above should allow it even if no_bookmark_exec is
|
|
Packit |
f574b8 |
* TRUE an we are not now coming from a bookmark page. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
HTUserMsg(BOOKMARK_EXEC_DISABLED);
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (anAnchor != HTMainAnchor &&
|
|
Packit |
f574b8 |
!(reloading && anAnchor->document) &&
|
|
Packit |
f574b8 |
strcmp(arg, HTLoadedDocumentURL()) &&
|
|
Packit |
f574b8 |
HText_AreDifferent(anAnchor, arg) &&
|
|
Packit |
f574b8 |
!can_exec_cgi(pgm, pgm_args)) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If we are reloading a lynxcgi document that had already been loaded,
|
|
Packit |
f574b8 |
* the various checks above should allow it even if exec_ok() would
|
|
Packit |
f574b8 |
* reject it because we are not now coming from a document with a URL
|
|
Packit |
f574b8 |
* allowed by TRUSTED_LYNXCGI rules. - kw
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
HTFormat format_in;
|
|
Packit |
f574b8 |
HTStream *target = NULL; /* Unconverted data */
|
|
Packit |
f574b8 |
int fd1[2], fd2[2];
|
|
Packit |
f574b8 |
char buf[MAX_LINE];
|
|
Packit |
f574b8 |
int pid;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef HAVE_TYPE_UNIONWAIT
|
|
Packit |
f574b8 |
union wait wstatus;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
int wstatus;
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
fd1[0] = -1;
|
|
Packit |
f574b8 |
fd1[1] = -1;
|
|
Packit |
f574b8 |
fd2[0] = -1;
|
|
Packit |
f574b8 |
fd2[1] = -1;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (anAnchor->isHEAD || keep_mime_headers) {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Show output as plain text */
|
|
Packit |
f574b8 |
format_in = WWW_PLAINTEXT;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Decode full HTTP response */
|
|
Packit |
f574b8 |
format_in = HTAtom_for("www/mime");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
target = HTStreamStack(format_in,
|
|
Packit |
f574b8 |
format_out,
|
|
Packit |
f574b8 |
sink, anAnchor);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (target == NULL) {
|
|
Packit |
f574b8 |
char *tmp = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&tmp, CANNOT_CONVERT_I_TO_O,
|
|
Packit |
f574b8 |
HTAtom_name(format_in),
|
|
Packit |
f574b8 |
HTAtom_name(format_out));
|
|
Packit |
f574b8 |
HTAlert(tmp);
|
|
Packit |
f574b8 |
FREE(tmp);
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (anAnchor->post_data && pipe(fd1) < 0) {
|
|
Packit |
f574b8 |
HTAlert(CONNECT_SET_FAILED);
|
|
Packit |
f574b8 |
PERROR("pipe() failed");
|
|
Packit |
f574b8 |
status = -3;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (pipe(fd2) < 0) {
|
|
Packit |
f574b8 |
HTAlert(CONNECT_SET_FAILED);
|
|
Packit |
f574b8 |
PERROR("pipe() failed");
|
|
Packit |
f574b8 |
close(fd1[0]);
|
|
Packit |
f574b8 |
close(fd1[1]);
|
|
Packit |
f574b8 |
status = -3;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
static BOOL first_time = TRUE; /* One time setup flag */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (first_time) { /* Set up static environment variables */
|
|
Packit |
f574b8 |
first_time = FALSE; /* Only once */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
add_environment_value("REMOTE_HOST=localhost");
|
|
Packit |
f574b8 |
add_environment_value("REMOTE_ADDR=127.0.0.1");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&user_agent, "HTTP_USER_AGENT=%s/%s libwww/%s",
|
|
Packit |
f574b8 |
LYNX_NAME, LYNX_VERSION, HTLibraryVersion);
|
|
Packit |
f574b8 |
add_environment_value(user_agent);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&server_software, "SERVER_SOFTWARE=%s/%s",
|
|
Packit |
f574b8 |
LYNX_NAME, LYNX_VERSION);
|
|
Packit |
f574b8 |
add_environment_value(server_software);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
fflush(stdout);
|
|
Packit |
f574b8 |
fflush(stderr);
|
|
Packit |
f574b8 |
CTRACE_FLUSH(tfp);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if ((pid = fork()) > 0) { /* The good, */
|
|
Packit |
f574b8 |
ssize_t chars;
|
|
Packit |
f574b8 |
off_t total_chars;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
close(fd2[1]);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (anAnchor->post_data) {
|
|
Packit |
f574b8 |
ssize_t written;
|
|
Packit |
f574b8 |
int remaining, total_written = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
close(fd1[0]);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* We have form data to push across the pipe */
|
|
Packit |
f574b8 |
if (TRACE) {
|
|
Packit |
f574b8 |
CTRACE((tfp,
|
|
Packit |
f574b8 |
"LYNXCGI: Doing post, content-type '%s'\n",
|
|
Packit |
f574b8 |
anAnchor->post_content_type));
|
|
Packit |
f574b8 |
CTRACE((tfp, "LYNXCGI: Writing:\n"));
|
|
Packit |
f574b8 |
trace_bstring(anAnchor->post_data);
|
|
Packit |
f574b8 |
CTRACE((tfp, "----------------------------------\n"));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
remaining = BStrLen(anAnchor->post_data);
|
|
Packit |
f574b8 |
while ((written = write(fd1[1],
|
|
Packit |
f574b8 |
BStrData(anAnchor->post_data) + total_written,
|
|
Packit |
f574b8 |
(size_t) remaining)) != 0) {
|
|
Packit |
f574b8 |
if (written < 0) {
|
|
Packit |
f574b8 |
#ifdef EINTR
|
|
Packit |
f574b8 |
if (errno == EINTR)
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
#endif /* EINTR */
|
|
Packit |
f574b8 |
#ifdef ERESTARTSYS
|
|
Packit |
f574b8 |
if (errno == ERESTARTSYS)
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
#endif /* ERESTARTSYS */
|
|
Packit |
f574b8 |
PERROR("write() of POST data failed");
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
CTRACE((tfp, "LYNXCGI: Wrote %d bytes of POST data.\n",
|
|
Packit |
f574b8 |
(int) written));
|
|
Packit |
f574b8 |
total_written += (int) written;
|
|
Packit |
f574b8 |
remaining -= (int) written;
|
|
Packit |
f574b8 |
if (remaining == 0)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (remaining != 0) {
|
|
Packit |
f574b8 |
CTRACE((tfp, "LYNXCGI: %d bytes remain unwritten!\n",
|
|
Packit |
f574b8 |
remaining));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
close(fd1[1]);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTReadProgress(total_chars = 0, (off_t) 0);
|
|
Packit |
f574b8 |
while ((chars = read(fd2[0], buf, sizeof(buf))) != 0) {
|
|
Packit |
f574b8 |
if (chars < 0) {
|
|
Packit |
f574b8 |
#ifdef EINTR
|
|
Packit |
f574b8 |
if (errno == EINTR)
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
#endif /* EINTR */
|
|
Packit |
f574b8 |
#ifdef ERESTARTSYS
|
|
Packit |
f574b8 |
if (errno == ERESTARTSYS)
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
#endif /* ERESTARTSYS */
|
|
Packit |
f574b8 |
PERROR("read() of CGI output failed");
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
total_chars += (int) chars;
|
|
Packit |
f574b8 |
HTReadProgress(total_chars, (off_t) 0);
|
|
Packit |
f574b8 |
CTRACE((tfp, "LYNXCGI: Rx: %.*s\n", (int) chars, buf));
|
|
Packit |
f574b8 |
(*target->isa->put_block) (target, buf, (int) chars);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (chars < 0 && total_chars == 0) {
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
(*target->isa->_abort) (target, NULL);
|
|
Packit |
f574b8 |
target = NULL;
|
|
Packit |
f574b8 |
} else if (chars != 0) {
|
|
Packit |
f574b8 |
status = HT_PARTIAL_CONTENT;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
status = HT_LOADED;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifndef HAVE_WAITPID
|
|
Packit |
f574b8 |
while (wait(&wstatus) != pid) ; /* do nothing */
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
while (-1 == waitpid(pid, &wstatus, 0)) { /* wait for child */
|
|
Packit |
f574b8 |
#ifdef EINTR
|
|
Packit |
f574b8 |
if (errno == EINTR)
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
#endif /* EINTR */
|
|
Packit |
f574b8 |
#ifdef ERESTARTSYS
|
|
Packit |
f574b8 |
if (errno == ERESTARTSYS)
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
#endif /* ERESTARTSYS */
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* !HAVE_WAITPID */
|
|
Packit |
f574b8 |
close(fd2[0]);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (pid == 0) { /* The Bad, */
|
|
Packit |
f574b8 |
char **argv = NULL;
|
|
Packit |
f574b8 |
int argv_cnt = 3; /* name, one arg and terminator */
|
|
Packit |
f574b8 |
char **cur_argv = NULL;
|
|
Packit |
f574b8 |
int exec_errno;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Set up output pipe */
|
|
Packit |
f574b8 |
close(fd2[0]);
|
|
Packit |
f574b8 |
dup2(fd2[1], fileno(stdout)); /* Should check success code */
|
|
Packit |
f574b8 |
dup2(fd2[1], fileno(stderr));
|
|
Packit |
f574b8 |
close(fd2[1]);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (non_empty(language)) {
|
|
Packit |
f574b8 |
HTSprintf0(&accept_language, "HTTP_ACCEPT_LANGUAGE=%s", language);
|
|
Packit |
f574b8 |
add_environment_value(accept_language);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (non_empty(pref_charset)) {
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
StrAllocCopy(cp, "HTTP_ACCEPT_CHARSET=");
|
|
Packit |
f574b8 |
StrAllocCat(cp, pref_charset);
|
|
Packit |
f574b8 |
add_environment_value(cp);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (anAnchor->post_data &&
|
|
Packit |
f574b8 |
anAnchor->post_content_type) {
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
StrAllocCopy(cp, "CONTENT_TYPE=");
|
|
Packit |
f574b8 |
StrAllocCat(cp, anAnchor->post_content_type);
|
|
Packit |
f574b8 |
add_environment_value(cp);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (anAnchor->post_data) { /* post script, read stdin */
|
|
Packit |
f574b8 |
close(fd1[1]);
|
|
Packit |
f574b8 |
dup2(fd1[0], fileno(stdin));
|
|
Packit |
f574b8 |
close(fd1[0]);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Build environment variables */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
add_environment_value("REQUEST_METHOD=POST");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&post_len, "CONTENT_LENGTH=%d",
|
|
Packit |
f574b8 |
BStrLen(anAnchor->post_data));
|
|
Packit |
f574b8 |
add_environment_value(post_len);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
close(fileno(stdin));
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (anAnchor->isHEAD) {
|
|
Packit |
f574b8 |
add_environment_value("REQUEST_METHOD=HEAD");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Set up argument line, mainly for <index> scripts
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (pgm_args != NULL) {
|
|
Packit |
f574b8 |
for (cp = pgm_args; *cp != '\0'; cp++) {
|
|
Packit |
f574b8 |
if (*cp == '+') {
|
|
Packit |
f574b8 |
argv_cnt++;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
argv = (char **) malloc((unsigned) argv_cnt * sizeof(char *));
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (argv == NULL) {
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYCgi");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
cur_argv = argv + 1; /* For argv[0] */
|
|
Packit |
f574b8 |
if (pgm_args != NULL) {
|
|
Packit |
f574b8 |
char *cr;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Data for a get/search form */
|
|
Packit |
f574b8 |
if (is_www_index) {
|
|
Packit |
f574b8 |
add_environment_value("REQUEST_METHOD=SEARCH");
|
|
Packit |
f574b8 |
} else if (!anAnchor->isHEAD && !anAnchor->post_data) {
|
|
Packit |
f574b8 |
add_environment_value("REQUEST_METHOD=GET");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
StrAllocCopy(cp, "QUERY_STRING=");
|
|
Packit |
f574b8 |
StrAllocCat(cp, pgm_args);
|
|
Packit |
f574b8 |
add_environment_value(cp);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Split up arguments into argv array
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
cp = pgm_args;
|
|
Packit |
f574b8 |
cr = cp;
|
|
Packit |
f574b8 |
while (1) {
|
|
Packit |
f574b8 |
if (*cp == '\0') {
|
|
Packit |
f574b8 |
*(cur_argv++) = HTUnEscape(cr);
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else if (*cp == '+') {
|
|
Packit |
f574b8 |
*cp++ = '\0';
|
|
Packit |
f574b8 |
*(cur_argv++) = HTUnEscape(cr);
|
|
Packit |
f574b8 |
cr = cp;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
cp++;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
} else if (!anAnchor->isHEAD && !anAnchor->post_data) {
|
|
Packit |
f574b8 |
add_environment_value("REQUEST_METHOD=GET");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
*cur_argv = NULL; /* Terminate argv */
|
|
Packit |
f574b8 |
argv[0] = pgm;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* Begin WebSter Mods -jkt */
|
|
Packit |
f574b8 |
if (non_empty(LYCgiDocumentRoot)) {
|
|
Packit |
f574b8 |
/* Add DOCUMENT_ROOT to env */
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
StrAllocCopy(cp, "DOCUMENT_ROOT=");
|
|
Packit |
f574b8 |
StrAllocCat(cp, LYCgiDocumentRoot);
|
|
Packit |
f574b8 |
add_environment_value(cp);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (path_info != NULL) {
|
|
Packit |
f574b8 |
/* Add PATH_INFO to env */
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
StrAllocCopy(cp, "PATH_INFO=");
|
|
Packit |
f574b8 |
StrAllocCat(cp, path_info);
|
|
Packit |
f574b8 |
add_environment_value(cp);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (non_empty(LYCgiDocumentRoot) && path_info != NULL) {
|
|
Packit |
f574b8 |
/* Construct and add PATH_TRANSLATED to env */
|
|
Packit |
f574b8 |
StrAllocCopy(document_root, LYCgiDocumentRoot);
|
|
Packit |
f574b8 |
LYTrimHtmlSep(document_root);
|
|
Packit |
f574b8 |
path_translated = document_root;
|
|
Packit |
f574b8 |
StrAllocCat(path_translated, path_info);
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
StrAllocCopy(cp, "PATH_TRANSLATED=");
|
|
Packit |
f574b8 |
StrAllocCat(cp, path_translated);
|
|
Packit |
f574b8 |
add_environment_value(cp);
|
|
Packit |
f574b8 |
FREE(path_translated);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
/* End WebSter Mods -jkt */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
execve(argv[0], argv, env);
|
|
Packit |
f574b8 |
exec_errno = errno;
|
|
Packit |
f574b8 |
PERROR("execve failed");
|
|
Packit |
f574b8 |
printf("Content-Type: " STR_PLAINTEXT "\r\n\r\n");
|
|
Packit |
f574b8 |
if (!anAnchor->isHEAD) {
|
|
Packit |
f574b8 |
printf("exec of %s failed", pgm);
|
|
Packit |
f574b8 |
printf(": %s.\r\n", LYStrerror(exec_errno));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
fflush(stdout);
|
|
Packit |
f574b8 |
fflush(stderr);
|
|
Packit |
f574b8 |
_exit(1);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else { /* and the Ugly */
|
|
Packit |
f574b8 |
HTAlert(CONNECT_FAILED);
|
|
Packit |
f574b8 |
PERROR("fork() failed");
|
|
Packit |
f574b8 |
close(fd1[0]);
|
|
Packit |
f574b8 |
close(fd1[1]);
|
|
Packit |
f574b8 |
close(fd2[0]);
|
|
Packit |
f574b8 |
close(fd2[1]);
|
|
Packit |
f574b8 |
status = -1;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (target != NULL) {
|
|
Packit |
f574b8 |
(*target->isa->_free) (target);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
FREE(path_info);
|
|
Packit |
f574b8 |
FREE(pgm);
|
|
Packit |
f574b8 |
FREE(orig_pgm);
|
|
Packit |
f574b8 |
#else /* VMS */
|
|
Packit |
f574b8 |
HTStream *target;
|
|
Packit |
f574b8 |
char *buf = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
target = HTStreamStack(WWW_HTML,
|
|
Packit |
f574b8 |
format_out,
|
|
Packit |
f574b8 |
sink, anAnchor);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf, "<html>\n<head>\n<title>%s</title>\n</head>\n<body>\n",
|
|
Packit |
f574b8 |
gettext("Good Advice"));
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf, "%s\n", gettext("Good Advice"));
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf, "%s
|
|
Packit |
f574b8 |
gettext("An excellent http server for VMS is available via"));
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf,
|
|
Packit |
f574b8 |
"href=\"http://www.ecr6.ohio-state.edu/www/doc/serverinfo.html\"\n");
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf, ">%s.\n", gettext("this link"));
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf, "%s\n",
|
|
Packit |
f574b8 |
gettext("It provides state of the art CGI script support.\n"));
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&buf, "</body>\n</html>\n");
|
|
Packit |
f574b8 |
PUTS(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
(*target->isa->_free) (target);
|
|
Packit |
f574b8 |
FREE(buf);
|
|
Packit |
f574b8 |
status = HT_LOADED;
|
|
Packit |
f574b8 |
#endif /* VMS */
|
|
Packit |
f574b8 |
#else /* LYNXCGI_LINKS */
|
|
Packit |
f574b8 |
HTUserMsg(CGI_NOT_COMPILED);
|
|
Packit |
f574b8 |
status = HT_NOT_LOADED;
|
|
Packit |
f574b8 |
#endif /* LYNXCGI_LINKS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
(void) arg;
|
|
Packit |
f574b8 |
(void) anAnchor;
|
|
Packit |
f574b8 |
(void) format_out;
|
|
Packit |
f574b8 |
(void) sink;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
return (status);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* __MINGW32__ */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef GLOBALDEF_IS_MACRO
|
|
Packit |
f574b8 |
#define _LYCGI_C_GLOBALDEF_1_INIT { "lynxcgi", LYLoadCGI, 0 }
|
|
Packit |
f574b8 |
GLOBALDEF(HTProtocol, LYLynxCGI, _LYCGI_C_GLOBALDEF_1_INIT);
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
GLOBALDEF HTProtocol LYLynxCGI =
|
|
Packit |
f574b8 |
{"lynxcgi", LYLoadCGI, 0};
|
|
Packit |
f574b8 |
#endif /* GLOBALDEF_IS_MACRO */
|