Cgi and file access

Discussion in 'C Programming' started by francesco, Jan 16, 2011.

  1. francesco

    francesco Guest

    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
    francesco, Jan 16, 2011
    #1
    1. Advertising

  2. francesco

    Tim Harig Guest

    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.

    On 2011-01-16, francesco <> wrote:
    > 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.
    Tim Harig, Jan 16, 2011
    #2
    1. Advertising

  3. francesco

    francesco Guest

    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.
    >
    > On 2011-01-16, francesco <> wrote:
    >> I must use a text file in a cgi program written in C.

    >

    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
    francesco, Jan 16, 2011
    #3
  4. francesco

    Tim Harig Guest

    On 2011-01-16, francesco <> wrote:
    > 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.
    >>
    >> On 2011-01-16, francesco <> wrote:
    >>> I must use a text file in a cgi program written in C.

    >>

    > 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


    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.
    Tim Harig, Jan 16, 2011
    #4
  5. francesco

    Lew Pitcher Guest

    On Jan 16, 6:23 am, francesco <> wrote:
    > 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 <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"))


    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("<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);


    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.

    >
    > Francesco
    Lew Pitcher, Jan 16, 2011
    #5
  6. francesco

    francesco Guest

    Il Sun, 16 Jan 2011 07:56:59 -0800, China Blue Max ha scritto:

    > In article <4d32d52d$0$30915$>,
    > francesco <> wrote:
    >
    >> else
    >> {
    >> fp=fopen("counter.txt","w+");
    >> contatore=1;
    >> fprintf(fp,"%d",contatore);
    >> fclose(fp);
    >> }

    >
    > 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-
    francesco, Jan 16, 2011
    #6
  7. francesco

    francesco Guest


    >
    >
    > 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.
    francesco, Jan 16, 2011
    #7
  8. francesco

    Nick Guest

    China Blue Max <> writes:

    >> Note that you call exist_file() before you emit any HTML

    >
    > 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.
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
    Nick, Jan 16, 2011
    #8
  9. On 16 Jan 2011 11:23:25 GMT, francesco <>
    wrote:

    >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.
    Richard Sanders, Jan 16, 2011
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jürgen Exner

    Re: CGI Perl "use CGI" statement fail

    Jürgen Exner, Jul 31, 2003, in forum: Perl
    Replies:
    0
    Views:
    1,223
    Jürgen Exner
    Jul 31, 2003
  2. Muzammil
    Replies:
    1
    Views:
    1,062
    red floyd
    Aug 28, 2008
  3. fatted
    Replies:
    1
    Views:
    117
    Steve Grazzini
    Jul 25, 2003
  4. zippy

    cgi and cgi-bin

    zippy, Feb 1, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    306
    Sam Holden
    Feb 2, 2005
  5. BestFriend
    Replies:
    2
    Views:
    743
Loading...

Share This Page