Thread: Request QueryString Value for CGI style app

  1. #1
    Registered User
    Join Date
    Dec 2004
    Location
    London
    Posts
    12

    Request QueryString Value for CGI style app

    Hello All,

    I'm hoping this is not a stupid question but I am quite new to C, so If it is dumb, please humour me.

    I am trying to write a function for use in my CGI style app.

    The function is to return the value of the specified item in the QUERY_STRING environment variable. If the item does not exist it returns a blank string "".

    This is what I have done but not working how I thought it would.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
     
    int main(){
     printf(QueryString("test"));
    }
     
    // ---- Return QueryString Value ---- //
    QueryString(char *strobj){
     char *qs = getenv("QUERY_STRING");
     char *init_word;
     if (qs){
            if (strstr(qs, strobj)){
       char *word;
       char *strtype = "name";
       char *stropt = "false";
       word = strtok(qs, "&,=");
       while (word){
        if (strcmp(word, strobj)){
         if (strtype == "name"){
          stropt = "true";
         }
         else{
          if (stropt == "true"){
           return word;
           break;
          }
         }
        }
        if (strtype == "name"){
         strtype = "value";
        }
        else{
         strtype = "name";
        }
        word = strtok(NULL, "&,=");
       }
      }
      else{
       return "";
      }
     }
     else{
            return "";
     }
    }
    Could someone please give me a helping hand.

    Also does anyone know of any good C CGI tutorials?

    Thanks and any help is much appreciated.

    Kind Regards,
    Tarran
    Last edited by Tarran; 12-29-2004 at 02:59 PM.

  2. #2
    Registered User Azuth's Avatar
    Join Date
    Feb 2002
    Posts
    236
    I think one of your problems may be defining your string thus char *stropt = "false"; you are making a string literal, that is a string that the compiler never expects to be changed. But I have to guess, since you didn't explain what it's doing. Always helps if you define what it does or show a sample of the output so people don't have to compile the program to help you.
    Demonographic rhinology is not the only possible outcome, but why take the chance

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I wrote this little CGI library for myself a long time ago. Here's a link to the relevant files. Have fun:
    http://www.tinymaze.com/libcgi.c
    http://www.tinymaze.com/cgi.h

    EDIT: It could use a little sprucing up probably. For instance, I never added a couple of functions that I should have (free_opt_vals() and free_cookies()).
    Last edited by itsme86; 12-29-2004 at 04:57 PM.
    If you understand what you're doing, you're not learning anything.

  4. #4

  5. #5
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    there a couple of things i see offhand.
    for one you shouldn't implicitly declare getenv. its located in the stdlib.h so you should include that. There could be undefined behaviour in your calls to it.

    your QueryString function doesn't return a type, which it should be doing. Also the "QUERY_STRING" environment variable (i could be wrong) is returned when the http request method is get, I don't know that it will work without a http request.

    Code:
    if (strstr(qs, strobj)){//if strobj in qs
    why are you looking for a substring in the query string. Assuming this a valid CGI app in C, if you do get the value of QUERY_STRING, the next procedures should be to parse it and decode its hexadecimal format to decimal. (perhaps there is something i'm not seeing in your code?)

    Code:
    word = strtok(qs, "&,=")
    here you seem to start decode the string. however the strtok function takes as an argument the delimeters your looking for. why are you looking for ',' character. the ones you should be concerned with are '&' and '=' and maybe '+'.

    I didn't go through all of the code i stopped but those would be a few things i would fix.
    First however you should get some info on the CGI standard here some FAQ a couple tutorials:
    http://computer.howstuffworks.com/cgi.htm
    http://www.coding-zone.co.uk/cpp/cgi/170401cgicpp.shtml
    http://perl.about.com/library/weekly/aa070901a.htm

    hoped it helped a little bit.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  6. #6
    Registered User
    Join Date
    Dec 2004
    Location
    London
    Posts
    12
    Thanks everyone for your help and suggestions.

    I will have a play and let you know how I go.

  7. #7
    Registered User
    Join Date
    Dec 2004
    Location
    London
    Posts
    12
    I sorted it out - must say thanks for everyones help.

    Code:
    char *QueryString(char *strobj) {
    	if (getenv("QUERY_STRING")) {
            if (strstr(getenv("QUERY_STRING"), strobj)) {
    			char *word;
    			boolean strtype = TRUE;
    			int stropt = 0;
    			word = strtok(getenv("QUERY_STRING"), "&=");
    			while (word) {
    				if (strtype == TRUE) {
                        if (strstr(word, strobj)) {
    						stropt = 1;
    					}
    					strtype = FALSE;
    				} else {
    					if (stropt == 1) {
    						return ("%s", word);
    					}
    					strtype = TRUE;
    				}
    				word = strtok(NULL, "&=");
    			}
    		} else {
    			return "";
    		}
    	} else {
            return "";
    	}
    }
    Is there a better way to do this?

    Thanks once again.

  8. #8
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    I am trying to write a function for use in my CGI style app.
    what do you mean CGI STYLE? is this going to be used on the web or your checking for local envionement variables?

    The function is to return the value of the specified item in the QUERY_STRING environment variable. If the item does not exist it returns a blank string "".
    if this is the case then you don't really need to decode it do you?

    As it stands your code is convuluted. it does 2 many things. It parses and searches for the substring.

    why not have two functions. one function parses the QUERY_STRING and the other simply searches for the substring in QUERY_STRING return value. This makes it more modular and easier to debug if and when their is a probelem. As it stands you have if statements at least 5 deep, perhaps we look at it differently but i find it a little messy and i would think it would be easier to debug when a problem crops up. You don't want to write your code and then two weeks from now you can't even remember why and how you did it. make it more modular.
    Not to mention if there is a better or faster algorithem you find later to do one thing you can implement it without having to rewrite the whole function and crashing the code.

    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
    char *QueryString(char *strobj) {
    	if (getenv("QUERY_STRING")) {
                // Code
    	}
    }
    And so what happens if getenv() returns NULL? It's a crash waiting to happen. A good reason to listen to compiler warnings.
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User
    Join Date
    Dec 2004
    Location
    London
    Posts
    12

    Re:

    Code:
    char *QueryString(char *strobj) {
    	if (getenv("QUERY_STRING")) {
                // Code
    	}
    }
    And so what happens if getenv() returns NULL? It's a crash waiting to happen. A good reason to listen to compiler warnings.
    Cheers for your input itsme86.
    As I stated I am very new to C but i thought if I ended my if statement with an else this would run if getenv("QUERY_STRING") returned a NULL.

    Code:
    if (getenv("QUERY_STRING")) {
      // Code
    } else {
      // null code
    }
    As I am not getting any compiler warnings I thought this would be fine. Is there a better way to do this.

  11. #11
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Yeah, that should work with the else. The indentation is kinda weird so I thought it was part of another block.
    If you understand what you're doing, you're not learning anything.

  12. #12
    Registered User
    Join Date
    Dec 2004
    Location
    London
    Posts
    12
    For some reason when I access this function I only can use it once and then if I try to access it again it doesn't work (When using this querystring: name1=value1&name2=value2).

    It seems that the function is continuing from when it was previously accessed.

    Code:
    int main(int argc, char *argv[]) {
        printf("HTTP/1.1 200 OK\n");
        printf("Content-Type: text/html\n\n");
        printf("%s<br />", QueryString("name1"));
        printf("%s<br />", QueryString("name2"));
        return 0;
    }
    
    char *QueryString(char *strobj) {
        if (getenv("QUERY_STRING")) {
            if (strstr(getenv("QUERY_STRING"), strobj)) {
                char *word;
                boolean strtype = TRUE;
                int stropt = 0;
                word = strtok(getenv("QUERY_STRING"), "&=");
                while (word) {
                    if (strtype == TRUE) {
                        if (strstr(word, strobj)) {
                            stropt = 1;
                        }
                        strtype = FALSE;
                    } else {
                        if (stropt == 1) {
                            return ("%s", word);
                            break;
                        }
                        strtype = TRUE;
                    }
                    word = strtok(NULL, "&=");
                }
            } else {
                return "";
            }
        } else {
            return "";
        }
    }
    Does anyone know why this would be happening and how I can fix this?

  13. #13
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    From man strtok:
    Code:
    BUGS
           Never use these functions. If you do, note that:
                  These functions modify their first argument.
                  The identity of the delimiting character is lost.
                  These functions cannot be used on constant strings.
    The bolded line seems like it might be your problem.
    If you understand what you're doing, you're not learning anything.

  14. #14
    Registered User
    Join Date
    Dec 2004
    Location
    London
    Posts
    12
    I've tried using strcpy function and then using the strtok on the copied string and the program causes a app error and terminates.

    Is this not what I should be doing? What do I need to do to fix this?

    Code:
    char *QueryString(char *strobj) {
        if (getenv("QUERY_STRING")) {
            if (strstr(getenv("QUERY_STRING"), strobj)) {
                char *init_word;
                char *word;
                boolean strtype = TRUE;
                int stropt = 0;
                strcpy(init_word, getenv("QUERY_STRING"));
                word = strtok(init_word, "&=");
                while (word) {
                    if (strtype == TRUE) {
                        if (strstr(word, strobj)) {
                            stropt = 1;
                        }
                        strtype = FALSE;
                    } else {
                        if (stropt == 1) {
                            return ("%s", word);
                            break;
                        }
                        strtype = TRUE;
                    }
                    word = strtok(NULL, "&=");
                }
            } else {
                return "";
            }
        } else {
            return "";
        }
    }
    Cheers

  15. #15
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
                char *init_word;
                char *word;
                boolean strtype = TRUE;
                int stropt = 0;
                strcpy(init_word, getenv("QUERY_STRING"));
    init_word doesn't have any memory set aside for it and you're trying to copy a string into it. You're lucky the function works at all. You need to either malloc() memory for it or turn init_word into an array.
    If you understand what you're doing, you're not learning anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Controls Style: Resource View vs Running App
    By devGordon in forum Windows Programming
    Replies: 4
    Last Post: 06-19-2009, 09:43 PM
  2. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  3. Instant messenger app help
    By AusTex in forum C Programming
    Replies: 2
    Last Post: 05-01-2005, 12:41 AM
  4. best program to start
    By gooddevil in forum Networking/Device Communication
    Replies: 4
    Last Post: 05-28-2004, 05:56 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM