67e0b4c03f89b4d6bc421c28a6be2a3f8f44d029
[swftools.git] / lib / modules / swfcgi.c
1 /* swfcgi.c
2
3    Parse CGI parameters
4    
5    Partly adopted from Steven Grimm's uncgi tool and library.
6
7    Extension module for the rfxswf library.
8    Part of the swftools package.
9
10    Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
11  
12    This file is distributed under the GPL, see file COPYING for details 
13
14 */
15
16
17 #define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
18
19 #define PREFIX "WWW_"
20
21 static int swf_htoi(unsigned char * s)
22 { int     value;
23   char    c;
24
25   c = s[0];
26   if (isupper(c)) c = tolower(c);
27   value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
28
29   c = s[1];
30   if (isupper(c)) c = tolower(c);
31   value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
32
33   return (value);
34 }
35
36 static void swf_url_unescape(unsigned char * s)
37 { unsigned char  *dest = s;
38
39   while (s[0])
40   { if (s[0] == '+') dest[0] = ' ';
41     else
42     { if (s[0] == '%' && ishex(s[1]) && ishex(s[2]))
43       { dest[0] = (unsigned char) swf_htoi(s + 1);
44         s += 2;
45       }
46       else dest[0] = s[0];
47     }
48     s++;dest++;
49   }
50   dest[0] = 0;
51 }
52
53 static void swf_cgienv(unsigned char * var)
54 { unsigned char *buf, *c, *s, *t, *oldval = NULL, *newval;
55   int despace = 0, got_cr = 0;
56
57   // fprintf(stderr,"%s\n",var);
58   swf_url_unescape(var);
59   // fprintf(stderr,"%s\n",var);
60
61   
62   buf = (unsigned char*)malloc(strlen(var) + sizeof(PREFIX) + 2);
63   if (!buf) return;
64
65   strcpy(buf, PREFIX);
66   if (var[0] == '_')
67   { strcpy(&buf[sizeof(PREFIX)-1], &var[1]);
68     despace = 1;
69   }
70   else strcpy(&buf[sizeof(PREFIX)-1], var);
71
72   for (c = buf; c[0] ; c++)
73   { if (c[0] == '.') c[0] = '_';
74     if (c[0] == '=') break;
75   }
76   if (!c[0]) c[1] = 0;
77   c[0] = 0;
78
79   if (despace && c[1])
80   { for (s = c+1; s[0] && isspace(s[0]); s++);
81     t = c + 1;
82     while (s[0])
83     { if (s[0] == '\r')
84       { got_cr = 1;
85         s++;
86         continue;
87       }
88       if (got_cr)
89       { if (s[0] != '\n')
90         *t++ = '\n';
91         got_cr = 0;
92       }
93       *t++ = *s++;
94     }
95     while (t > c && isspace(*--t));
96     t[1] = 0;
97   }
98
99   if ((oldval = getenv(buf)))
100   { newval = (unsigned char*)malloc(strlen(oldval) + strlen(buf) + strlen(&c[1]) + 3);
101     if (!newval) return;
102
103     c[0] = '=';
104     sprintf(newval, "%s#%s", buf, oldval);
105     c[0] = 0;
106
107     oldval -= strlen(buf) + 1; // skip past VAR= 
108   }
109   else 
110   { c[0] = '=';
111     newval = buf;
112   }
113   
114   putenv(newval);
115         
116   if (oldval)
117   { free(oldval);
118     free(buf);
119   }
120 }
121
122 static void swf_scanquery(char * q)
123 { char *next = q;
124   if (!q) return;
125
126   while (next)
127   { next = strchr(q, '&');
128     if (next) next[0] = 0;
129     swf_cgienv(q);
130     if (next)
131     { next[0] = '&';
132       q = next+1;
133     }
134   } 
135 }
136
137 char * swf_postread()
138 { char * buf = NULL;
139   int size = 0, sofar = 0, got;
140
141   buf = getenv("CONTENT_TYPE");
142   if ((!buf) || strcmp(buf, "application/x-www-form-urlencoded")) return NULL;
143
144   buf = getenv("CONTENT_LENGTH");
145   if (!buf) return NULL;
146         
147   size = atoi(buf);
148   buf = (unsigned char*)malloc(size + 1);
149   if (buf)
150   { do
151     { got = fread(buf + sofar, 1, size - sofar, stdin);
152       sofar += got;
153     } while (got && sofar < size);
154     buf[sofar] = 0;
155   }
156
157   return buf;
158 }
159
160 void swf_uncgi()
161 { char *query, *dupquery, *method;
162
163   query = getenv("QUERY_STRING");
164   if ((query) && strlen(query))
165   { dupquery = strdup(query);
166     swf_scanquery(dupquery);
167     free(dupquery);
168   }
169
170   method = getenv("REQUEST_METHOD");
171   if ((method) && ! strcmp(method, "POST"))
172   { query = swf_postread();
173     if ((query)&&(query[0]!=0)) swf_scanquery(query);
174     free(query);
175   }
176   
177 }
178       
179 #undef ishex
180 #undef PREFIX