#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12

    Question function to parse STDIN (cgi)


    I'm working on a cgi script in c that will take form input and copy it to a .txt file. Its actually much more complicated than that, but the rest of the script is running fine, I'm just having problems with a function for copying the input into a tmpfile()

    Here is the function as simple as I could make it. But something is awry.

    Code:
    void parseSTDIN(FILE *tmp_input){
      char buffer[2000];
    
      gets(buffer);	
    	
      fprintf(tmp_input, "%s", buffer);
    
      rewind(tmp_input);
    
    } // parseSTDIN() -
    Would it be a better idea to use fputs(buffer, tmp_input) than to use fprintf()?

    Or am I just way off track here? Any help greatly appreciated.

    Travis
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12
    I made a few changes, here is what the updated code looks like.

    PHP Code:
    void parseSTDIN(FILE *tmp_input){
        
    char *buffer, *contentLength getenv("CONTENT_LENGTH");
        
    int length;
        
        if(!
    contentLength){
            
    length 0;
            
    makeFailure(4);
        }else{
            
    length atoi(contentLength);
        }
        
        
    buffer = (char *) malloc(length 1);
        
        if(
    fread(buffer1lengthstdin) != length)makeFailure(4);    
        
        
    fprintf(tmp_input"%s"buffer);

        
    rewind(tmp_input);
        
    free(buffer);
    // parseSTDIN() - 
    I notice that people are viewing this but not making replies. If the code looks fine, please say something so I can look elsewhere for probs. I am nearly positive that this is the source of my problems though as I have few bugs with the program when I simulate stdin by opening a .txt file.

    Travis
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2002
    Location
    Flint, MI
    Posts
    328
    Rep Power
    13
    Traverse,

    I don't see any problems with your second example (although consider fwrite instead of fputs or fprintf).

    Rather than parsing the CGI data stream yourself, you might consider using a library to do this for you. If the bulk of your program is in C++, I recommend GNU's cgicc, which is fast and effective. If you're using most C (as it appears from your code), I suggest cgic from Boutell.com

    I have experience with both libraries, and I can say that neither has ever let me down. They are well documented, easy to use, and compile on most platforms (Windows included). They also lcome as static libraries, which will ease deployment slightly.
    Clay Dowling
    Lazarus Notes
    Articles and commentary on web development
    http://www.lazarusid.com/notes/
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12
    Clay,

    Thanks for the help. I think I will try to use cgic.

    I tried using my second version last night and it was still giving me problems. Basically, it exited out when it got to the test
    (!contentLength), which I assume to mean there are problems retrieving the "environment variables."

    The only thing keeping me from trying cgic has been my inexperience, which is a poor excuse I know. The funny thing is, that function is basically from a book written by Boutell with only a change made to kill the script if(!contentLength).

    One question, is it possible to have a server-side restriction put on the size of the incoming form's postdata? I don't think my form is too big. And I know the form works fine if I just use mailto: and send it to myself. This is utterly bewildering, especially considering that it worked fine just last year.

    Thanks again for your help.

    Travis
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2002
    Location
    Flint, MI
    Posts
    328
    Rep Power
    13
    You cannot limit the size of the input stream. You can, of course, stop reading it if you can't handle any more. But in any event, try cgic, you won't be sorry. Boutell's library makes it really easy.

    Clay
    Clay Dowling
    Lazarus Notes
    Articles and commentary on web development
    http://www.lazarusid.com/notes/
  10. #6
  11. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12

    Smile


    I'll give it a shot.

    Thanks again for your help.

    Travis
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    61
    Rep Power
    12
    Is your input simple text input or a file input?

    Parsing input from file uploads can be tricky.

    If your form has enctype="multipart/form-date" then input from it will be much trixier to decode than a simple from.
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12
    I'm really not sure to be honest with you. I guess I'm counting on it being simple text.

    How would I go about testing for this and making adjustments?

    Travis
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    61
    Rep Power
    12
    Post your HTML code here, and I will tell you what kind of form input your C program should be receiving.
  18. #10
  19. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12
    My apologies for the size.

    PHP Code:
    Sorry....had to get rid of all that....it was killing me
    The HTML is actually quite a bit larger. I have attached the file in case you want to check the whole thing out. I have "mailto" in use until I get this worked out.

    Travis
    Last edited by traverse; March 7th, 2003 at 07:18 AM.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    61
    Rep Power
    12
    And getenv("CONTENT_LENGTH") return NULL?

    Maybe the browser chooses to send the request using Transfer-Encoding: chunked

    Try printing to stdout as you are reding from stdin and redirect it to a file - it will show if the content is sent in chunks.
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    61
    Rep Power
    12
    Oops, sorry, I forgot that it is a CGI prog.
    Just print it to stdout, use a "Content-Type: text/plain" header to help viewing in browser.
  24. #13
  25. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12
    K......I'll give it a shot.

    I'm actually redoing the whole thing in PHP as we speak. I needed to learn about this language anyway. And this way I can incorporate MySQL.

    But I still would like to get the C version all polished up. It is so close to done and in my opinion a pretty cool little package if you like college basketball and the NCAA tournament.

    Thanks for the ideas. Now that I think about it, it probably is coming in one big "chunk". I was just used to working with the info from a .txt file. I would use "mailto" and send it to myself and then change the .att to .txt.

    How do I attack it if it is coming in one chunk? I just want to print it to a tmpfile() so I can manipulate the info. It actually prints out an .html file, a .txt backup of the postdata, and updates another .html file before printing the page that the user will see.

    Travis
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    61
    Rep Power
    12
    Depending on whether it is encoded as chunked or not chunked, you will have to read it and write it to a file, if you need that file.

    I am not sure if that is what it is called, but test if getenv("TRANSFER_ENCODING") returns anything, and do that experiment with printing it all back to browser.

    If it is chunked, you will need to read in a loop, where first line is a hex number telling how long the chunk is (use strtol() to convert to a number), then the chunk itself. At the end of the input, a zero-length chunk is read and then you are done.

    so do something like:

    read one line
    while ((length = strtol(line)) != 0)
    {
    read length bytes
    (skip any whitespaces)
    read one line;
    }


    Off course, if getenv("CONTENT_LENGTH") is set, you just:

    const char* str_length = getenv("CONTENT_LENGTH");
    if (str_length != NULL)
    {
    int len = atoi(str_length);
    char *buffer = malloc(len+1);
    read(0, buffer, len);
    /*
    open your file and write content of buffer to it
    */
    free(buffer);
    }
  28. #15
  29. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    35
    Rep Power
    12

    Smile


    I see.

    Thanks a bunch for your help. I'll give it a shot and get back to you. Right now I need some sleep. Its 6:30am and I've got a scary mix of PHP and C running through my head.

    Thanks again,
    Travis

IMN logo majestic logo threadwatch logo seochat tools logo