Cgi and file access

F

francesco

I must use a text file in a cgi program written in C.

The source of the program is the following:

#include "stdio.h"
#include "stdlib.h"
typedef enum {false,true} boolean;
boolean exist_file(char *nomefile);
int main(void)
{
FILE *fp=NULL;
int contatore=0;
// Legge il dato dal file counter.txt
if(exist_file("counter.txt"))
{
fp=fopen("counter.txt","r+");
if(fscanf(fp,"%d",&contatore)!=EOF)
// lo incrementa
contatore++;
// Si riposiziona all'inizio del file
rewind(fp);
// lo riscrive
fprintf(fp, "%d",contatore);
fclose(fp);
}
// Il file non esiste, viene creato
else
{
fp=fopen("counter.txt","w+");
contatore=1;
fprintf(fp,"%d",contatore);
fclose(fp);
}
printf("Content-Type: text/html\r\n\r\n");
printf("<html>\n");
printf("<head>\n");
printf("<title>Prova contatore\n");
printf("</head>\n");
printf("<body>\n");
printf("<h1>Questa pagina è stata visitata %d volte</h1>\n",contatore);
printf("</body>\n");
printf("</html>\n");
return 0;
}
boolean exist_file(char *nomefile)
{
FILE *fp;
boolean exists=false;
printf("Nome file=%s\n",nomefile);
fp=fopen(nomefile,"r");
exists=(fp!=NULL);
//fclose(fp);
return exists;
}


but it doesn't work, there are some errors in the file management
functions I have used, for locally it works fine, but when I copy the
executable in the directory cgi-bin of my local apache webserver (linux
opensuse os), I get the following messages

"Server error!

The server has generated an inner error and isn't able to satisfy the
query. (Well, I translated it from italian )


Premature end of script headers: http_counter.exe "



Francesco
 
T

Tim Harig

This is really out off topic here. You could should find a group for your
webserver or CGI module. This is not a C problem.

I must use a text file in a cgi program written in C.

That is a bad idea. If you do actually use a flat file for this, then
you need to implement locking of the file or otherwise ensure that only a
single process can access the file at once. The web server will start a
new process for each request and nothing prevents several requests from
incoming at the same time. Your webserver might provide a library for
locking functionality or you might need to use functions provided by your
operating sytem.
boolean exist_file(char *nomefile)
{
FILE *fp;
boolean exists=false;
printf("Nome file=%s\n",nomefile);

I don't know if this is your problem; but, this probably should not be
printed before your headers. It certainly doesn't match the format of an
HTTP header.
fp=fopen(nomefile,"r");
exists=(fp!=NULL);
//fclose(fp);
return exists;
}
"Server error!
Premature end of script headers: http_counter.exe "

If you remove the extraneous output and still receive this error, then you
need to check what headers your server might require your program to
provide.
 
F

francesco

Il Sun, 16 Jan 2011 12:37:34 +0000, Tim Harig ha scritto:
This is really out off topic here. You could should find a group for
your webserver or CGI module. This is not a C problem.
end of script headers: http_counter.exe "
If you remove the extraneous output and still receive this error, then
you need to check what headers your server might require your program to
provide.

If I remove code to handle files, the little program works fine. Anyway i
was trying to create a simple web page counter in C
 
T

Tim Harig

Il Sun, 16 Jan 2011 12:37:34 +0000, Tim Harig ha scritto:

end of script headers: http_counter.exe "

If I remove code to handle files, the little program works fine. Anyway i
was trying to create a simple web page counter in C

Considering the extraneous output comes from your file handling functions,
I would say that is the cause of your issues. Remove that output and it
should work; except that of course you have no file locking so if you get
two hits at once, you are likely to loose one of them.
 
L

Lew Pitcher

I must use a text file in a cgi program written in C.

The source of the program is the following:

#include "stdio.h"
#include "stdlib.h"

These should be
#include <stdio.h>
#include said:
typedef enum {false,true} boolean;
boolean exist_file(char *nomefile);
int main(void)
{
FILE *fp=NULL;
int contatore=0;
// Legge il dato dal file counter.txt
if(exist_file("counter.txt"))

Note that you call exist_file() before you emit any HTML
{
fp=fopen("counter.txt","r+");
if(fscanf(fp,"%d",&contatore)!=EOF)
// lo incrementa
contatore++;
// Si riposiziona all'inizio del file
rewind(fp);
// lo riscrive
fprintf(fp, "%d",contatore);
fclose(fp);}

// Il file non esiste, viene cre

Now, you emit the HTML
printf("Content-Type: text/html\r\n\r\n");
printf("<html>\n");
printf("<head>\n");
printf("<title>Prova contatore\n");

Note that the <title> tag requires a closing </title> tag.
This printf should read
printf("</head>\n");
printf("<body>\n");
printf("<h1>Questa pagina è stata visitata %d volte</h1>\n",contatore);
printf("</body>\n");
printf("</html>\n");
return 0;}

boolean exist_file(char *nomefile)
{
    FILE *fp;
    boolean exists=false;
    printf("Nome file=%s\n",nomefile);

Here, you emit a string. Remember that you called this function /
before/ emitting any HTML. The reader of your stdout stream (in this
case, your webserver) expects that anything emitted before the start
of the html will be valid HTTP headers. But, you aren't sending a
valid HTTP header at this point; you are sending a diagnostic string.

I bet that your webserver is choking on this string. Remove the above
printf and try again.
    fp=fopen(nomefile,"r");
        exists=(fp!=NULL);
        //fclose(fp);
        return exists;

}

but it doesn't work, there are some errors in the file management
functions I have used, for locally it works fine, but when I copy the
executable in the directory cgi-bin of my local apache webserver (linux
opensuse os), I get the following messages

"Server error!

The server has generated an inner error and isn't able to satisfy the
query. (Well, I translated it from italian )

Premature end of script headers: http_counter.exe "

Yah, it saw
Nome file=counter.txt
which isn't a script header.
 
F

francesco

Il Sun, 16 Jan 2011 07:56:59 -0800, China Blue Max ha scritto:
I think Apache sets the working directory to .../cgi-bin, and runs the
code as www or nobody or some other least privileged user. There's a
good chance that you don't have write permissions to the current
directory and so this open fails. That would mean fp=NULL and fprintf
should die horribly.
I chanegd the program like this

#include "stdio.h"
#include "stdlib.h"
#define counter "/srv/www/cgi-bin/data/counter.txt"
typedef enum {false,true} boolean;
boolean exist_file(char *nomefile);
int main(void)
{
FILE *fp=NULL;
int contatore=0;
// Legge il dato dal file counter.txt
if(exist_file(counter))
{
fp=fopen(counter,"r");
if(fscanf(fp,"%d",&contatore))
// lo incrementa
contatore++;
else
contatore=1;
fclose(fp);
}
if((fp=fopen(counter,"w+")))
{
fprintf(fp,"%d",contatore);
fclose(fp);
}
// Inizia la creazione della pagina html
printf("Content-Type: text/html\n\n");
printf("<html>\n");
printf("<head>\n");
printf("<title>Prova contatore</title>\n");
printf("</head>\n");
printf("<body>\n");
printf("<h1>Questa pagina è stata visitata %d volte</h1>\n",contatore);
printf("</body>\n");
printf("</html>\n");
return 0;
}
boolean exist_file(char *nomefile)
{
FILE *fp;
boolean exists=false;
//printf("Nome file=%s\n",nomefile);
fp=fopen(nomefile,"r");
exists=(fp!=NULL);
fclose(fp);
return exists;
}



But it stills isn't able (apache, I suppose) in the file. I put it in /
srv/www/cgi-bin/data directory, where I set a read-write permission to my
user. Infact, now, if I launch the program from command line /srv/www/cgi-
bin/http_counter.exe it works fine, but when I try to execute it from the
browswer, http://localhost/cgi-bin/http_counter.exe, isn't able to update
the counter, but only to read it, showing me its content I updated by
command line-
 
F

francesco

But it stills isn't able (apache, I suppose) in the file. I put it in /
srv/www/cgi-bin/data directory, where I set a read-write permission to
my user. Infact, now, if I launch the program from command line
/srv/www/cgi- bin/http_counter.exe it works fine, but when I try to
execute it from the browswer, http://localhost/cgi-bin/http_counter.exe,
isn't able to update the counter, but only to read it, showing me its
content I updated by command line-

I have solved the problem, I had to give write access to counter.txt for
everybody.
 
N

Nick

China Blue Max said:
If the response doesn't begin with valid headers, it is assumed to be
content type text/plain and the entire response is the plain text
content.

Really? If you write a program in C (or bash, or whatever), stick it in
cgi-bin and run it, and it produces text output and no headers, what
you'll generally get is a "Premature end of script headers" error from
Apache.

Believe me, I've been there many times.
 
R

Richard Sanders

I must use a text file in a cgi program written in C. [snip]

but it doesn't work, there are some errors in the file management
functions I have used, for locally it works fine, but when I copy the
executable in the directory cgi-bin of my local apache webserver (linux
opensuse os), I get the following messages

"Server error!

The server has generated an inner error and isn't able to satisfy the
query. (Well, I translated it from italian )


Premature end of script headers: http_counter.exe "

I have run into the same sort of problem with NT webservers.

On NT it is permissions. The anonymous user (the client connection)
must have read/write permissions to the text file. I always put my
files like this in cgi-bin or a directory that has the same
permissions as cgi-bin.

You may be having the same sort of problems.
 

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

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top