/*************************************************************************/ /** **/ /** hello.c -- "hello, world" padrao, para demonstrar **/ /** programacao CGI basica e o uso da rotina getcgivars(). **/ /** **/ /** Voce pode colar a rotina completa em seu programa, como eu **/ /** fiz aqui, ou criar um arquivo separado de objeto e header. **/ /** **/ /*************************************************************************/ /***************** inicio do modulo getcgivars() *************************/ /*************************************************************************/ /** **/ /** getcgivars.c -- rotina para ler variaveis de entrada CGI **/ /** e armazenar em um array de strings. **/ /** **/ /** As rotinas x2c() and unescape_url() foram extraidas diretamente **/ /** do programa-exemplo util.c, incluido no pacote HTTPD da NCSA. **/ /** **/ /*************************************************************************/ #include #include #include /** Converter uma string de dois caracteres hexa no caractere correspondente **/ char x2c(char *what) { register char digit; digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); return(digit); } /** Converter qualquer "escape sequence" %xx nos caracteres correspondentes **/ void unescape_url(char *url) { register int i,j; for(i=0,j=0; url[j]; ++i,++j) { if((url[i] = url[j]) == '%') { url[i] = x2c(&url[j+1]) ; j+= 2 ; } } url[i] = '\0' ; } /** Ler a entrada CGI e colocar todos os pares nome/valor na lista. **/ /** Retorna lista contendo nome1, valor1, nome2, valor2, ... , NULL **/ char **getcgivars() { register int i ; char *request_method ; int content_length; char *cgiinput ; char **cgivars ; char **pairlist ; int paircount ; char *nvpair ; char *eqpos ; /** Dependendo do metodo de solicitacao, ler toda a entrada CGI e colocar em cgiinput **/ /** (realmente deve produzir mensagens de erro HTML, em vez de sair com exit() ) **/ request_method= getenv("REQUEST_METHOD") ; if (!strcmp(request_method, "GET") || !strcmp(request_method, "HEAD") ) { cgiinput= strdup(getenv("QUERY_STRING")) ; } else if (!strcmp(request_method, "POST")) { /* strcasecmp() is not supported in Windows-- use strcmpi() instead */ if ( strcasecmp(getenv("CONTENT_TYPE"), "application/x-www-form-urlencoded")) { printf("getcgivars(): Unsupported Content-Type.\n") ; exit(1) ; } if ( !(content_length = atoi(getenv("CONTENT_LENGTH"))) ) { printf("getcgivars(): No Content-Length was sent with the POST request.\n") ; exit(1) ; } if ( !(cgiinput= (char *) malloc(content_length+1)) ) { printf("getcgivars(): Could not malloc for cgiinput.\n") ; exit(1) ; } if (!fread(cgiinput, content_length, 1, stdin)) { printf("Couldn't read CGI input from STDIN.\n") ; exit(1) ; } cgiinput[content_length]='\0' ; } else { printf("getcgivars(): unsupported REQUEST_METHOD\n") ; exit(1) ; } /** Retornar todos os '+' para espacos **/ for(i=0; cgiinput[i]; i++) if(cgiinput[i] == '+') cgiinput[i] = ' ' ; /** Primeiro, quebrar nos "&" para extrair os pares nome-valor para pairlist **/ pairlist= (char **) malloc(256*sizeof(char **)) ; paircount= 0 ; nvpair= strtok(cgiinput, "&") ; while (nvpair) { pairlist[paircount++]= strdup(nvpair) ; if (!(paircount%256)) pairlist= (char **) realloc(pairlist,(paircount+256)*sizeof(char **)) ; nvpair= strtok(NULL, "&") ; } pairlist[paircount]= 0 ; /* terminar a lista com NULL */ /** Agora, da lista de pares extrair os nomes e valores **/ cgivars= (char **) malloc((paircount*2+1)*sizeof(char **)) ; for (i= 0; i\n") ; printf("CGI Results\n") ; printf("\n") ; printf("

Hello, world.

\n") ; printf("Your CGI input variables were:\n") ; printf("
    \n") ; /** Imprimir as variaveis CGI enviadas pelo usuario. Note que a lista **/ /** de variaveis alterna nomes e valores, e termina em NULL. **/ for (i=0; cgivars[i]; i+= 2) printf("
  • [%s] = [%s]\n", cgivars[i], cgivars[i+1]) ; printf("
\n") ; printf("\n") ; printf("\n") ; /** Liberar tudo que deva ser liberado **/ for (i=0; cgivars[i]; i++) free(cgivars[i]) ; free(cgivars) ; exit(0) ; }