-/* swfcgi.c\r
-\r
- Parse CGI parameters\r
- \r
- Partly adopted from Steven Grimm's uncgi tool and library.\r
-\r
- Extension module for the rfxswf library.\r
- Part of the swftools package.\r
-\r
- Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
- \r
- This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-\r
-#define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))\r
-\r
-#define PREFIX "WWW_"\r
-\r
-static int htoi(unsigned char * s)\r
-{ int value;\r
- char c;\r
-\r
- c = s[0];\r
- if (isupper(c)) c = tolower(c);\r
- value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;\r
-\r
- c = s[1];\r
- if (isupper(c)) c = tolower(c);\r
- value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;\r
-\r
- return (value);\r
-}\r
-\r
-static void url_unescape(unsigned char * s)\r
-{ unsigned char *dest = s;\r
-\r
- while (s[0])\r
- { if (s[0] == '+') dest[0] = ' ';\r
- else\r
- { if (s[0] == '%' && ishex(s[1]) && ishex(s[2]))\r
- { dest[0] = (unsigned char) htoi(s + 1);\r
- s += 2;\r
- }\r
- else dest[0] = s[0];\r
- }\r
- s++;dest++;\r
- }\r
- dest[0] = 0;\r
-}\r
-\r
-static void cgienv(unsigned char * var)\r
-{ unsigned char *buf, *c, *s, *t, *oldval = NULL, *newval;\r
- int despace = 0, got_cr = 0;\r
-\r
- // fprintf(stderr,"%s\n",var);\r
- url_unescape(var);\r
- // fprintf(stderr,"%s\n",var);\r
-\r
- \r
- buf = (unsigned char*)malloc(strlen(var) + sizeof(PREFIX) + 2);\r
- if (!buf) return;\r
-\r
- strcpy(buf, PREFIX);\r
- if (var[0] == '_')\r
- { strcpy(&buf[sizeof(PREFIX)-1], &var[1]);\r
- despace = 1;\r
- }\r
- else strcpy(&buf[sizeof(PREFIX)-1], var);\r
-\r
- for (c = buf; c[0] ; c++)\r
- { if (c[0] == '.') c[0] = '_';\r
- if (c[0] == '=') break;\r
- }\r
- if (!c[0]) c[1] = 0;\r
- c[0] = 0;\r
-\r
- if (despace && c[1])\r
- { for (s = c+1; s[0] && isspace(s[0]); s++);\r
- t = c + 1;\r
- while (s[0])\r
- { if (s[0] == '\r')\r
- { got_cr = 1;\r
- s++;\r
- continue;\r
- }\r
- if (got_cr)\r
- { if (s[0] != '\n')\r
- *t++ = '\n';\r
- got_cr = 0;\r
- }\r
- *t++ = *s++;\r
- }\r
- while (t > c && isspace(*--t));\r
- t[1] = 0;\r
- }\r
-\r
- if ((oldval = getenv(buf)))\r
- { newval = (unsigned char*)malloc(strlen(oldval) + strlen(buf) + strlen(&c[1]) + 3);\r
- if (!newval) return;\r
-\r
- c[0] = '=';\r
- sprintf(newval, "%s#%s", buf, oldval);\r
- c[0] = 0;\r
-\r
- oldval -= strlen(buf) + 1; // skip past VAR= \r
- }\r
- else \r
- { c[0] = '=';\r
- newval = buf;\r
- }\r
- \r
- putenv(newval);\r
- \r
- if (oldval)\r
- { free(oldval);\r
- free(buf);\r
- }\r
-}\r
-\r
-static void scanquery(char * q)\r
-{ char *next = q;\r
- if (!q) return;\r
-\r
- while (next)\r
- { next = strchr(q, '&');\r
- if (next) next[0] = 0;\r
- cgienv(q);\r
- if (next)\r
- { next[0] = '&';\r
- q = next+1;\r
- }\r
- } \r
-}\r
-\r
-char * postread()\r
-{ char * buf = NULL;\r
- int size = 0, sofar = 0, got;\r
-\r
- buf = getenv("CONTENT_TYPE");\r
- if ((!buf) || strcmp(buf, "application/x-www-form-urlencoded")) return NULL;\r
-\r
- buf = getenv("CONTENT_LENGTH");\r
- if (!buf) return NULL;\r
- \r
- size = atoi(buf);\r
- buf = (unsigned char*)malloc(size + 1);\r
- if (buf)\r
- { do\r
- { got = fread(buf + sofar, 1, size - sofar, stdin);\r
- sofar += got;\r
- } while (got && sofar < size);\r
- buf[sofar] = 0;\r
- }\r
-\r
- return buf;\r
-}\r
-\r
-void uncgi()\r
-{ char *query, *dupquery, *method;\r
-\r
- query = getenv("QUERY_STRING");\r
- if ((query) && strlen(query))\r
- { dupquery = strdup(query);\r
- scanquery(dupquery);\r
- free(dupquery);\r
- }\r
-\r
- method = getenv("REQUEST_METHOD");\r
- if ((method) && ! strcmp(method, "POST"))\r
- { query = postread();\r
- if ((query)&&(query[0]!=0)) scanquery(query);\r
- free(query);\r
- }\r
- \r
-}\r
- \r
-#undef ishex\r
+/* swfcgi.c
+
+ Parse CGI parameters
+
+ Partly adopted from Steven Grimm's uncgi tool and library.
+
+ Extension module for the rfxswf library.
+ Part of the swftools package.
+
+ Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) 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 General Public License for more details.
+
+ You should have received a copy of the GNU 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 */
+
+
+#define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
+
+#define PREFIX "WWW_"
+
+static int swf_htoi(unsigned char * s)
+{ int value;
+ char c;
+
+ c = s[0];
+ if (isupper(c)) c = tolower(c);
+ value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
+
+ c = s[1];
+ if (isupper(c)) c = tolower(c);
+ value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
+
+ return (value);
+}
+
+static void swf_url_unescape(unsigned char * s)
+{ unsigned char *dest = s;
+
+ while (s[0])
+ { if (s[0] == '+') dest[0] = ' ';
+ else
+ { if (s[0] == '%' && ishex(s[1]) && ishex(s[2]))
+ { dest[0] = (unsigned char) swf_htoi(s + 1);
+ s += 2;
+ }
+ else dest[0] = s[0];
+ }
+ s++;dest++;
+ }
+ dest[0] = 0;
+}
+
+static void swf_cgienv(unsigned char * var)
+{ unsigned char *buf, *c, *s, *t, *oldval = NULL, *newval;
+ int despace = 0, got_cr = 0;
+
+ // fprintf(stderr,"%s\n",var);
+ swf_url_unescape(var);
+ // fprintf(stderr,"%s\n",var);
+
+
+ buf = (unsigned char*)malloc(strlen(var) + sizeof(PREFIX) + 2);
+ if (!buf) return;
+
+ strcpy(buf, PREFIX);
+ if (var[0] == '_')
+ { strcpy(&buf[sizeof(PREFIX)-1], &var[1]);
+ despace = 1;
+ }
+ else strcpy(&buf[sizeof(PREFIX)-1], var);
+
+ for (c = buf; c[0] ; c++)
+ { if (c[0] == '.') c[0] = '_';
+ if (c[0] == '=') break;
+ }
+ if (!c[0]) c[1] = 0;
+ c[0] = 0;
+
+ if (despace && c[1])
+ { for (s = c+1; s[0] && isspace(s[0]); s++);
+ t = c + 1;
+ while (s[0])
+ { if (s[0] == '\r')
+ { got_cr = 1;
+ s++;
+ continue;
+ }
+ if (got_cr)
+ { if (s[0] != '\n')
+ *t++ = '\n';
+ got_cr = 0;
+ }
+ *t++ = *s++;
+ }
+ while (t > c && isspace(*--t));
+ t[1] = 0;
+ }
+
+ if ((oldval = getenv(buf)))
+ { newval = (unsigned char*)malloc(strlen(oldval) + strlen(buf) + strlen(&c[1]) + 3);
+ if (!newval) return;
+
+ c[0] = '=';
+ sprintf(newval, "%s#%s", buf, oldval);
+ c[0] = 0;
+
+ oldval -= strlen(buf) + 1; // skip past VAR=
+ }
+ else
+ { c[0] = '=';
+ newval = buf;
+ }
+
+ putenv(newval);
+
+ if (oldval)
+ { free(oldval);
+ free(buf);
+ }
+}
+
+static void swf_scanquery(char * q)
+{ char *next = q;
+ if (!q) return;
+
+ while (next)
+ { next = strchr(q, '&');
+ if (next) next[0] = 0;
+ swf_cgienv(q);
+ if (next)
+ { next[0] = '&';
+ q = next+1;
+ }
+ }
+}
+
+char * swf_postread()
+{ char * buf = NULL;
+ int size = 0, sofar = 0, got;
+
+ buf = getenv("CONTENT_TYPE");
+ if ((!buf) || strcmp(buf, "application/x-www-form-urlencoded")) return NULL;
+
+ buf = getenv("CONTENT_LENGTH");
+ if (!buf) return NULL;
+
+ size = atoi(buf);
+ buf = (unsigned char*)malloc(size + 1);
+ if (buf)
+ { do
+ { got = fread(buf + sofar, 1, size - sofar, stdin);
+ sofar += got;
+ } while (got && sofar < size);
+ buf[sofar] = 0;
+ }
+
+ return buf;
+}
+
+void swf_uncgi()
+{ char *query, *dupquery, *method;
+
+ query = getenv("QUERY_STRING");
+ if ((query) && strlen(query))
+ { dupquery = strdup(query);
+ swf_scanquery(dupquery);
+ free(dupquery);
+ }
+
+ method = getenv("REQUEST_METHOD");
+ if ((method) && ! strcmp(method, "POST"))
+ { query = swf_postread();
+ if ((query)&&(query[0]!=0)) swf_scanquery(query);
+ free(query);
+ }
+
+}
+
+#undef ishex
+#undef PREFIX