. cgiDebug() und cgiDebugLevel eingefuehrt
[infodrom/cgilib] / cgi.c
1 /*
2     cgi.c - Some simple routines for cgi programming
3     Copyright (c) 1996-8  Martin Schulze <joey@infodrom.north.de>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <malloc.h>
25 #include <cgi.h>
26
27 int cgiDebugLevel = 0;
28 int cgiDebugStderr = 1;
29
30 void cgiHeader ()
31 {
32     printf ("Content-type: text/html\n\n");
33 }
34
35 void cgiDebug (int level, int where)
36 {
37     if (level > 0)
38         cgiDebugLevel = level;
39     else
40         cgiDebugLevel = 0;
41     if (where)
42         cgiDebugStderr = 0;
43     else
44         cgiDebugStderr = 1;
45 }
46
47 char *cgiDecodeString (char *text)
48 {
49     char *cp, *xp;
50
51     for (cp=text,xp=text; *cp; cp++) {
52         if (*cp == '%') {
53             if (strchr("0123456789ABCDEFabcdef", *(cp+1))
54                 && strchr("0123456789ABCDEFabcdef", *(cp+2))) {
55                 if (islower(*(cp+1)))
56                     *(cp+1) = toupper(*(cp+1));
57                 if (islower(*(cp+2)))
58                     *(cp+2) = toupper(*(cp+2));
59                 *(xp) = (*(cp+1) >= 'A' ? *(cp+1) - 'A' + 10 : *(cp+1) - '0' ) * 16
60                     + (*(cp+2) >= 'A' ? *(cp+2) - 'A' + 10 : *(cp+2) - '0');
61                 xp++;cp+=2;
62             }
63         } else {
64             *(xp++) = *cp;
65         }
66     }
67     bzero(xp, cp-xp);
68     return text;
69 }
70
71 /*  cgiInit()
72  *
73  *  Read from stdin if no string is provided via CGI.  Variables that
74  *  doesn't have a value associated with it doesn't get stored.
75  */
76 s_cgi **cgiInit ()
77 {
78     int length;
79     char *line;
80     int numargs;
81     char *cp, *ip, *esp;
82     s_cgi **result, *var;
83     int i;
84     char tmp[101];
85
86     line = getenv("CONTENT_LENGTH");
87
88     if (line){
89         length = atoi(line);
90         if ((line = (char *)malloc (length+2)) == NULL)
91             return NULL;
92         fgets(line, length+1, stdin);
93     } else {
94         if (!getenv("REQUEST_METHOD")) {
95             length = 0;
96             printf ("(offline mode: enter name=value pairs on standard input)\n");
97             for (cp = fgets(tmp, 100, stdin); cp != NULL;
98                  cp = fgets(tmp, 100, stdin) ) {
99                 if (strlen(tmp)) {
100                     length += strlen(tmp);
101                     if ((ip = (char *)malloc (length * sizeof(char))) == NULL)
102                         return NULL;
103                     bzero(ip, length);
104                     if (line) {
105                         if (line[strlen(line)-1] == '\n')
106                             line[strlen(line)-1] = '&';
107                         strcpy(ip, line);
108                     }
109                     ip = strcat(ip, tmp);
110                     if (line)
111                         free (line);
112                     line = ip;
113                 }
114             } /* for */
115             if (line[strlen(line)-1] == '\n')
116                 line[strlen(line)-1] = '\0';
117         } else
118             return NULL;
119     }
120     /* line now contains all values stored like foo=bar&foobar=barfoo&foofoo= */
121
122     if (cgiDebugLevel > 0)
123         if (cgiDebugStderr)
124             fprintf (stderr, "Received cgi input: %s\n", line);
125         else
126             printf ("<b>Received cgi input</b><br>\n<pre>\n--\n%s\n--\n</pre>\n\n", line);
127
128     for (cp=line; *cp; cp++)
129         if (*cp == '+')
130             *cp = ' ';
131
132     if (strlen(line)) {
133         for (numargs=1,cp=line; *cp; cp++)
134             if (*cp == '&') numargs++;
135     } else
136         numargs = 0;
137     if (cgiDebugLevel > 0)
138         if (cgiDebugStderr)
139             fprintf (stderr, "%d cgi variables found.\n", numargs);
140         else
141             printf ("%d cgi variables found.<br>\n", numargs);
142
143     if ((result = (s_cgi **)malloc((numargs+1) * sizeof(s_cgi *))) == NULL)
144         return NULL;
145     bzero (result, (numargs+1) * sizeof(s_cgi *));
146
147     cp = line;
148     i=0;
149     while (*cp) {
150         if ((ip = (char *)index(cp, '&')) != NULL) {
151             *ip = '\0';
152         }else
153             ip = cp + strlen(cp);
154
155         if ((esp=(char *)index(cp, '=')) == NULL) {
156             cp = ++ip;
157             continue;
158         }
159
160         if (!strlen(esp)) {
161             cp = ++ip;
162             continue;
163         }
164
165         if (i<numargs) {
166             if ((result[i] = (s_cgi *)malloc(sizeof(s_cgi))) == NULL)
167                 return NULL;
168             if ((result[i]->name = (char *)malloc((esp-cp+1) * sizeof(char))) == NULL)
169                 return NULL;
170             bzero (result[i]->name, esp-cp+1);
171             strncpy(result[i]->name, cp, esp-cp);
172             cp = ++esp;
173             if ((result[i]->value = (char *)malloc((ip-esp+1) * sizeof(char))) == NULL)
174                 return NULL;
175             bzero (result[i]->value, ip-esp+1);
176             strncpy(result[i]->value, cp, ip-esp);
177             result[i]->value = cgiDecodeString(result[i]->value);
178             if (cgiDebugLevel) {
179                 if (cgiDebugStderr)
180                     fprintf (stderr, "%s: %s\n", result[i]->name, result[i]->value);
181                 else
182                     printf ("<h3>Variable %s</h3>\n<pre>\n%s\n</pre>\n\n", result[i]->name, result[i]->value);
183             }
184             i++;
185         }
186         cp = ++ip;
187     }
188     return result;
189 }
190
191 char *cgiGetValue(s_cgi **parms, const char *var)
192 {
193   int i;
194
195   if (parms)
196     for (i=0;parms[i]; i++)
197       if (!strcmp(var,parms[i]->name))
198         return parms[i]->value;
199   return NULL;
200 }
201
202 /*
203  * Local variables:
204  *  c-indent-level: 4
205  *  c-basic-offset: 4
206  *  tab-width: 8
207  * End:
208  */