. Reformatted some c-code
[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 <ctype.h>
25 #include <malloc.h>
26 #include <cgi.h>
27
28 int cgiDebugLevel = 0;
29 int cgiDebugStderr = 1;
30
31 void cgiHeader ()
32 {
33     printf ("Content-type: text/html\n\n");
34 }
35
36 void cgiDebug (int level, int where)
37 {
38     if (level > 0)
39         cgiDebugLevel = level;
40     else
41         cgiDebugLevel = 0;
42     if (where)
43         cgiDebugStderr = 0;
44     else
45         cgiDebugStderr = 1;
46 }
47
48 char *cgiDecodeString (char *text)
49 {
50     char *cp, *xp;
51
52     for (cp=text,xp=text; *cp; cp++) {
53         if (*cp == '%') {
54             if (strchr("0123456789ABCDEFabcdef", *(cp+1))
55                 && strchr("0123456789ABCDEFabcdef", *(cp+2))) {
56                 if (islower(*(cp+1)))
57                     *(cp+1) = toupper(*(cp+1));
58                 if (islower(*(cp+2)))
59                     *(cp+2) = toupper(*(cp+2));
60                 *(xp) = (*(cp+1) >= 'A' ? *(cp+1) - 'A' + 10 : *(cp+1) - '0' ) * 16
61                     + (*(cp+2) >= 'A' ? *(cp+2) - 'A' + 10 : *(cp+2) - '0');
62                 xp++;cp+=2;
63             }
64         } else {
65             *(xp++) = *cp;
66         }
67     }
68     bzero(xp, cp-xp);
69     return text;
70 }
71
72 /*  cgiInit()
73  *
74  *  Read from stdin if no string is provided via CGI.  Variables that
75  *  doesn't have a value associated with it doesn't get stored.
76  */
77 s_cgi **cgiInit ()
78 {
79     int length;
80     char *line;
81     int numargs;
82     char *cp, *ip, *esp;
83     s_cgi **result;
84     int i;
85     char tmp[101];
86
87     line = getenv("CONTENT_LENGTH");
88
89     if (line){
90         length = atoi(line);
91         if ((line = (char *)malloc (length+2)) == NULL)
92             return NULL;
93         fgets(line, length+1, stdin);
94     } else {
95         if (!getenv("REQUEST_METHOD")) {
96             length = 0;
97             printf ("(offline mode: enter name=value pairs on standard input)\n");
98             for (cp = fgets(tmp, 100, stdin); cp != NULL;
99                  cp = fgets(tmp, 100, stdin) ) {
100                 if (strlen(tmp)) {
101                     length += strlen(tmp);
102                     if ((ip = (char *)malloc (length * sizeof(char))) == NULL)
103                         return NULL;
104                     bzero(ip, length);
105                     if (line) {
106                         if (line[strlen(line)-1] == '\n')
107                             line[strlen(line)-1] = '&';
108                         strcpy(ip, line);
109                     }
110                     ip = strcat(ip, tmp);
111                     if (line)
112                         free (line);
113                     line = ip;
114                 }
115             } /* for */
116             if (line[strlen(line)-1] == '\n')
117                 line[strlen(line)-1] = '\0';
118         } else
119             return NULL;
120     }
121     /* line now contains all values stored like foo=bar&foobar=barfoo&foofoo= */
122
123     if (cgiDebugLevel > 0)
124         if (cgiDebugStderr)
125             fprintf (stderr, "Received cgi input: %s\n", line);
126         else
127             printf ("<b>Received cgi input</b><br>\n<pre>\n--\n%s\n--\n</pre>\n\n", line);
128
129     for (cp=line; *cp; cp++)
130         if (*cp == '+')
131             *cp = ' ';
132
133     if (strlen(line)) {
134         for (numargs=1,cp=line; *cp; cp++)
135             if (*cp == '&') numargs++;
136     } else
137         numargs = 0;
138     if (cgiDebugLevel > 0)
139         if (cgiDebugStderr)
140             fprintf (stderr, "%d cgi variables found.\n", numargs);
141         else
142             printf ("%d cgi variables found.<br>\n", numargs);
143
144     if ((result = (s_cgi **)malloc((numargs+1) * sizeof(s_cgi *))) == NULL)
145         return NULL;
146     bzero (result, (numargs+1) * sizeof(s_cgi *));
147
148     cp = line;
149     i=0;
150     while (*cp) {
151         if ((ip = (char *)index(cp, '&')) != NULL) {
152             *ip = '\0';
153         }else
154             ip = cp + strlen(cp);
155
156         if ((esp=(char *)index(cp, '=')) == NULL) {
157             cp = ++ip;
158             continue;
159         }
160
161         if (!strlen(esp)) {
162             cp = ++ip;
163             continue;
164         }
165
166         if (i<numargs) {
167             if ((result[i] = (s_cgi *)malloc(sizeof(s_cgi))) == NULL)
168                 return NULL;
169             if ((result[i]->name = (char *)malloc((esp-cp+1) * sizeof(char))) == NULL)
170                 return NULL;
171             bzero (result[i]->name, esp-cp+1);
172             strncpy(result[i]->name, cp, esp-cp);
173             cp = ++esp;
174             if ((result[i]->value = (char *)malloc((ip-esp+1) * sizeof(char))) == NULL)
175                 return NULL;
176             bzero (result[i]->value, ip-esp+1);
177             strncpy(result[i]->value, cp, ip-esp);
178             result[i]->value = cgiDecodeString(result[i]->value);
179             if (cgiDebugLevel) {
180                 if (cgiDebugStderr)
181                     fprintf (stderr, "%s: %s\n", result[i]->name, result[i]->value);
182                 else
183                     printf ("<h3>Variable %s</h3>\n<pre>\n%s\n</pre>\n\n", result[i]->name, result[i]->value);
184             }
185             i++;
186         }
187         cp = ++ip;
188     }
189     return result;
190 }
191
192 char *cgiGetValue(s_cgi **parms, const char *var)
193 {
194     int i;
195
196     if (parms)
197         for (i=0;parms[i]; i++)
198             if (!strcmp(var,parms[i]->name)) {
199                 if (cgiDebug)
200                     if (cgiDebugStderr)
201                         fprintf (stderr, "%s found as %s\n", var, parms[i]->value);
202                     else
203                         printf ("%s found as %s<br>\n", var, parms[i]->value);
204                 return parms[i]->value;
205             }
206     if (cgiDebug)
207         if (cgiDebugStderr)
208             fprintf (stderr, "%s not found\n", var);
209         else
210             printf ("%s not found<br>\n", var);
211
212     return NULL;
213 }
214
215 /*
216  * Local variables:
217  *  c-indent-level: 4
218  *  c-basic-offset: 4
219  *  tab-width: 8
220  * End:
221  */