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