cgi simple script in c to search text file


B

bpascal123

Hi cyberusers

I have learned the basic of C programming a while ago but left for something closer to my job. Now I feel my job is getting close to web programming so i decided to see the basic of web programming.

I encounter this message
Error 500: Script Execution Failure

the web url : http://multiskillz.tekcities.com
(just to warn you there is a google javascript that monitor traffic and another one for the same purpose but not on everypage, anyway nothing else, I coded everything using a text editor...)

For reference, the script below is almost entirely inspired from this website :
http://www.lamsade.dauphine.fr/rigaux/mysqlphp/index.php?page=exemples

This is the script I'm trying to run

I saved it under name "k5001_tuto1ExCgi.cgi"
----------c cgi code start----------

#include <stdio.h>
#include <stdlib.h>
#define MAXL 132

char * ExtraitArg(char* ligne, char *arg);

/*int main(void){*/
int main(int arg, char* argv[]){
int nbFilms=0, anMin, anMax=0, annee_naissance;
char titre[40], film[40], nom[40], prenom[40], comb[3];
int annee, lg;
FILE *films;
char ligne[MAXL], arg[MAXL];
short bonTitre=0, bonnePeriode=0;

printf("Content-type: text/html\n\n");
printf("<HEAD><TITLE>Resultat de la recherche</TITLE>");
printf("</HEAD><BODY bgcolor=white>");

printf("<H1><CENTER>Resultat de la recherche</CENTER></H1>")

/***PHASE 1 EXTRACTION DES PARAMETRES dasn chaine ligne***/

lg = atoi(getenv("CONTENT_LENGTH"));
fgets(ligne, lg+1, stdin);
printf("<B>Parametres : </B> %s<P>\n", ligne);
strcpy(ligne, ExtraitArg(ligne,titre));
strcpy(ligne, ExtraitArg(ligne,arg));
anMin = atoi(arg);
strcpy(ligne, ExtraitArg(ligne,titre));
anMax = atoi(arg);
strcpy(ligne, ExtraitArg(ligne,comb));
printf("<HR><P><B>Recherche:</B>Titre=%s %s annee de %d a %d<br /><HR>", titre, comb, anMin, anMax);

/*Phase 2 rech et affi */

films = fopen("k4000_films.txt", "r");
while(fgets(ligne, MAXL, films)){
sscanf(ligne, "%s %d %s %s %d", film, &annee, nom, prenom, &annee_naissance);
if(!strcmp(film, titre)) bontitre = 1;
if(annee >= anMin && annee <= anMax) bonnePeriode = 1;
if((!strcmp("AND", comb) && bonTitre && bonnePeriode) || (!strcmp("OR", comb) && (bonTitre || bonnePeriode))){
nbFilms++;
printf("<b>Film:</b> %s, %d, de %s %s <br />", film, annee, prenom, nom);
}
bonTitre=0;
bonnePeriode=0;
}
fclose(films);
if(!nbFilms) printf("<b>No films found!</b>");
return 1;
}

/***FUNCTION USED IN MAIN ***/
char* ExtraitArg(char* ligne, char *arg){
int pos = 0, posArg = 0;

while (ligne[pos++] != '=');
while (ligne[pos] != '&' && ligne[pos] != '\0')
arg[posArg++] = ligne[pos++];
arg[posArg] = '\0';

return &(ligne[pos+1]);
}

----------c cgi code end----------

the html form for the script

------------HTML start------------

<FORM ACTION = 'http://multiskillz.tekcities.com/cgi-bin/k5001_tuto1ExCgi..cgi' METHOD=POST>

<p><i>Search info from this form using cgi script</i></p>
<br />
<p>Title <INPUT TYPE='TEXT' SIZE=20 NAME='titre'></p>
<br />
<p>Starting year <INPUT TYPE='TEXT' SIZE=4 NAME='anMin' VALUE=1900>&nbsp &nbsp &nbsp &nbsp
Ending year <INPUT TYPE='TEXT' SIZE=4 NAME='anMax' VALUE=2100></p>
<br />
<p><b>Combine search criteria</b> &nbsp &nbsp
<i>AND</i>&nbsp &nbsp<INPUT TYPE='RADIO' NAME='comb' VALUE='AND' CHECKED>&nbsp &nbsp
<i>OR</i>&nbsp &nbsp<INPUT TYPE='RADIO' NAME='comb' VALUE='OR'> ? </p>
<br />
<p><INPUT TYPE='SUBMIT' VALUE=' Search '>
</FORM>
</CENTER>

------------HTML end------------

and the text file k4000_films.txt
---txt start---
Alien 1979 Scott Ridley 1943
Vertigo 1958 Hitchcock Alfred 1899
Psychose 1960 Hitchcock Alfred 1899
Kagemusha 1980 Kurosawa Akira 1910
Volte-face 1997 Woo John 1946
Titanic 1997 Cameron James 1954
Sacrifice 1986 Tarkovski Andrei 1932
---txt ends---


Does something see something that makes the script not run? There are a fewother files I had to amend in the author website so maybe it's same here. At least it's good practice.

Variable names are in French, I can change that if that helps. In the c file, I am not well versed with sscanf and file reading, however the annee variable which means 'year' in French is declared as int type. As the text file is displayed in this way Alien 1979 Scott Ridley 1943Vertigo, (in a single line) however if you copy paste there is a carriage return, I don't know if it's '\n' or '\r' but I am not sure if it doesn't mess with the variable'film' which is declared as a 40 characters array. I am not sure if that'sthe reason. Anything else, it's difficult to debug unless I compiled and run it locally. I'm not even sure if I can access a simple c compiler on windows 7. Please advise.

Thank in advance

Regards
Pascal
 
Ad

Advertisements

B

bpascal123

never mind for the query about compiling again c code on Windows 7. I just tried mingw and it's fine, previously i was using djgpp but now on windows 7 64 bit (with so much resources i'll never need) i wasn't sure if djgpp would even run (install) even for simple code that don't matter with protected memory...still i did remember starting playing around with pointers...
 
I

Ian Collins

bpascal123 wrote:

Please try and keep your line length under 80.
Hi cyberusers

I have learned the basic of C programming a while ago but left for something closer to my job. Now I feel my job is getting close to web programming so i decided to see the basic of web programming.

I encounter this message
Error 500: Script Execution Failure

You need to set up a test environment (with the environment variables a
CGI expects) set so you can test your code stand alone.

The easiest way to do this is to do the environment processing in a
separate function (and even a separate source file) from the application
logic.

With CGIs it also helps to log the parameters to stderr, which will end
up in your web server's errors file.
This is the script I'm trying to run

I saved it under name "k5001_tuto1ExCgi.cgi"
----------c cgi code start----------

#include <stdio.h>
#include <stdlib.h>
#define MAXL 132

char * ExtraitArg(char* ligne, char *arg);

/*int main(void){*/
int main(int arg, char* argv[]){
int nbFilms=0, anMin, anMax=0, annee_naissance;
char titre[40], film[40], nom[40], prenom[40], comb[3];
int annee, lg;
FILE *films;
char ligne[MAXL], arg[MAXL];

You have arg declared twice, change the parameter of main to argc.
short bonTitre=0, bonnePeriode=0;

printf("Content-type: text/html\n\n");
printf("<HEAD><TITLE>Resultat de la recherche</TITLE>");
printf("</HEAD><BODY bgcolor=white>");

printf("<H1><CENTER>Resultat de la recherche</CENTER></H1>")

Missing semicolon.
/***PHASE 1 EXTRACTION DES PARAMETRES dasn chaine ligne***/

lg = atoi(getenv("CONTENT_LENGTH"));

What happens if CONTENT_LENGTH isn't set?
fgets(ligne, lg+1, stdin);
printf("<B>Parametres : </B> %s<P>\n", ligne);
strcpy(ligne, ExtraitArg(ligne,titre));
strcpy(ligne, ExtraitArg(ligne,arg));
anMin = atoi(arg);
strcpy(ligne, ExtraitArg(ligne,titre));
anMax = atoi(arg);
strcpy(ligne, ExtraitArg(ligne,comb));
printf("<HR><P><B>Recherche:</B>Titre=%s %s annee de %d a %d<br /><HR>", titre, comb, anMin, anMax);

/*Phase 2 rech et affi */

films = fopen("k4000_films.txt", "r");

You should test for failure here.
while(fgets(ligne, MAXL, films)){
sscanf(ligne, "%s %d %s %s %d", film, &annee, nom, prenom, &annee_naissance);
if(!strcmp(film, titre)) bontitre = 1;
if(annee >= anMin && annee <= anMax) bonnePeriode = 1;
if((!strcmp("AND", comb) && bonTitre && bonnePeriode) || (!strcmp("OR", comb) && (bonTitre || bonnePeriode))){
nbFilms++;
printf("<b>Film:</b> %s, %d, de %s %s <br />", film, annee, prenom, nom);
}
bonTitre=0;
bonnePeriode=0;
}
fclose(films);
if(!nbFilms) printf("<b>No films found!</b>");
return 1;

Why do you return 1?

You don't close your HTML body or html tags.
 
I

Ian Collins

Ian said:
bpascal123 wrote:

Please try and keep your line length under 80.


You need to set up a test environment (with the environment variables a
CGI expects) set so you can test your code stand alone.

The easiest way to do this is to do the environment processing in a
separate function (and even a separate source file) from the application
logic.

With CGIs it also helps to log the parameters to stderr, which will end
up in your web server's errors file.

I should have said log errors not parameters. I normally log relevant
environment variables as part of an error log entry.
 
B

bpascal123

Hi

I just went ahead yesterday... compiled the file locally with mingw, ran itand first got string.h missing for strcpy, strlen and strcmp... done with that i met loads of errors like 'mainCRTStartup', crt1.c:260 : first defined here ... in function 'WinMainCRTStartup'... about 30 lines like that 'atexit', _onexit and so on

I understand the file can't be run locally as such. What i think next to dois to replace variables with what should be send from the POST form directly into the code mainly the arg parameter so atoi(arg) returns something locally and not from a browser since i'm running the code as an exe and not from the cgi bin in local host... same for variable lg = atoi(getenv("CONTENT_LENGTH")); and see if the code can run from there.

But before I get onto that which is not an easy task as I have to figure out how the POST sends stuff into arg and simulate that locally so the rest of the code can extract the data, is someone experienced with that and help figure out why the code is not running at all.

Regards
Pascal
 
I

Ian Collins

bpascal123 wrote:

*** Please try and keep your line length under 80. ***
Hi

I just went ahead yesterday... compiled the file locally with mingw,
ran it and first got string.h missing for strcpy, strlen and
strcmp... done with that i met loads of errors like 'mainCRTStartup',
crt1.c:260 : first defined here ... in function
'WinMainCRTStartup'... about 30 lines like that 'atexit', _onexit and
so on

Yuck, nothing to do with C, must be a build environment issue.
I understand the file can't be run locally as such.

It can. All that happens with CGI is the web server invokes your
application after setting up the CGI environment variables from the HTTP
request. In your case, you only need CONTENT_LENGTH.
What i think next
to do is to replace variables with what should be send from the POST
form directly into the code mainly the arg parameter so atoi(arg)
returns something locally and not from a browser since i'm running
the code as an exe and not from the cgi bin in local host... same for
variable lg = atoi(getenv("CONTENT_LENGTH")); and see if the code can
run from there.

All you should have to do is set CONTENT_LENGTH in your environment, run
your executable and type in the request data.
But before I get onto that which is not an easy task as I have to
figure out how the POST sends stuff into arg and simulate that
locally so the rest of the code can extract the data, is someone
experienced with that and help figure out why the code is not running
at all.

The data sent with an HTTP POST will be passed to your executable on cin.
 
Ad

Advertisements

B

bpascal123

Hi Ian

Actually I didn't mean locally like localhost, I meant locally like as an exe on the hard drive... so to spot any errors using compiling flags like wall.

But I'm currently trying to figure out how to run cgi files using Apache onWindows 7. It seems with my current configuration, the most simple interpreted perl script is not ran by the localhost server. It seems it's a whole world out there. It might take me a few days until I understand the basics.I'll see how far I can go.

Any help would be appreciated

Thanks
Pascal
 
I

Ian Collins

bpascal123 said:
Hi Ian

Actually I didn't mean locally like localhost, I meant locally like
as an exe on the hard drive... so to spot any errors using compiling
flags like wall.

You can just run your application from the command line.
But I'm currently trying to figure out how to run cgi files using
Apache on Windows 7. It seems with my current configuration, the most
simple interpreted perl script is not ran by the localhost server. It
seems it's a whole world out there. It might take me a few days until
I understand the basics. I'll see how far I can go.

Any help would be appreciated

Don't use windows? I don't use windows, but running and testing CGI
executable is trivial on UNIX (like) systems, so surely it can't be hard
on windows? Your original code runs fine on my system:

export CONTENT_LENGTH=42
c99 /tmp/x.c && ./a.out
Content-type: text/html

<HEAD><TITLE>Resultat de la recherche</TITLE></HEAD><BODY
bgcolor=white><H1><CENTER>Resultat de la recherche</CENTER></H1>

Oh, and please fix your quoting and line length!
 
B

bpascal123

Ian,

Your solution is quite technical for someone not professional like me. I can't follow you on running this code the way you do.

Else you advise to fix quotes. I think it's about quotes in the html form, I understand it should be double quotes rather than single ones.

For the line Length, you mean the variable returned by the POST method from the form like getenv("CONTENT_LENGTH"); ? The author wrote:
lg = atoi(getenv("CONTENT_LENGTH"));
fgets(ligne, lg+1, stdin);

so you advise to check the length of lg. It makes, I agree with you. For now, I'm just testing and if i go online with this for something serious, I'll follow you on this.

Thanks
 
B

bpascal123

I think I understand why i currently can't run this file or any simple c cgi script. I have to re-install Apache web server...

I am now wondering if I should choose a 32-bit Apache installation or a 64-bit to compile and run files locally (on localhost) and use the same files onto the web server that hosts the website, for which I'm not sure of the server version?

Please advise
 
I

Ian Collins

bpascal123 said:
Ian,

Your solution is quite technical for someone not professional like
me. I can't follow you on running this code the way you do.

Compile, run. What didn't you follow?
Else you advise to fix quotes. I think it's about quotes in the html
form, I understand it should be double quotes rather than single
ones.

For the line Length, you mean the variable returned by the POST
method from the form like getenv("CONTENT_LENGTH"); ? The author
wrote: lg = atoi(getenv("CONTENT_LENGTH")); fgets(ligne, lg+1,
stdin);

I was referring to the line length and lack of context quoting in your
posts to this group!
 
Ad

Advertisements

K

Keith Thompson

bpascal123 said:
Else you advise to fix quotes. I think it's about quotes in the html
form, I understand it should be double quotes rather than single ones.

No, he's referring to your line length and quoting in your posted
articles.

Text in comp.lang.c posts should be no wider than 80 columns, preferably
no wider than 72. Quoted text is marked by prepending "> " to each
quoted line, with an attribution line at the top and irrelevant material
deleted.

See most of the articles posted here for examples. Any decent
newsreader will do most of this for you.
 
I

Ian Collins

bpascal123 said:
I think I understand why i currently can't run this file or any
simple c cgi script. I have to re-install Apache web server...

If that's your understanding, you don't understand why you currently
can't run this example!

A CGI "script" is no different from any other scrip or executable.
I am now wondering if I should choose a 32-bit Apache installation or
a 64-bit to compile and run files locally (on localhost) and use the
same files onto the web server that hosts the website, for which I'm
not sure of the server version?

Please advise

For that information, you are asking in the wrong place.
 
B

bpascal123

If that's your understanding, you don't understand why you currently
can't run this example!

I just decided to take the problem from bottom to top. If I can't run this script, for the first time in this environment, I try something much more simple, if it still doesn't work, I shouldn't keep trying in the same direction. It's likely i need to see the application environment
 
B

bpascal123

I just decided to take the problem from bottom to top. If I can't run this script, for the first time in this environment, I try something much moresimple, if it still doesn't work, I shouldn't keep trying in the same direction. It's likely i need to see the application environment

:::my fault, i should have gone through this first
 
Ad

Advertisements

B

bpascal123

Hi Dr Nick

Doing a tutorial to understand a few things about computer and web technology isn't crossing a highway like coding for a company... If I ever get to something serious with cgi script written in c, I will code in a safe way and check out on books or else the reliability of functions (i still remembera few things about buffer overflow and segmentation or infinite loop on the server but i guess i'm far from many security issue in this field). But it's the same with Php and MySql. As I can see there, although these are very accessible, they may require depending on the importance of a project advanced knowledge on server code or script.

Pascal
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top