|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* @file agCgi.c
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* This is a CGI wrapper for AutoGen. It will take POST-method
|
|
Packit Service |
96b5d3 |
* name-value pairs and emit AutoGen definitions to a spawned
|
|
Packit Service |
96b5d3 |
* AutoGen process.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* This file is part of AutoGen.
|
|
Packit Service |
96b5d3 |
* AutoGen Copyright (C) 1992-2016 by Bruce Korb - all rights reserved
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* AutoGen is free software: you can redistribute it and/or modify it
|
|
Packit Service |
96b5d3 |
* under the terms of the GNU General Public License as published by the
|
|
Packit Service |
96b5d3 |
* Free Software Foundation, either version 3 of the License, or
|
|
Packit Service |
96b5d3 |
* (at your option) any later version.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* AutoGen is distributed in the hope that it will be useful, but
|
|
Packit Service |
96b5d3 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
96b5d3 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit Service |
96b5d3 |
* See the GNU General Public License for more details.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* You should have received a copy of the GNU General Public License along
|
|
Packit Service |
96b5d3 |
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
typedef struct {
|
|
Packit Service |
96b5d3 |
char const * name;
|
|
Packit Service |
96b5d3 |
char * cgi_val;
|
|
Packit Service |
96b5d3 |
} name_map_t;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
#define ENV_TABLE \
|
|
Packit Service |
96b5d3 |
_ET_(REQUEST_METHOD) \
|
|
Packit Service |
96b5d3 |
_ET_(QUERY_STRING) \
|
|
Packit Service |
96b5d3 |
_ET_(CONTENT_LENGTH) \
|
|
Packit Service |
96b5d3 |
\
|
|
Packit Service |
96b5d3 |
_ET_(AUTH_TYPE) \
|
|
Packit Service |
96b5d3 |
_ET_(CONTENT_TYPE) \
|
|
Packit Service |
96b5d3 |
_ET_(GATEWAY_INTERFACE) \
|
|
Packit Service |
96b5d3 |
_ET_(HTTP_ACCEPT) \
|
|
Packit Service |
96b5d3 |
_ET_(HTTP_REFERER) \
|
|
Packit Service |
96b5d3 |
_ET_(HTTP_USER_AGENT) \
|
|
Packit Service |
96b5d3 |
_ET_(PATH_INFO) \
|
|
Packit Service |
96b5d3 |
_ET_(PATH_TRANSLATED) \
|
|
Packit Service |
96b5d3 |
_ET_(REMOTE_ADDR) \
|
|
Packit Service |
96b5d3 |
_ET_(REMOTE_HOST) \
|
|
Packit Service |
96b5d3 |
_ET_(REMOTE_IDENT) \
|
|
Packit Service |
96b5d3 |
_ET_(REMOTE_USER) \
|
|
Packit Service |
96b5d3 |
_ET_(SCRIPT_NAME) \
|
|
Packit Service |
96b5d3 |
_ET_(SERVER_NAME) \
|
|
Packit Service |
96b5d3 |
_ET_(SERVER_PORT) \
|
|
Packit Service |
96b5d3 |
_ET_(SERVER_PROTOCOL) \
|
|
Packit Service |
96b5d3 |
_ET_(SERVER_SOFTWARE)
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
static name_map_t name_val_map[] = {
|
|
Packit Service |
96b5d3 |
#define _ET_(n) { #n, NULL },
|
|
Packit Service |
96b5d3 |
ENV_TABLE
|
|
Packit Service |
96b5d3 |
#undef _ET_
|
|
Packit Service |
96b5d3 |
{ NULL, NULL }
|
|
Packit Service |
96b5d3 |
};
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
typedef enum {
|
|
Packit Service |
96b5d3 |
#define _ET_(n) n ## _IDX,
|
|
Packit Service |
96b5d3 |
ENV_TABLE
|
|
Packit Service |
96b5d3 |
#undef _ET_
|
|
Packit Service |
96b5d3 |
NAME_CT
|
|
Packit Service |
96b5d3 |
} name_idx_t;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
#define cgi_method name_val_map[ REQUEST_METHOD_IDX ].cgi_val
|
|
Packit Service |
96b5d3 |
#define cgi_query name_val_map[ QUERY_STRING_IDX ].cgi_val
|
|
Packit Service |
96b5d3 |
#define cgi_len name_val_map[ CONTENT_LENGTH_IDX ].cgi_val
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
static inline char *
|
|
Packit Service |
96b5d3 |
parse_input(char * src, int len)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
size_t rsz = (len * 4) + PARSE_INPUT_AG_DEF_STR_LEN;
|
|
Packit Service |
96b5d3 |
char * res = AGALOC(rsz, "CGI Defs");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
memcpy(res, PARSE_INPUT_AG_DEF_STR, PARSE_INPUT_AG_DEF_STR_LEN);
|
|
Packit Service |
96b5d3 |
(void)cgi_run_fsm(src, len, res + PARSE_INPUT_AG_DEF_STR_LEN, len * 2);
|
|
Packit Service |
96b5d3 |
assert(rsz > strlen(res));
|
|
Packit Service |
96b5d3 |
return AGREALOC(res, strlen(res)+1, "CGI input");
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
LOCAL void
|
|
Packit Service |
96b5d3 |
load_cgi(void)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Redirect stderr to a file. If it gets used, we must trap it
|
|
Packit Service |
96b5d3 |
* and emit the content-type: preamble before actually emitting it.
|
|
Packit Service |
96b5d3 |
* First, tho, do a simple stderr->stdout redirection just in case
|
|
Packit Service |
96b5d3 |
* we stumble before we're done with this.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
dup2(STDOUT_FILENO, STDERR_FILENO);
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
FILE * fp = fdopen(STDERR_FILENO, "w" FOPEN_BINARY_FLAG);
|
|
Packit Service |
96b5d3 |
(void)fp;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
int tmpfd;
|
|
Packit Service |
96b5d3 |
oops_pfx = CGI_ERR_MSG_FMT;
|
|
Packit Service |
96b5d3 |
AGDUPSTR(cgi_stderr, CGI_TEMP_ERR_FILE_STR, "stderr file");
|
|
Packit Service |
96b5d3 |
tmpfd = mkstemp(cgi_stderr);
|
|
Packit Service |
96b5d3 |
if (tmpfd < 0)
|
|
Packit Service |
96b5d3 |
AG_ABEND(aprf(MKSTEMP_FAIL_FMT, cgi_stderr));
|
|
Packit Service |
96b5d3 |
dup2(tmpfd, STDERR_FILENO);
|
|
Packit Service |
96b5d3 |
close(tmpfd);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Pull the CGI-relevant environment variables. Anything we don't find
|
|
Packit Service |
96b5d3 |
* gets an empty string default.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
name_map_t * nm_map = name_val_map;
|
|
Packit Service |
96b5d3 |
name_idx_t ix = (name_idx_t)0;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
do {
|
|
Packit Service |
96b5d3 |
nm_map->cgi_val = getenv(nm_map->name);
|
|
Packit Service |
96b5d3 |
if (nm_map->cgi_val == NULL)
|
|
Packit Service |
96b5d3 |
nm_map->cgi_val = (char *)zNil;
|
|
Packit Service |
96b5d3 |
} while (nm_map++, ++ix < NAME_CT);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
base_ctx = (scan_ctx_t *)AGALOC(sizeof(scan_ctx_t), "CGI ctx");
|
|
Packit Service |
96b5d3 |
memset(VOIDP(base_ctx), 0, sizeof(scan_ctx_t));
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
size_t len = strtoul(cgi_len, NULL, 0);
|
|
Packit Service |
96b5d3 |
char * text;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (strcasecmp(cgi_method, "POST") == 0) {
|
|
Packit Service |
96b5d3 |
if (len == 0)
|
|
Packit Service |
96b5d3 |
AG_ABEND(LOAD_CGI_NO_DATA_MSG);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
text = AGALOC(len + 1, "CGI POST");
|
|
Packit Service |
96b5d3 |
if (fread(text, (size_t)1, len, stdin) != len)
|
|
Packit Service |
96b5d3 |
AG_CANT(LOAD_CGI_READ_NAME, LOAD_CGI_READ_WHAT);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
text[ len ] = NUL;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
base_ctx->scx_data = parse_input(text, (int)len);
|
|
Packit Service |
96b5d3 |
AGFREE(text);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
} else if (strcasecmp(cgi_method, LOAD_CGI_GET_NAME) == 0) {
|
|
Packit Service |
96b5d3 |
if (len == 0)
|
|
Packit Service |
96b5d3 |
len = strlen(cgi_query);
|
|
Packit Service |
96b5d3 |
base_ctx->scx_data = parse_input(cgi_query, (int)len);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
} else {
|
|
Packit Service |
96b5d3 |
AG_ABEND(aprf(LOAD_CGI_INVAL_REQ_FMT, cgi_method));
|
|
Packit Service |
96b5d3 |
/* NOTREACHED */
|
|
Packit Service |
96b5d3 |
#ifdef WARNING_WATCH
|
|
Packit Service |
96b5d3 |
text = NULL;
|
|
Packit Service |
96b5d3 |
#endif
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
base_ctx->scx_line = 1;
|
|
Packit Service |
96b5d3 |
base_ctx->scx_fname = LOAD_CGI_DEFS_MARKER;
|
|
Packit Service |
96b5d3 |
base_ctx->scx_scan = base_ctx->scx_data;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Local Variables:
|
|
Packit Service |
96b5d3 |
* mode: C
|
|
Packit Service |
96b5d3 |
* c-file-style: "stroustrup"
|
|
Packit Service |
96b5d3 |
* indent-tabs-mode: nil
|
|
Packit Service |
96b5d3 |
* End:
|
|
Packit Service |
96b5d3 |
* end of agen5/agCgi.c */
|