/** ** Copyright (C) 1994, 1995 Enterprise Integration Technologies Corp. ** VeriFone Inc./Hewlett-Packard. All Rights Reserved. ** Kevin Hughes, kev@kevcom.com 3/11/94 ** Kent Landfield, kent@landfield.com 4/6/97 ** ** This program and library is free software; you can redistribute it and/or ** modify it under the terms of the GNU (Library) General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or 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 (Library) General Public License for more details. ** ** You should have received a copy of the GNU (Library) General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This file is part of the LIBCGI library * */ #include "cgi.h" #define LF 10 #define CR 13 #define STARTSIZE 8 form_entry *get_form_entries(cgi_info *ci) { if (ci && ci->request_method && !strncasecmp(ci->request_method, "POST", 4) && ci->content_type && !strncasecmp(ci->content_type, "application/x-www-form-urlencoded", 33)) return get_fes_from_stream(ci->content_length, stdin); else if (ci && ci->request_method && !strncasecmp(ci->request_method, "GET", 3)) return get_fes_from_string(ci->query_string); else return NULL; } void free_form_entries(form_entry *fe) { form_entry *tempfe; while (fe) { if (fe->name) free(fe->name); if (fe->val) free(fe->val); tempfe = fe->next; free(fe); fe = tempfe; } } char *parmval(form_entry *fe, char *s) { while (fe) { if (!strcasecmp(fe->name, s)) return fe->val; else fe = fe->next; } return NULL; } form_entry *get_fes_from_string(char *s) { form_entry *fe; int asize; int i; if (s == NULL) return NULL; while (isspace(*s) || *s == '&') s++; /* some cases that shouldn't happen */ if (*s == '\0') return NULL; fe = (form_entry *)malloc(sizeof(form_entry)); if (fe == NULL) return NULL; fe->name = malloc((asize = STARTSIZE * sizeof(char))); if (fe->name == NULL) { free(fe); return NULL; } /* get form field name */ for (i = 0; *s && *s != '&' && *s != '='; s++, i++) { switch (*s) { case '+': fe->name[i] = ' '; break; case '%': fe->name[i] = dd2c(s[1], s[2]); s += 2; break; default: fe->name[i] = *s; } if (i + 1 >= asize) { /* try to double the buffer */ fe->name = realloc(fe->name, (asize *= 2)); if (fe->name == NULL) return NULL; } } fe->name[i] = '\0'; switch (*s++) { case '&': fe->val = NULL; break; case '=': fe->val = malloc((asize = STARTSIZE * sizeof(char))); if (fe->val == NULL) break; for (i = 0; *s && *s != '&'; s++, i++) { switch (*s) { case '+': fe->val[i] = ' '; break; case '%': fe->val[i] = dd2c(s[1], s[2]); s += 2; break; default: fe->val[i] = *s; } if (i + 1 >= asize) { /* try to double the buffer */ fe->val = realloc(fe->val, (asize *= 2)); if (fe->val == NULL) return NULL; } } fe->val[i] = '\0'; switch (*s++) { case '&': fe->next = get_fes_from_string(s); break; case '\0': default: fe->next = NULL; } break; case '\0': default: fe->val = NULL; fe->next = NULL; } return fe; } #define getccl(s, l) (l-- ? getc(s) : EOF) form_entry *get_fes_from_stream(int length, FILE *stream) { form_entry *fe; int asize; int i; int c; int c1, c2; while (isspace(c = getccl(stream, length)) || c == '&'); if (c == EOF) return NULL; fe = (form_entry *)malloc(sizeof(form_entry)); if (fe == NULL) return NULL; fe->name = malloc((asize = STARTSIZE * sizeof(char))); if (fe->name == NULL) { free(fe); return NULL; } /* get form field name */ for (i = 0; c != EOF && c != '&' && c != '='; c = getccl(stream, length), i++) { switch (c) { case '+': fe->name[i] = ' '; break; case '%': c1 = getccl(stream, length); c2 = getccl(stream, length); fe->name[i] = dd2c(c1, c2); break; default: fe->name[i] = c; } if (i + 1 >= asize) { /* try to double the buffer */ fe->name = realloc(fe->name, (asize *= 2)); if (fe->name == NULL) return NULL; } } fe->name[i] = '\0'; if (c == EOF) { fe->val = NULL; fe->next = NULL; } else switch (c) { case '&': fe->val = NULL; break; case '=': fe->val = malloc((asize = STARTSIZE * sizeof(char))); for (i = 0, c = getccl(stream, length); c != EOF && c != '&'; c = getccl(stream, length), i++) { switch (c) { case '+': fe->val[i] = ' '; break; case '%': c1 = getccl(stream, length); c2 = getccl(stream, length); fe->val[i] = dd2c(c1, c2); break; default: fe->val[i] = c; } if (i + 1 >= asize) { /* try to double the buffer */ fe->val = realloc(fe->val, (asize *= 2)); if (fe->val == NULL) return NULL; } } fe->val[i] = '\0'; if (c == '&') { fe->next = get_fes_from_stream(length, stream); } else fe->next = NULL; } return fe; } unsigned char dd2c(char d1, char d2) { register unsigned char digit; digit = (d1 >= 'A' ? ((d1 & 0xdf) - 'A') + 10 : (d1 - '0')); digit *= 16; digit += (d2 >= 'A' ? ((d2 & 0xdf) - 'A') + 10 : (d2 - '0')); return (digit); } void dump_cgi_info(cgi_info *ci) { printf("CONTENT_LENGTH: %d\n", ci->content_length); if (ci->content_type != NULL) printf("
CONTENT_TYPE: %s\n", ci->content_type); if (ci->server_name != NULL) printf("
SERVER_NAME: %s\n", ci->server_name); if (ci->server_software != NULL) printf("
SERVER_SOFTWARE: %s\n", ci->server_software); if (ci->gateway_interface != NULL) printf("
GATEWAY_INTERFACE: %s\n", ci->gateway_interface); if (ci->server_protocol != NULL) printf("
SERVER_PROTOCOL: %s\n", ci->server_protocol); if (ci->server_port != NULL) printf("
SERVER_PORT: %s\n", ci->server_port); if (ci->request_method != NULL) printf("
REQUEST_METHOD: %s\n", ci->request_method); if (ci->http_accept != NULL) printf("
HTTP_ACCEPT: %s\n", ci->http_accept); if (ci->path_info != NULL) printf("
PATH_INFO: %s\n", ci->path_info); if (ci->path_translated != NULL) printf("
PATH_TRANSLATED: %s\n", ci->path_translated); if (ci->script_name != NULL) printf("
SCRIPT_NAME: %s\n", ci->script_name); if (ci->query_string != NULL) printf("
QUERY_STRING: %s\n", ci->query_string); if (ci->remote_host != NULL) printf("
REMOTE_HOST: %s\n", ci->remote_host); if (ci->remote_addr != NULL) printf("
REMOTE_ADDR: %s\n", ci->remote_addr); if (ci->auth_type != NULL) printf("
AUTH_TYPE: %s\n", ci->auth_type); if (ci->remote_user != NULL) printf("
REMOTE_USER: %s\n", ci->remote_user); if (ci->remote_ident != NULL) printf("
REMOTE_IDENT: %s\n", ci->remote_ident); return; }