Feia molts anys que no escrivia un CGI i mes anys encara que no programava en C. Fa cosa de 3 setmanes o així que vaig haver d’escriure un CGI en C i una mica mes i hem cago viu.
Aquí escric un script en C per al tractament d’un formulari amb les de dades passades a través de POST.
#include <stdlib .h>
#include <string .h>
typedef struct {
char *nombre;
char *valor;
} parametro;
//Devuelve un substring de la cadena apuntada por f de tamaño *cl o finalizada con
//el carácter centinela stop.
char *readword(FILE *f, char stop, int *cl) {
int wsize;
char *word;
int ll;
wsize = 102400;
ll=0;
//Reservamos memoria.
word = (char *) malloc(sizeof(char) * (wsize + 1));
//La salida del bucle se realiza mediante un return.
while(1) {
//Leemos carácter a carácter de la entrada estándar y lo almacenamos.
word[ll] = (char)fgetc(f);
//Reajustamos si hemos excedido la longitud de la variable word.
if(ll==wsize) {
word[ll+1] = ‘\0’;
wsize+=102400;
word = (char *)realloc(word,sizeof(char)*(wsize+1));
}
//Actualizamos el número de carácteres a leer.
–(*cl);
//Si encontrado el carácter centinela o final de lectura salimos del bucle.
if((word[ll] == stop) || (feof(f)) || (!(*cl))) {
if(word[ll] != stop) ll++;
word[ll] = ‘\0’;
return word;
}
++ll;
}
}
void getword(char *word, char *line, char stop) {
int x = 0,y;
for(x=0;((line[x]) && (line[x] != stop));x++)
word[x] = line[x];
word[x] = ‘\0’;
if(line[x]) ++x;
y=0;
while(line[y++] = line[x++]);
}
main() {
//Limitacio a 10 variables nombre = valor.
parametro entradas[10];
int tamano, i;
//Tipo MIME del documento que genera el CGI.
printf(“Content-type: text/html\n\n”);
//Comprobamos que el método recibido es un POST.
if(strcmp(getenv(“REQUEST_METHOD”),”POST”)) {
printf(“Tiene que ser con POST“);
exit(1);
}
//Comprobamos que conocemos el tipo MIME que nos ha pasado el formulario.
if(strcmp(getenv(“CONTENT_TYPE”),”application/x-www-form-urlencoded”)) {
printf(“Tipo MIME desconocido“);
exit(1);
}
//Almacenamos la longitud de los datos recibidos.
tamano = atoi(getenv(“CONTENT_LENGTH”));
for(i=0; tamano && (!feof(stdin)); i++) {
entradas[i].valor = readword(stdin, ‘&’, &tamano);
entradas[i].nombre = (char *) malloc(sizeof(char) * (strlen(entradas[i].valor + 1)));
getword(entradas[i].nombre, entradas[i].valor, ‘=’);
}
/* Aquí el tractament del formulari */
exit(0);
}
per a compilar gcc fitxer.c