Solved

Need a C Function to Parse HTML Form

Posted on 1997-12-09
4
211 Views
Last Modified: 2013-12-25
I need a C function that simply parses an HTML form and creates a linked list of Variable/Value pairs.  I've been told to get a CGI C Library, but they don't do what I want (they do way too much).  I just want the form data in a linked list so I can do what I want with it (write it to a file, mail it, create a web page in response, manipulate the data, etc.).  Can any one help me with this?
0
Comment
Question by:Slugger
  • 2
4 Comments
 
LVL 5

Expert Comment

by:julio011597
Comment Utility
This deserves some more points.

BTW, would we assume you need this function:

key_value *parse_query(char *query_string);

where parse_query() gets the query string in input, and gives back a pointer the the head of the list as output?

Regards.
0
 

Accepted Solution

by:
aurelio earned 70 total points
Comment Utility
Here is a complete program that :
1) reads a form via post
It is not very clean but does its job.
2) displays the linked list via Content-type
It has been tested under VC5.0 - must work in other envs with little changes.

#include <windows.h>
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <ctype.h>

#define TOPE 10
#define MAXMOGO 10  // maximo numero de variables en FORM
#define MAXLIST 200 // maximo numero de documentos encontrados
#define DIRBASE "DOCS"
#define LISTADOC "LISTA.TXT"
#define MAXLIN 200      //linea del fichero de ficheros

#ifndef TRUE
#define TRUE 0
#define FALSE 1
#endif


void saca(char *);

class input_list;

class input_var
{private:
 friend input_list;
 input_var *next;
 char *nom;
 char *txt;

} ;

class input_list
{ private:
        input_var *cabeza,*cursor;
  public:
        void insert(char *inom,char *itxt);
        void reset(void) { cursor = cabeza ; }
        int next()
        { if(cursor->next) { cursor=cursor->next;return 1; }
          return 0;
        }
        int locate(char *inom)
        { for(;cursor!=NULL;cursor=cursor->next)
        if(!strcmp(inom,cursor->nom)) return 1;
        return 0;}
        char *get_nom(void) { if(cursor!=NULL) return(cursor->nom);else return(NULL); }
        char *get_txt(void) { if(cursor!=NULL) return(cursor->txt);else return(NULL); }
                void set_nom(char *inom)
                { if(cursor->nom !=NULL) delete[] cursor->nom;
                  cursor->nom = new char [ strlen(inom) + 1 ];
                  strcpy(cursor->nom,inom);
                }
                void set_txt(char *itxt)
                { if(cursor->txt !=NULL) delete[] cursor->txt;
                  cursor->txt = new char [ strlen(itxt) + 1 ];
                  strcpy(cursor->txt,itxt);
                }

        input_list(void)    { cabeza = NULL ; cursor = NULL; }
} ;


void input_list::insert(char *inom,char *itxt)
{       input_var *tail;
        tail = new input_var;
                if(tail == NULL) exit(1);
        tail->nom = new char [ strlen(inom) + 1 ];
                if(tail->nom == NULL) exit(1);
        tail->txt = new char [ strlen(itxt) + 1 ];
                if(tail->txt == NULL) exit(1);

        strcpy(tail->nom,inom);
        strcpy(tail->txt,itxt);

        if(cabeza == NULL)
        { tail->next = NULL;
          cursor = tail;
          cabeza = tail;
        }
        else
        { tail->next = cursor->next;
          cursor->next = tail;
          cursor = tail;
        }
}


int htoi(char *s)
{
char *d="0123456789ABCDEF";
s[0]=toupper(s[0]);
s[1]=toupper(s[1]);
return (16 * (strchr(d,s[0]) - strchr(d,'0')) + (strchr(d,s[1]) - strchr(d,'0')));
}

void saca(char *s)
{
        cout << "Content-type: text/html\n\n" ;
        cout << "<html>\n<head><title>ruina</title>";
        cout << "</head>\n<body>\n<h1>" << s << "\n";

        cout << "</h1>\n</body>\n</html>\n" ;
}


void main(int argc, char **argv)
{       char *p,*q,*aux1,*aux2;
               
                int buscaL=0;
               
               
        char *mazo;                             //aki kargamos el CONTENT_LEN
                long tamanio,van;                        //del CONTENT_LENGTH
        input_list *entrada,*fichero;
                int numfich=0;
        entrada = new input_list;
                fichero = new input_list;


        if((p = getenv("CONTENT_LENGTH"))== (char *)NULL)
        { saca("No se que conio pasa con el CONTENT_LEN");
          exit(1);
        }
        tamanio = atol(p);


        if(tamanio < 1)
        { saca("El CONTENT_LEN es muy canino !!! ");
          exit(1);
        }

        if(chdir(DIRBASE) < 0)
        {
          saca("Error CHDIR ( DIRBASE )");                      // vete al subdir DOCS
//          exit(1);
        }
        mazo = new char [tamanio + 1] ;
        if(mazo == NULL)
        { saca("Error new char mazo");
                exit(1);
        }
        p = mazo ;
        van=0;
        cin.read(mazo,tamanio);


        mazo[tamanio]='\0';


                                                // ke estan name=value&name=value ...
                                                // cerrar el rollo con *
        p=mazo;                                 // kitamos los + y los %
        while(*p!='\0')
        { switch(*p)
                { case '+' : *p=' ';p++;break;
          case '%' : if(*(p+1)!='\0' && *(p+2)!='\0')
                     { char ki,uno,dos;
                       uno = *(p+1); dos = *(p+2);
                                        ki = (uno>='A' ? ((uno&0xdf) -'A')+10:(uno - '0'));
                                        ki*=16;
                                        ki+= (dos>='A' ? ((dos&0xdf) -'A')+10:(dos - '0'));
                                        *p = ki ;
                                        *(p+1) = ' '; // vaya chapuza colega
                                        *(p+2) = ' '; // sigue la qapa.Te sobran 2 ' '.
                                    p+=2;
                     } p++ ; break;
                default : p++; break;
                }
        }               // ahora hay que pillar name=value&name=value&



        aux1=new char [tamanio+1];
        aux2=new char [tamanio+1];
                p=mazo;

        while(*p!='\0')
        { q=aux1;                                                                       // buscar el name
          while(*p!='=' && *p!='\0') *q++ = *p++;       // name=value&
          if(*p == '\0') { saca("Doc EOF not expecte");exit(1); }
          *q='\0';                                                                      // en aux1 esta el name
              p++ ;                                                                         // ahora *p es '='
      q=aux2;
      while(*p!='&' && *p!='\0')
          {
                *q++ = *p++;
          }
              *q='\0';             // en aux2 esta el value
          if(*p!='\0') p++;        // puede valer &
                entrada->insert(aux1,aux2);
        }

        delete [] aux1;
        delete [] aux2;
        delete [] mazo;

        cout << "Content-type: text/html\n\n" ;
        cout << "<html>\n<head><title>ruina</title>";
        cout << "</head>\n<body>\n";
        entrada->reset();               // buscar el input correspondiente a busca
        do
        { p = entrada->get_nom();
          cout << p ;
          p = entrada->get_txt();
          cout << " = " << p << "<br>\n" ;
        } while(entrada->next());

        cout << "</body>\n</html>\n" ;
  exit(0);
}

Hope it helps.


0
 

Author Comment

by:Slugger
Comment Utility
The code you have given appears to be C++ code.  I only have access to a C compiler on a UNIX system.
0
 

Expert Comment

by:aurelio
Comment Utility
Hi slugger! here is something like C normal code. It works under
UNIX SYSV and it's not clean code , but it works and the only place to modify is in the "printf's" part ( always issue a reset() before accessing the linked list )
Email me at aurelio_r@hotmail.com if you need further information.
Bye!


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <ctype.h>

#define TOPE 10
#define MAXMOGO 10  // maximo numero de variables en FORM
#define MAXLIST 200 // maximo numero de documentos encontrados
#define DIRBASE "DOCS"
#define LISTADOC "LISTA.TXT"
#define MAXLIN 200      //linea del fichero de ficheros

#ifndef TRUE
#define TRUE 0
#define FALSE 1
#endif


void saca(char *);

struct input_var
{
 struct input_var *next;
 char *nom;
 char *txt;

} ;

struct input_var *cabeza=NULL,*cursor=NULL;

void reset(void) { cursor = cabeza ; }

int next(void)
        { if(cursor->next) { cursor=cursor->next;return 1; }
          return 0;
        }

int locate(char *inom)
{ for(;cursor!=NULL;cursor=cursor->next)
  if(!strcmp(inom,cursor->nom)) return 1;
return 0;
}
char *get_nom(void)
{ if(cursor!=NULL) return(cursor->nom);else return(NULL);
}
char *get_txt(void)
{ if(cursor!=NULL) return(cursor->txt);else return(NULL);
}
void set_nom(char *inom)
{ if(cursor->nom !=NULL) free( cursor->nom);
  cursor->nom = malloc( strlen(inom) + 1 );
  strcpy(cursor->nom,inom);
}
void set_txt(char *itxt)
{ if(cursor->txt !=NULL) free (cursor->txt);
  cursor->txt = malloc( strlen(itxt) + 1 );
  strcpy(cursor->txt,itxt);
}



void insert(char *inom,char *itxt)
{       struct input_var *tail;
        tail = ( struct input_var *)malloc(sizeof(struct input_var));
                if(tail == NULL) exit(1);
        tail->nom = malloc( strlen(inom) + 1 );
                if(tail->nom == NULL) exit(1);
        tail->txt = malloc( strlen(itxt) + 1 );
                if(tail->txt == NULL) exit(1);

        strcpy(tail->nom,inom);
        strcpy(tail->txt,itxt);

        if(cabeza == NULL)
        { tail->next = NULL;
          cursor = tail;
          cabeza = tail;
        }
        else
        { tail->next = cursor->next;
          cursor->next = tail;
          cursor = tail;
        }
}

int htoi(char *s)
{
char *d="0123456789ABCDEF";
s[0]=toupper(s[0]);
s[1]=toupper(s[1]);
return (16 * (strchr(d,s[0]) - strchr(d,'0')) + (strchr(d,s[1]) - strchr(d,'0')));
}

void saca(char *s)
{
        printf( "Content-type: text/html\n\n" );
        printf( "<html>\n<head><title>ruina</title>");
        printf("</head>\n<body>\n<h1>%s\n",  s);
        printf("</h1>\n</body>\n</html>\n") ;
}


void main(int argc, char **argv)
{       char *p,*q,*aux1,*aux2;
               
                int buscaL=0;
        char *mazo;                
                long tamanio,van;
                int numfich=0;

        if((p = getenv("CONTENT_LENGTH"))== (char *)NULL)
        { saca("No se que conio pasa con el CONTENT_LEN");
          exit(1);
        }
        tamanio = atol(p);

        if(tamanio < 1)
        { saca("El CONTENT_LEN es muy canino !!! ");
          exit(1);
        }

        mazo = malloc (tamanio + 1) ;
        if(mazo == NULL)
        { saca("Error new char mazo");
                exit(1);
        }
        p = mazo ;
        van=0;
      
        read(0,mazo,tamanio);
        mazo[tamanio]='\0';
        p=mazo;                
        while(*p!='\0')
        { switch(*p)
        { case '+' : *p=' ';p++;break;
          case '%' : if(*(p+1)!='\0' && *(p+2)!='\0')
                     { char ki,uno,dos;
                       uno = *(p+1); dos = *(p+2);
                                        ki = (uno>='A' ? ((uno&0xdf) -'A')+10:(uno - '0'));
                                        ki*=16;
                                        ki+= (dos>='A' ? ((dos&0xdf) -'A')+10:(dos - '0'));
                                        *p = ki ;
                                        *(p+1) = ' ';
                                        *(p+2) = ' ';
                                    p+=2;
                     } p++ ; break;
                default : p++; break;
                }
        }              



        aux1=malloc(tamanio+1);
        aux2=malloc(tamanio+1);
        p=mazo;
        while(*p!='\0')
        { q=aux1;                                                                      
          while(*p!='=' && *p!='\0') *q++ = *p++;      
          if(*p == '\0') { saca("Doc EOF not expecte");exit(1); }
          *q='\0';                                                                        p++;
      q=aux2;
      while(*p!='&' && *p!='\0')
          {
                *q++ = *p++;
          }
              *q='\0';
          if(*p!='\0') p++;
                insert(aux1,aux2);
        }

        free( aux1);
        free( aux2);
        free(mazo);

        printf("Content-type: text/html\n\n") ;
        printf("<html>\n<head><title>ruina</title>");
        printf("</head>\n<body>\n");
        reset();  
        do
        { p = get_nom();
          printf(p) ;
          p = get_txt();
          printf(" = %s<br>\n",p) ;
        } while(next());
        printf("</body>\n</html>\n") ;
  exit(0);
}

0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

It is a general practice to get rid of old user profiles on a computer  in a LAN environment. As I have been working with a company in a LAN environment where users move from one place to some other place at times. This will make many user profil…
This article will show, step by step, how to integrate R code into a R Sweave document
Learn the basics of while and for loops in Python.  while loops are used for testing while, or until, a condition is met: The structure of a while loop is as follows:     while <condition>:         do something         repeate: The break statement m…
The viewer will learn how to count occurrences of each item in an array.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now