INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

CGI Strangeness Across Platforms

CGI Strangeness Across Platforms

(OP)
So I've gotten a start writing CGI programs in C. I've been trying to learn how to process form data, and I have a few of the basics down. I installed Abyss web server on both my Windows PC and Ubuntu laptop. I've been doing the coding on my Windows PC and then copying it over to my laptop (compiling and running on both).

I felt that I had a hang of the GET method, so I tried one with the POST method. Here's my code:

CODE --> C

/*CGI07.c: I kind of have the hang of the "GET" method
	of input. Now I'm going to try "POST".*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXQS	1024
int main(void)
{
	char *s;
	char e[MAXQS];
	long int len;
	char *parse_qs(const char *,char *);

	printf("Content-Type: text/html; charset=ISO-8859-1\n\n");
	
	printf("<HTML><TITLE>Yay!</TITLE>");
	printf("<BODY BGCOLOR=\"#4411AA\" TEXT=\"#BBBBFF\">");
	printf("<CENTER><H1>Spontaneously Generated Web Page!</H1></CENTER>");
	printf("<HR>");
	len=atol(getenv("CONTENT_LENGTH"));
	printf("len = %ld<BR>",len);
	if(len==0){
		printf("Error getting CONTENT_LENGTH.\n");
		exit(1);
	}
	fgets(e,len+1,stdin);
	printf("QUERY_STRING:<BR>%s<BR><BR>",e);
	printf("String Length: %ld<BR>",len);

	while(s=parse_qs(e," <==> "))
		printf("%s<BR>",s);

	printf("</BODY></HTML>\n\n");

  return 0;
}

#define MAXFIELD	64
#define MAXVALUE	512
#define MAXSEP		32
char *parse_qs(const char *QS,char *sep)
{
	char field[MAXFIELD];
	char value[MAXVALUE];
	int a,QSlen;
	static char ret[MAXFIELD+MAXVALUE+MAXSEP];
	static int i=0;
	void decode(char []);

	/*Starting off with this because this function is meant to
		be called repeatedly, so it's okay to check 'i' right away.*/
	QSlen=strlen(QS);
        if(i>=QSlen-1){
		i=0;
		return NULL;
	}

	ret[0]='\0';/*'NULL' it out for subsequent calls.*/

	/*Get field.*/
	a=0;
	while(QS[i]!='=')
		field[a++]=QS[i++];
	field[a]='\0';
	decode(field);
	/*Get past equals sign.*/
	i++;

	/*Get value.*/
	a=0;
	while((QS[i]!='&') && (QS[i]!='\0'))
		value[a++]=QS[i++];
	value[a]='\0';
	decode(value);

	i++;/*Get past ampersand.*/

	/*In the off-chance that sep is too large...*/
	if(strlen(sep)>MAXSEP)
		sep[MAXSEP]='\0';

	strcat(ret,field);
	strcat(ret,sep);
	strcat(ret,value);
	return ret;
}

void decode(char buff[])
{
	int w=0;
	int h,mark;
	char mini[3];
	char *endptr;/*Only needed for strtol().*/

	while(buff[w]){
		switch(buff[w]){
			case '%':
         	/*It's three friggin' characters. It's not worth a loop.*/
				mini[0]=buff[w+1];
				mini[1]=buff[w+2];
				mini[2]='\0';
				h=(int)strtol(mini,&endptr,16);
				buff[w++]=h;
				mark=w;/*Mark where we are in the array.*/
				/*Draw-in the rest of the array.*/
				while(buff[w+2]){
					buff[w]=buff[w+2];
					w++;
				}
				buff[w]='\0';
				w=mark;
				break;
			case '+':
				buff[w++]=' ';
				break;
			default:
				w++;
				break;
		}
	}
} 
This is the version I compiled and ran in Ubuntu. However, when I was testing it out, I didn't run it as a CGI. I ran it in a terminal, and for some reason I kept getting a "SEGMENTATION FAULT (core dumped)" after it displayed the first printf. Even stranger, I found that if I ended all my printf()s with \n they would display, but I would still get segmentation faults when it got to the getenv(). I realize that running from a terminal will not have the CONTENT_LENGTH variable, but shouldn't it just return NULL instead of crashing?
Out of frustration I decided to run it as a CGI anyway, and to my surprise it worked.

Also, with the fgets() from above, on my Windows PC I originally had:
fgets(e,MAXQS,stdin);
I coded this without much thought. After all, what's the point in getting the string length if I'm not going to use it and instead use the #define value?
But this was causing another issue. In Windows, this runs just fine. The program gets fed the query string and the fgets() exits successfully. In Ubuntu, it hangs and the server times-out. I'm assuming that it hangs because it's waiting for MAXQS characters. I figured fgets() is a pretty standard function, I'm surprised it behaves differently on both systems. I would love some clarity on this!

RE: CGI Strangeness Across Platforms

The function getenv() returns a NULL pointer when the environment variable isn't defined. Passing that NULL to atol() gives you your SEGMENTATION FAULT.

RE: CGI Strangeness Across Platforms

(OP)
D'oh. Thanks. I was confusing the empty string "" with NULL.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close