/*
some simple CGI helper routines
Copyright (C) Andrew Tridgell 1997-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "includes.h"
#include "system/passwd.h"
#include "system/filesys.h"
#include "web/swat_proto.h"
#define MAX_VARIABLES 10000
/* set the expiry on fixed pages */
#define EXPIRY_TIME (60*60*24*7)
#ifdef DEBUG_COMMENTS
extern void print_title(char *fmt, ...);
#endif
struct cgi_var {
char *name;
char *value;
};
static struct cgi_var variables[MAX_VARIABLES];
static int num_variables;
static int content_length;
static int request_post;
static char *query_string;
static const char *baseurl;
static char *pathinfo;
static char *C_user;
static bool inetd_server;
static bool got_request;
static char *grab_line(FILE *f, int *cl)
{
char *ret = NULL;
int i = 0;
int len = 0;
while ((*cl)) {
int c;
if (i == len) {
char *ret2;
if (len == 0) len = 1024;
else len *= 2;
ret2 = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR(ret, len);
if (!ret2) return ret;
ret = ret2;
}
c = fgetc(f);
(*cl)--;
if (c == EOF) {
(*cl) = 0;
break;
}
if (c == '\r') continue;
if (strchr_m("\n&", c)) break;
ret[i++] = c;
}
if (ret) {
ret[i] = 0;
}
return ret;
}
/**
URL encoded strings can have a '+', which should be replaced with a space
(This was in rfc1738_unescape(), but that broke the squid helper)
**/
static void plus_to_space_unescape(char *buf)
{
char *p=buf;
while ((p=strchr_m(p,'+')))
*p = ' ';
}
/***************************************************************************
load all the variables passed to the CGI program. May have multiple variables
with the same name and the same or different values. Takes a file parameter
for simulating CGI invocation eg loading saved preferences.
***************************************************************************/
void cgi_load_variables(void)
{
static char *line;
char *p, *s, *tok;
int len, i;
FILE *f = stdin;
#ifdef DEBUG_COMMENTS
char dummy[100]="";
print_title(dummy);
d_printf("\n",__FILE__);
#endif
if (!content_length) {
p = getenv("CONTENT_LENGTH");
len = p?atoi(p):0;
} else {
len = content_length;
}
if (len > 0 &&
(request_post ||
((s=getenv("REQUEST_METHOD")) &&
strequal(s,"POST")))) {
while (len && (line=grab_line(f, &len))) {
p = strchr_m(line,'=');
if (!p) continue;
*p = 0;
variables[num_variables].name = SMB_STRDUP(line);
variables[num_variables].value = SMB_STRDUP(p+1);
SAFE_FREE(line);
if (!variables[num_variables].name ||
!variables[num_variables].value)
continue;
plus_to_space_unescape(variables[num_variables].value);
rfc1738_unescape(variables[num_variables].value);
plus_to_space_unescape(variables[num_variables].name);
rfc1738_unescape(variables[num_variables].name);
#ifdef DEBUG_COMMENTS
printf("\n",
variables[num_variables].name,
variables[num_variables].value);
#endif
num_variables++;
if (num_variables == MAX_VARIABLES) break;
}
}
fclose(stdin);
open("/dev/null", O_RDWR);
if ((s=query_string) || (s=getenv("QUERY_STRING"))) {
char *saveptr;
for (tok=strtok_r(s, "&;", &saveptr); tok;
tok=strtok_r(NULL, "&;", &saveptr)) {
p = strchr_m(tok,'=');
if (!p) continue;
*p = 0;
variables[num_variables].name = SMB_STRDUP(tok);
variables[num_variables].value = SMB_STRDUP(p+1);
if (!variables[num_variables].name ||
!variables[num_variables].value)
continue;
plus_to_space_unescape(variables[num_variables].value);
rfc1738_unescape(variables[num_variables].value);
plus_to_space_unescape(variables[num_variables].name);
rfc1738_unescape(variables[num_variables].name);
#ifdef DEBUG_COMMENTS
printf("\n",
variables[num_variables].name,
variables[num_variables].value);
#endif
num_variables++;
if (num_variables == MAX_VARIABLES) break;
}
}
#ifdef DEBUG_COMMENTS
printf("\n");
#endif
/* variables from the client are in UTF-8 - convert them
to our internal unix charset before use */
for (i=0;i%s%s
%s