Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

atoi(getenv())

Posted on 1998-10-14
16
Medium Priority
?
1,737 Views
Last Modified: 2013-12-25
In my cgi program (written in C) for the guestbook of my homepage, several lines of codes are listed below:

   :
  printf("Content-type: text/html%c%c",10,10);  
  len=atoi(getenv("CONTENT_LENGTH"));  
   for(i=0; len && (!feof(stdin)); i++) {
                m=i;
                inputs[i].val=ReadStdin(stdin,'&',&len);
                AddToSpace(inputs[i].val);
                Convert(inputs[i].val);
                inputs[i].name=ReadData(inputs[i].val,'=');
        }                                                           :
When I try to run it, segmentation fault exists. I notice that it is the problem of the line:
  len=atoi(getenv("CONTENT_LENGTH"));  
but I don't know how to correct it. Can anyone help?
0
Comment
Question by:onki
  • 6
  • 5
  • 2
  • +2
16 Comments
 
LVL 10

Expert Comment

by:rbr
ID: 1829071
Try
char *emv;

env=getenv("CONTENT_LENGTH");
if (env) {
    len=atoi(env);
} else {
    len=0;
    fprintf(stderr;"CONTENT_LENGTH not found");
}

Are you sure that CONTENT_LENGTH is set correctly?
0
 

Author Comment

by:onki
ID: 1829072
How to set the CONTENT_LENGTH?

p.s. your code doesn't work.
0
 
LVL 11

Expert Comment

by:mouatts
ID: 1829073
You problem is that CONTENT_LENGTH isn't present and thus getenv returns NULL which is invalid as an arguement to atoi.

The reason that CONTENT_LENGTH is missing is because I would imagine the CGI was called via a GET which when used places the name value pairs in QUERY_STRING rather than via stdin and does not set the CONTENT_LENGTH.

To determine whether POST or GET was used you should check the environment variable REQUEST_METHOD.

rbrs code is correct except for the typo in the definition of env although I would use a different variable name as some compilers supply a function called env().

Steve
0
Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

 

Author Comment

by:onki
ID: 1829074
For my cgi program, I used
<FORM METHOD="POST" ACTION="/cgi-bin/guestmsg.cgi">  
but not "GET" as you said.
0
 
LVL 11

Expert Comment

by:mouatts
ID: 1829075
According to the HTTP spec there are circumstances where browsers are known to wrongly change POSTS to GETS. Whilst you haven't said anything that implies that this is the case here it may be just as well to trap GET as well.

That aside can you post the rest of the code as it would seem that the problem is elsewhere. In particular I would be interested to see the variable definition.

In addition what Web Server is involved and what platform?
0
 
LVL 8

Expert Comment

by:MaDdUCK
ID: 1829076
interesting...
0
 

Author Comment

by:onki
ID: 1829077
/* below are the codes of my cgi program */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

typedef struct {
        char *name;
        char *val;
}input;

char *ReadStdin(FILE *f, char stop, int *len);
void AddToSpace(char *str);
void Convert(char *url);
char *ReadData(char *line, char stop);

main(int argc, char *argv[])
{
        char *env;
        input inputs[10000];
        register int i, m=0;
        int len;
        time_t Ourtime;
        FILE *fp, *fopen();
        fp=fopen("/Guest/guestbook.htm","a");

        printf("Content-type: text/html%c%c",10,10);
      *env=getenv("CONTENT_LENGTH");
      if(*env) len=atoi(env);
      else {
              len=0;
              fprintf(stderr,"CONTENT_LENGTH not found\n");
      }
        for(i=0; len && (!feof(stdin)); i++) {
                m=i;
                inputs[i].val=ReadStdin(stdin,'&',&len);
                AddToSpace(inputs[i].val);
                Convert(inputs[i].val);
                inputs[i].name=ReadData(inputs[i].val,'=');
        }
        printf("<H1>Thank you for you opinion, %s! </H1>", inputs[0].val);
      printf("<H3>your e-mail is %s! </H3>", inputs[1].val);
        printf("<H3>your opinion is %s! </H3>", inputs[2].val);
        fputs("\n<p>name: ", fp);
        fputs(inputs[0].val,fp);
        fputs(",email: ", fp);
        fputs(inputs[1].val, fp);
        fputs(", opinion:", fp);
        fputs(inputs[2].val, fp);

        fclose(fp);
}
0
 
LVL 1

Expert Comment

by:wisdom042597
ID: 1829078
Take a look at this URL:
  http://www.icorp.net/wdg/

This lists a complete C-based guestbook (with source) that I wrote for the book, "HTML & CGI Unleashed" which uses the NCSA library code which is also on the site.  The actual link to test-run the script is outdated but the code definitely works.
0
 
LVL 11

Expert Comment

by:mouatts
ID: 1829079
Youe problem is here

*env=getenv("CONTENT_LENGTH");
if(*env) len=atoi(env);

this should read

env=getenv("CONTENT_LENGTH");
if(env) len=atoi(env);

Steve
0
 
LVL 8

Expert Comment

by:MaDdUCK
ID: 1829080
that's right...how could that slip by me...damn pointers :-)
0
 

Author Comment

by:onki
ID: 1829081
Segmentation fault is not caused by those two lines of code. Segmentation fault exists after the if-then condition.
0
 
LVL 10

Expert Comment

by:rbr
ID: 1829082
Can you post the code of ReadStdin pls.
0
 
LVL 11

Expert Comment

by:mouatts
ID: 1829083
Yes because you have stored the returned value from getenv at the address contained in env which at this point in time is unitialised. The chances are that it has stored the value at some abstract taken from the stack or 0.

When you the subsequently access env to obtain its length the function will search through the 'string' until it finds a null character. But as the string is not being addressed it will plough on until it happens upon a null or it generates a segment fault.

If you are really unlucky the actual problem may not even manifest itself within an access to env as the action of storing a value at an arbitary address can damage other structures within a program (I don't mean C structures here) such as the stack which can cause returns to the wrong place.

Try my solution and see if the problem disappears or at least changes. Whilst I can't be certain that there aren't some other problems with you program I would be willing to gamble more than you could afford that the two lines I mentioned are wrong.

Steve
0
 

Author Comment

by:onki
ID: 1829084
I have tried your answer. However, segmentation fault still exists after printing the warning
        "CONTENT_LENGHT does not find"
I know that the CONTENT_LENGTH is NULL and so the warning is printed out. But my question is how to set the CONTENT_LENGTH correctly so that it is not NULL any more. (Since I input something  to the form, the CONTENT_LEHGTH should not be NULL.)
0
 
LVL 11

Accepted Solution

by:
mouatts earned 50 total points
ID: 1829085
Well that wasn't your original question but the answer is you can't set the CONTENT_LENGTH. This is set by the Web Server based on the data it recieves when the form is posted. So this means that your server isn't working correctly. (I tend to think that this is not the case).

Given that you were complaining that the seg fault was occuring on  the if(env) line and now the error message is being displayed which is on a later line then things have changed as I predicted in my previous answer and you are now dealing with a different problem.

Three things that you can try. First trun on all the warnings that you compiler will allow. Currently you either have no warnings turned on, are ignoring them or your compiler is very old.

Change the line

    FILE *fp, *fopen();

To
   FILE *fp;

As you have already included stdio.h which provides the deffinition of fopen (and your compiler should have warned you)

Change the definition of
    input inputs[10000];
to
   input inputs[1000];

As the amount of room being created on the stack may be too much depending on platform and compiler

Steve


0
 

Author Comment

by:onki
ID: 1829086
Actually, the segmentation fault still exists on the line
   for((i=0; len && (!feof(stdin)); i++)
  after I have tried your answer, since the value of len is NULL.
Anyway, I don't want to argue with you anymore on  whether my original question is the question I asked. I give the marks to you now.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Recently I have been answering a lot of questions like this in IT forums that I frequent. The question posed is usually something along the lines of "We have software X installed and need to uninstall it for reason Y" or some other variant of the sa…
In this tutorial I will show you how to make a simple HTML bar chart with the usage of WhizBase, If you want more information about WhizBase please read my previous articles at http://www.experts-exchange.com/ARTH_5123186.html (http://www.experts-ex…
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question