CGI/HTML Leeres Textfeld

yax

Erfahrenes Mitglied
Hallo,

ich habe folgendes Problem:

ich schreibe eine Webseite die aus verschiedenen Textfeldern Daten ausliest. Wenn ich jetzt aber nicht alle Textfelder ausgefüllt habe, funtkioniert mein CGI-Programm nicht. Ich möchte aber, dass es dem User selber überlassen ist, wieviel textfelder er ausfüllt.

Hier mein HTML-Code:
HTML:
<html>
<head>
<title>Allgemein</title>
</head>

<body>

<center><h2>Allgemeines</h2></center>

<form action="http://localhost/cgi-bin/speichern.cgi">
<pre>
<b>Wohnort     : </b><input name="Wohnort" type="text" placeholder="Wo wohnst du?" size="28"><br><br>
<b>Heimatstadt : </b><input name="Heimatstadt" type="text" placeholder="Wo bist du aufgewachsen?" 

size="28"><br><br>
<b>Sprachen    : </b><input name="Sprachen" type="text" placeholder="Welche Sprachen sprichst du?" 

size="28"><br><br>
<b>Über mich   : </b><textarea name="UeberMich" cols="20" rows="4" placeholder="Was kannst du über dich 

sagen?"></textarea>
</pre><br>
<center><input type="image" src="speichern.jpg"></center>
</form>

</body>
</html>

Und mein CGI-Programm:

Code:
#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 *Strdub(char *str) {
     char *puffer = (char *)malloc(strlen(str)+1);
     if(puffer == NULL)
       return NULL;
     strcpy(puffer, str);
     return puffer;
}

char *getdata(void) {
     char *methode = getenv("REQUEST_METHOD");
     char *puffer;
     char *str, *cont_len;
     int size;
     
     if(methode == NULL)
       return NULL;
     else if(strcmp(methode, "GET") == 0) {
       str = getenv("QUERY_STRING");
       if(str == NULL)
         return NULL;
       puffer = Strdub(str);
       if(puffer == NULL)
         return NULL;
       return puffer;
     } else if(strcmp(methode, "POST") == 0) {
       cont_len = getenv("CONTET_LENGTH");
       if(cont_len == NULL)
         return NULL;
       size = (int) atoi(cont_len);
       if(size <= 0)
         return NULL;
       puffer = (char *)malloc(size+1);
       if(puffer == NULL)
         return NULL;
       if(NULL == fgets(puffer, size+1, stdin)){
         free(puffer);
         return NULL;
       }
       return puffer;
     }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");
           ptr_anfang->wert = (char *) malloc(strlen(res)+1);
           if(ptr_anfang->wert == NULL)
             return NULL;
           strcpy(ptr_anfang->wert, res);
           
           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");
           ptr_daten->wert = (char *) malloc(strlen(res)+1);
           if(ptr_daten->wert == NULL)
             return NULL;
           strcpy(ptr_daten->wert, res);
           
           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) {
    printf("Content-Type: text/html\n\n");
    struct CGI_DATEN *zeiger;
    char *str = getdata();
    if(str == NULL) {
      printf("Fehler bei str");
      return EXIT_FAILURE;
    }
    
    hex2ascii(str);
    
    zeiger = teilen(str);
    if(zeiger == NULL) {
      printf("Fehler bei teilen()");
      return EXIT_FAILURE;
    }
    
    printf("%s : %s", zeiger->variable, zeiger->wert);
    zeiger = zeiger->next;
    printf("%s : %s", zeiger->variable, zeiger->wert);
    zeiger = zeiger->next;
    printf("%s : %s", zeiger->variable, zeiger->wert);
    zeiger = zeiger->next;
    printf("%s : %s", zeiger->variable, zeiger->wert);
    zeiger = zeiger->next;
    
    return EXIT_SUCCESS;
}

Ich hoffe ihr könnt mir helfen :)

Gruß Yax :)
 
Hi.

Du hast die per GET übertragenen Variablen anscheinend in eine einfach verkettete Liste übertragen.

Dann mußt du doch nur prüfen ob der Zeiger gültig ist, bevor du ihn benutzt....

Gruß

\edit: Evlt. solltest du mal sagen was du mit "das Programm funktioniert nicht mehr" meinst.
 
Was meinst du mit überprüfen ob der zeiger gültig ist?

Ich meinte, dass dann die Fehlermeldung 500 von meinem Server kommt :)
 
Hi

Ohne den Code jetzt genau angeschaut zu haben:
vor Kurzem war auch so ein Problem hier, bei dem hat ein
C++:
fflush(stdout);
am Programmende gefehlt.
Versuchen schadet ja nicht.

Gruß
 
So wie deine Liste aufgebaut ist, ist der next-Pointer beim letzten Element NULL. D.h. die Ausgabe kannst du zu einer Schleife zusammenfassen, die so lange läuft, bis next auf NULL steht:

Code:
while ( zeiger != NULL )
{
  printf( "%s : %s", zeiger->variable, zeiger->wert );
  zeiger = zeiger->next;
}
 
Okay, stimmt, dass mit der Schleife hab ich total vergessen :D :D danke Endurion :)

Aber mein Problem ist ja, dass wenn ich nur ein Textfeld ausfülle, und dann auf Speichern klicke, dann kommt da die Fehlermeldung 500. Sobald ich aber alle Textfelder ausfülle und dann auf speichern klicke, wird mir die eingabe ausgegeben.

Hat jemand eine Lösung? :)
 
Okay, stimmt, dass mit der Schleife hab ich total vergessen :D :D danke Endurion :)

Aber mein Problem ist ja, dass wenn ich nur ein Textfeld ausfülle, und dann auf Speichern klicke, dann kommt da die Fehlermeldung 500.
Das deutet darauf hin, dass dein Programm einfach abstürzt.

Verwende einen Debugger und schau nach wo das Problem liegt.

Ich habe es gerade getestet und nachdem ich die Schleife mit der Prüfung des Zeigers einbaue stürzt das Programm auch nicht mehr ab.

Gruß
 
Meinst du die Schleife von Endurion ?
Welche denn sonst? Du hast es anscheinend nicht mal ausprobiert...

Bevor du einen Zeiger benutzt, mußt du doch erstmal prüfen ob der Zeiger gültig ist, also != NULL. Das hast du einmal nach Aufruf der Funktion teilen gemacht.

Dann setzt du den Zeiger auf next und dereferenzierst den Zeiger einfach, ohne zu prüfen ob != NULL. Das funktioniert nur wenn mehr als 1 Textfeld gefüllt ist...

Gruß
 
Also, es höhrt sich sehr logisch an, doch wenn ich diese Schleife in mein Programm einsetze, kommt wieder der Fehler 500 vom Server.
 
Zurück