#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_PAARE 255
#define BUF 255
struct CGI_DATEN {
char *variable;
char *wert;
struct CGI_DATEN *next;
};
struct CGI_DATEN *ende = NULL;
char *Strdup(char *str) {
char *puffer = (char *)malloc(strlen(str)+1);
if(puffer == NULL)
return NULL;
strcpy(puffer, str);
return puffer;
}
char *getdata(void) {
unsigned long size;
char *puffer = NULL;
char *request = getenv("REQUEST_METHOD");
char *cont_len;
char *cgi_string;
/* zuerst die Request-Methode überprüfen */
if( NULL == request )
return NULL;
else if( strcmp(request, "GET") == 0 ) {
/* Die Methode GET -> Query-String abholen */
cgi_string = getenv("QUERY_STRING");
if( NULL == cgi_string )
return NULL;
else {
puffer = (char *) Strdup(cgi_string);
return puffer; /* Rückgabewert an den Aufrufer */
}
}
else if( strcmp(request, "POST") == 0 ) {
/* die Methode POST -> Länge des Strings
* ermitteln (CONTENT_LENGTH) */
cont_len = getenv("CONTENT_LENGTH");
if( NULL == cont_len)
return NULL;
else {
/* String CONTENT_LENGTH in unsigned long umwandeln */
size = (unsigned long) atoi(cont_len);
if(size <= 0)
return NULL; /* Keine Eingabe!****** */
}
/* jetzt lesen wir die Daten von stdin ein */
puffer =(char *) malloc(size+1);
if( NULL == puffer )
return NULL;
else {
if( NULL == fgets(puffer, size+1, stdin) ) {
free(puffer);
return NULL;
}
else /* Rückgabewerte an den Aufrufer */
return puffer;
}
}
/* Weder die GET-Methode noch die POST-Methode wurden verwendet. */
else
return NULL;
}
struct CGI_DATEN *teilen(char *str) {
char *paare[MAX_PAARE];
char *s, *res;
int i=0, j=0;
struct CGI_DATEN *ptr_anfang = NULL;
struct CGI_DATEN *ptr_daten = NULL;
s = str;
res = strtok(s, "&");
while(res != NULL && i < MAX_PAARE) {
paare[i] = (char *) malloc(strlen(res)+1);
if(paare[i] == NULL)
return NULL;
strcpy(paare[i], res);
res = strtok(NULL, "&");
i++;
}
while(j < i) {
if(ptr_anfang == NULL) {
ptr_anfang = (struct CGI_DATEN *) malloc(sizeof(struct CGU_DATEN *));
if(ptr_anfang == NULL)
return NULL;
res = strtok(paare[j], "=");
ptr_anfang->variable = (char *) malloc(strlen(res)+1);
if(ptr_anfang->variable == NULL)
return NULL;
strcpy(ptr_anfang->variable, res);
res = strtok(NULL, "\0");
if(res != NULL) {
ptr_anfang->wert = (char *) malloc(strlen(res)+1);
if(ptr_anfang->wert == NULL)
return NULL;
strcpy(ptr_anfang->wert, res);
} else {
ptr_anfang->wert = (char *) malloc(strlen("")+1);
if(ptr_anfang->wert == NULL)
return NULL;
strcpy(ptr_anfang->wert, "");
}
ptr_anfang->next = (struct CGI_DATEN *) malloc(sizeof(struct CGI_DATEN *));
if(ptr_anfang->next == NULL)
return NULL;
ptr_daten = ptr_anfang->next;
j++;
} else {
res = strtok(paare[j], "=");
ptr_daten->variable = (char *) malloc(strlen(res)+1);
if(ptr_daten->variable == NULL)
return NULL;
strcpy(ptr_daten->variable, res);
res = strtok(NULL, "\0");
if(res != NULL) {
ptr_daten->wert = (char *) malloc(strlen(res)+1);
if(ptr_daten->wert == NULL)
return NULL;
strcpy(ptr_daten->wert, res);
} else {
ptr_daten->wert = (char *) malloc(strlen("")+1);
if(ptr_daten->wert == NULL)
return NULL;
strcpy(ptr_daten->wert, "");
}
ptr_daten->next = (struct CGI_DATEN *) malloc(sizeof(struct CGI_DATEN *));
if(ptr_daten->next == NULL)
return NULL;
ptr_daten = ptr_daten->next;
j++;
}
}
ende = ptr_daten;
return ptr_anfang;
}
char convert(char *hex) {
char ascii;
/* erster Hexawert */
ascii =
(hex[0] >= 'A' ? ((hex[0] & 0xdf) - 'A')+10 : (hex[0] - '0'));
ascii <<= 4; /* Bitverschiebung schneller als ascii*=16 */
/* zweiter Hexawert */
ascii +=
(hex[1] >= 'A' ? ((hex[1] & 0xdf) - 'A')+10 : (hex[1] - '0'));
return ascii;
}
void hex2ascii(char *str) {
int x, y;
for(x=0,y=0; str[y] != '\0'; ++x,++y) {
str[x] = str[y];
/* Ein hexadezimales Zeichen ? */
if(str[x] == '%') {
str[x] = convert(&str[y+1]);
y += 2;
}
/* Ein Leerzeichen ? */
else if( str[x] == '+')
str[x]=' ';
}
/* geparsten String sauber terminieren */
str[x] = '\0';
}
int main(void) {
char *string;
FILE *fp;
struct CGI_DATEN *daten;
printf("Content-Type: text/html\n\n");
string = getdata();
hex2ascii(string);
daten = teilen(string);
fp = fopen(daten->wert, "w+");
return EXIT_SUCCESS;
}