⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgi-util.c

📁 cgi分析
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  cgi-util.c    version 2.2.0    by Bill Kendrick <bill@newbreedsoftware.com>  and Mike Simons <msimons@moria.simons-clan.com>  and Gary Briggs <chunky@icculus.org>    Other contributions; see CHANGES.txt    New Breed Software  http://www.newbreedsoftware.com/cgi-util/    April 6, 1996 - May 16, 2004*/#include <stdio.h>#include <ctype.h>#include <errno.h>#include <unistd.h>#ifndef NO_STDLIB_H#include <stdlib.h>#elsechar *getenv();#endif#include <string.h>#include "cgi-util.h"/* Globals: */cgi_entry_type * cgi_entries = NULL;cgi_cookie_type * cgi_cookies = NULL;int cgi_num_entries = 0;int cgi_num_cookies = 0;int cgi_errno = CGIERR_NONE;int cgi_request_method = CGIREQ_NONE;int cgi_content_type = CGITYPE_NONE;char * cgi_query = NULL;/* English error strings: */char * cgi_error_strings[CGIERR_NUM_ERRS] = {  "", "Not an integer", "Not a double", "Not a boolean",  "Unknown method", "Incorrect Content Type",  "NULL Query String", "Bad Content Length",  "Content Length Discrepancy", "No Cookies", "Cookie Not Found",  "Not That Many"};/* Debugging.  If set, this library will attempt to append debugging   information to a file named "debug.txt" in the current directory. *//* #define DEBUG *//* Converts hexadecimal to decimal (character): */char x2c(char *what){  char digit;    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));  digit *= 16;  digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));  return (digit);}/* Unescapes "%"-escaped characters in a query: */void unescape_url(char *url){  int x,y,len;    len = strlen(url);    for (x=0, y=0; url[y]; ++x, ++y)    {      if ((url[x] = url[y]) == '%'	  && y < len - 2)   /* 2.0.4 - MJ Pomraning (pilcrow@mailbag.com) */	{	  url[x] = x2c(&url[y+1]);	  y+=2;        }    }  url[x] = '\0';}/* Converts pluses back to spaces in a query: */void plustospace(char *str){  int x;    for (x=0; str[x]; x++)    if (str[x] == '+')      str[x] = ' ';}/* Internal use: Write debugging stuff to a file */void debug(char * str1, char * str2){#ifdef DEBUG  FILE * fi;    fi = fopen("debug.txt", "a");  if (fi != NULL)    {      fprintf(fi, "%s:%s\n", str1, str2);      fclose(fi);    }#endif}/* Internal use: Read a line and return its length: */int lineread(FILE * stream, char * buf, int count){  char * c;  c = fgets(buf, count, stream);   if (c != NULL)    return(strlen(buf));  else    return(0);}/* Initialize the CGI.  Grab data from the browser and prepare it for us. */int cgi_init(void){	int cl, i, in_multipart_headers, which_entry, length_gotten, in_name;	char * boundary;    	/* Default, no errors, no name/value pairs ("entries"): */  	cgi_errno = CGIERR_NONE;	cgi_num_entries = 0;	length_gotten = 0; 	cgi_parse_cookies();   	/* Check for REQUEST_METHOD (set by HTTP server): */  	if (getenv("REQUEST_METHOD") == NULL)    {      /* None set?  Assume the user is invoking the CGI from a shell prompt	 (for debugging): */      		cgi_request_method = CGIREQ_NONE;    }	else    {      /* Determine the exact request method, and grab the data (if any)	 in the appropriate manner: */      		if (strcmp(getenv("REQUEST_METHOD"), "POST") == 0)		{			/* Post method (data is sent to us via "stdin"): */	  			cgi_request_method = CGIREQ_POST;			if (getenv("CONTENT_TYPE") == NULL)			{				/* Content type is not set! */				cgi_errno = CGIERR_INCORRECT_TYPE;				cgi_content_type = CGITYPE_UNKNOWN;	      				return(cgi_errno);			}			else if (strstr(getenv("CONTENT_TYPE"),							"application/x-www-form-urlencoded") == 						getenv("CONTENT_TYPE"))			{				cgi_content_type = CGITYPE_APPLICATION_X_WWW_FORM_URLENCODED;				/* How much data do we expect? */	      				if (getenv("CONTENT_LENGTH") == NULL ||						sscanf(getenv("CONTENT_LENGTH"), "%d", &cl) != 1)				{					cgi_errno = CGIERR_BAD_CONTENT_LENGTH;					return(cgi_errno);				}				/* Create space for it: */	      				cgi_query = malloc(cl + 1);				/* 2.0.1 - Tadek Orlowski (orlowski@epnet.com) ... "+1" */	      				if (cgi_query == NULL)				{					cgi_errno = CGIERR_OUT_OF_MEMORY;					return(cgi_errno);				}				/* Read it in: */	      				fgets(cgi_query, cl + 1, stdin);				/* Verify that we got as much data as we expected: */	      				if (cgi_query == NULL || strlen(cgi_query) != cl)					cgi_errno = CGIERR_CONTENT_LENGTH_DISCREPANCY;			}			else if (strstr(getenv("CONTENT_TYPE"),			  "multipart/form-data") == getenv("CONTENT_TYPE"))			{			cgi_content_type = CGITYPE_MULTIPART_FORM_DATA;	      			cgi_query = malloc(2050);			if (cgi_query == NULL)			{				cgi_errno = CGIERR_OUT_OF_MEMORY;				return(cgi_errno);			}	      /* Determine the boundary string: */	      			if (strstr(getenv("CONTENT_TYPE"),"boundary=") == NULL)			{				cgi_errno = CGIERR_NO_BOUNDARY;				return(cgi_errno);			}	      			/* boundary = strdup(strstr(getenv("CONTENT_TYPE"),				       "boundary=") + 9); */			boundary = malloc(strlen(strstr(getenv("CONTENT_TYPE"),                                "boundary=")) - strlen("boundary=") + 1);			strcpy(boundary, strstr(getenv("CONTENT_TYPE"), "boundary=") +                     strlen("boundary="));			debug("boundary", boundary);	      	      	      /* Read in until there's no more: */	      			in_multipart_headers = 0;			which_entry = -1;	      			do			{				length_gotten = lineread(stdin, cgi_query, 2048);		  				debug("cgi_query", cgi_query);		  				if (length_gotten > 0)				{					if (strstr(cgi_query, boundary) == cgi_query + 2 &&							cgi_query[0] == '-' && cgi_query[1] == '-')					{						/* We got a boundary! */			  						in_multipart_headers = 1;						which_entry = -1;					}					else /* (Not a boundary) */					{						if (in_multipart_headers == 1)						{							/* We had just got a boundary, read headers: */							if (cgi_query[0] == '\r' || cgi_query[0] == '\n')							{								/* Blank line, end of headers: */				  								in_multipart_headers = 0;							}							else /* (Not a blank line) */							{								/* What kind of header is it? */				  								if (strstr(cgi_query,"Content-Disposition: ") == cgi_query)								{									/* Content-disposition: */ 									/* For now, just look for "name=": */									if (strstr(cgi_query, "name=\"") != NULL)									{										/* Add a new entry: */										which_entry = cgi_num_entries;										cgi_num_entries++;										/* Make more room: */					  										cgi_entries = realloc(cgi_entries,															sizeof(cgi_entry_type) *															cgi_num_entries);					  										if (cgi_entries == NULL)										{											cgi_errno = CGIERR_OUT_OF_MEMORY;											return(cgi_errno);										}										/* Fill in the name slot: */										cgi_entries[which_entry].name =										malloc(strlen(strstr(cgi_query,"name=")) -strlen("name=") + 1);										strcpy(cgi_entries[which_entry].name,												strstr(cgi_query, "name=") +												strlen("name=") +												strlen("name="));					  					  /* strdup(strstr(cgi_query,					     "name=\"") +					     6); */					  					  					  /* Truncate after quote: */					  					  if (strchr(cgi_entries[which_entry].						     name, '\"') != NULL)					    {					      strcpy(strchr(cgi_entries							    [which_entry].name,							    '\"'), "\0");					    }					  					  					  /* Set default content-type: */					  					  cgi_entries[which_entry].					    content_type =					    "application/octet-stream";					  					  					  /* Set default content-length: */					  					  cgi_entries[which_entry].					    content_length = 0;					  					  					  /* Set default value: */					  					  cgi_entries[which_entry].val =					    malloc(1);					  					  cgi_entries[which_entry].val[0] =					    '\0';					  					  					  debug("entry.name",						cgi_entries[which_entry].name);					}				    }				  else if (strstr(cgi_query,						  "Content-Type: ") ==					   cgi_query)				    {				      /* Content-type: */				      				      cgi_entries[which_entry].content_type =					malloc(strlen(strstr(cgi_query,							     "Content-Type: ")) - strlen("Content-Type: ") + 1);				      cgi_entries[which_entry].content_type =					strcpy(cgi_entries[which_entry].content_type,					       strstr(getenv("CONTENT_TYPE"), "Content-Type: ") +					       strlen("Content-Type: "));				      					/* strdup(strstr(cgi_query,					   "Content-Type: ") +					   14); */				      				      debug("entry.content_type",					    cgi_entries[which_entry].					    content_type);				    }				}			    }			  else /* in_multipart_headers == 0 */			    {			      /* If we're recording into a particular				 entry, copy the data: */			      			      if (which_entry != -1)				{				  /* Make more room: */				  				  cgi_entries[which_entry].val =				    realloc(cgi_entries[which_entry].val,					    strlen(cgi_entries[which_entry].						   val) + length_gotten + 1);				  				  if (cgi_entries[which_entry].val == NULL)				    {				      cgi_errno = CGIERR_OUT_OF_MEMORY;				      return(cgi_errno);				    }				  				  				  /* Append the data: */				  				  memcpy(cgi_entries[which_entry].val +					 (cgi_entries[which_entry].					  content_length),					 cgi_query, length_gotten);				  cgi_entries[which_entry].content_length =				    (cgi_entries[which_entry].content_length +				     length_gotten);				}			    }			}		    }		}	      while (length_gotten > 0);	      	      free(cgi_query);	      cgi_query = NULL;	    }	  else	    {	      /* Content type is unrecognized! */	      	      cgi_errno = CGIERR_INCORRECT_TYPE;	      cgi_content_type = CGITYPE_UNKNOWN;	      	      return(cgi_errno);	    }	}      else if (strcmp(getenv("REQUEST_METHOD"), "GET") == 0)	{	  /* For now, assume Content Type of	     "application/x-www-form-urlencoded"	     (Is this a bad assumption?) */	  	  cgi_content_type = CGITYPE_APPLICATION_X_WWW_FORM_URLENCODED;	  	  	  /* GET method (data sent via "QUERY_STRING" env. variable): */	  	  cgi_request_method = CGIREQ_GET;	  	  	  /* Get a pointer to the data: */	  	  cgi_query = getenv("QUERY_STRING");	  	  if (cgi_query == NULL)	    {	      /* Does the "QUERY_STRING" env. variable not exist!? */	      	      /* cgi_errno = CGIERR_NULL_QUERY_STRING; */	      	      /* return(cgi_errno); */	      	      cl = 0;	      cgi_query = "";	    }	  else	    {	      /* Determine the content length by seeing how big the		 string is: */	      	      cl = strlen(cgi_query);	    }	}      else	{	  /* Something else? We can't handle it! */	  	  cgi_request_method = CGIREQ_UNKNOWN;	  cgi_errno = CGIERR_UNKNOWN_METHOD;	  cgi_num_entries = 0;	  	  return(cgi_errno);	}                        if (cgi_content_type != CGITYPE_MULTIPART_FORM_DATA)	{	  /* How many entries (name/value pairs) do we need to	     allocate space for? (They should be separated by "&"'s) */	  	  cgi_num_entries = 0;	  	  for (i = 0; i <= cl; i++)	    if (cgi_query[i] == '&' || cgi_query[i] == '\0')	      cgi_num_entries++;	  	  	  /* Allocate the space for that many structures: */	  	  cgi_entries = malloc(sizeof(cgi_entry_type) * cgi_num_entries);	  if (cgi_entries == NULL)	    {	      cgi_errno = CGIERR_OUT_OF_MEMORY;	      return(cgi_errno);	    }	  	  	  /* Grab each name/value pair: */	  	  cgi_num_entries = 0;	  	  	  /* (Begin with the first half of the first pair): */	  	  if (cgi_query[0] != '\0' && cgi_query[0] != '&')	    {	      cgi_entries[0].name = cgi_query;	      cgi_entries[0].content_type = "text/html";	    }	  	  	  /* Go through the entire string of characters: */	  	  in_name = 1;	  for (i = 0; i <= cl; i++)	    {	      if (cgi_query[i] == '&')		{		  /* "&" represents the end of a name/value pair: */		  		  cgi_entries[cgi_num_entries].name = cgi_query + i + 1;		  cgi_entries[cgi_num_entries].content_type = "text/html";		  cgi_query[i] = '\0';                  in_name = 1;		}	      else if (cgi_query[i] == '=' && in_name)		{		  /* "=" is the end of the name half of a name/value pair: */		  		  cgi_entries[cgi_num_entries].val = cgi_query + i + 1;		  		  /*  plustospace(cgi_entries[cgi_num_entries].val);		      unescape_url(cgi_entries[cgi_num_entries].val); */		  		  cgi_num_entries++;		  in_name = 0;		  		  cgi_query[i] = '\0';		}	    }	  	  for (i = 0; i < cgi_num_entries; i++)	    {	      plustospace(cgi_entries[i].val);	      unescape_url(cgi_entries[i].val);	    }	  	}                  /* Fix any NULL strings to be empty strings */      /* 2.0.4 - MJ Pomraning (pilcrow@mailbag.com) */            for (i = 0; i < cgi_num_entries; i++)	{	  if (cgi_entries[i].name == NULL)	    cgi_entries[i].name = "";	  if (cgi_entries[i].val == NULL)	    cgi_entries[i].val = "";	}    }    return(CGIERR_NONE);}/* Free up memory that was allocated when we called "cgi_init()": */void cgi_quit(void){  if (cgi_query != NULL)    free(cgi_query);    if (cgi_entries != NULL)    free(cgi_entries);  if (cgi_cookies != NULL)    free(cgi_cookies);  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -