/* cgi-printarg.c -- CGI プログラムに対する引数を表示するプログラム ~yas/syspro/www/cgi-printarg.c */ #include /* getenv(), malloc() */ #include /* printf() */ #include /* strlen() */ #include /* read() */ #include /* read() */ #include /* read() */ #include /* isdigit() */ extern void print_header(void); extern void print_content(void); extern char *get_query_string(); extern char *read_query_string(); extern void safe_printenv( char *name ); extern void safe_print_string( char *str ); extern char *html_escape( char *str ); extern char *decode_url( char *str ); extern char *getparam( int qc, char *qv[], char *name ); extern int string_split( char *str, char del, int *countp, char ***vecp ); extern void free_string_vector( int qc, char **vec ); extern int countchr( char *s, char c ); int main() { print_header(); print_content(); } void print_header() { printf("Content-Type: text/html\n"); printf("\n"); } void print_content() { char *query_string ; int qc ; char **qv ; int i ; printf("
\n");

	safe_printenv("REQUEST_METHOD");
	safe_printenv("SCRIPT_NAME");
	safe_printenv("QUERY_STRING");
	safe_printenv("CONTENT_LENGTH");

	query_string = get_query_string();
	printf("query_string=");
	safe_print_string( query_string ); printf("\n");

	if( query_string == NULL )
	{
		printf("No query string.\n");
	}
	else if( string_split( query_string,'&',&qc, &qv ) < 0 )
	{
		printf("Error while parsing query string\n");
	}
	else
	{
		for( i=0 ; i\n");
	if( query_string )
		free( query_string );
}

char *
get_query_string()
{
	char *request_method, *query_string;
	request_method = getenv("REQUEST_METHOD");
	if( request_method == 0 )
		return( 0 );
	else if( strcmp(request_method,"GET") == 0 )
	{
		query_string = getenv("QUERY_STRING");
		if( query_string == 0 )
			return( 0 );
		else
			return( strdup(query_string) );
	}
	else if( strcmp(request_method,"POST") == 0 )
	{
		return( read_query_string() );
	}
	else
	{
		printf("Unknown method: ");
		safe_print_string( request_method );
		printf("\n");
		return( 0 );
	}
}

char *
read_query_string()
{
	int   clen ;
	char *content_length ;
	char *buf ;

	content_length = getenv("CONTENT_LENGTH");
	if( content_length == 0 )
	{
		return( 0 );
	}
	else
	{
		clen = strtol( content_length,0,10 );
		buf = malloc( clen + 1 );
		if( buf == 0 )
		{
			printf("read_query_string(): no memory\n");
			exit( -1 );
		}
		if( read(0,buf,clen) != clen )
		{
			printf("read error.\n");
			exit( -1 );
		}
		buf[clen] = 0 ;
		return( buf );
	}
}

void
safe_printenv( char *name )
{
	char *val ;
	char *safe_val ;

	printf("%s=",name );
    	val = getenv( name );
	safe_print_string( val );
	printf("\n");
}


void
safe_print_string( char *str )
{
	char *safe_str ;

	if( str == 0 )
	{
		printf("(null)");
		return;
	}
	safe_str = html_escape( str );
	if( safe_str == 0 )
	{
		printf("(no memory)");
	}
	else
	{
		printf("%s",safe_str );
		free( safe_str );
	}
}

char *
html_escape( char *str )
{
	int len ;
	char c, *tmp, *p, *res ;

	len = strlen( str );
	tmp = malloc( len * 6 + 1 );
	if( tmp == 0 )
		return( 0 );
	p = tmp ;
	while( (c = *str++) )
	{
		switch( c )
		{
		case '&': memcpy(p,"&", 5); p += 5 ; break;
		case '<': memcpy(p,"<",  4); p += 4 ; break;
		case '>': memcpy(p,">",  4); p += 4 ; break;
		case '"': memcpy(p,""",6); p += 6 ; break;
		default:  *p = c ;              p++ ;    break;
		}
	}
	*p = 0 ;
	res = strdup( tmp );
	free( tmp );
	return( res );
}

char *
decode_url( char *str )
{
	int len ;
	char c, *tmp, *p, *res ;

	len = strlen( str );
	tmp = malloc( len + 1 );
	if( tmp == 0 )
		return( 0 );
	p = tmp ;

	while( *str )
	{
		if( *str == '%' && isxdigit(*(str+1)) && isxdigit(*(str+2)) )
		{
			char hexstr[3] ;
			hexstr[0] = *(str+1);
			hexstr[1] = *(str+2);
			hexstr[2] = 0 ;
			c = strtol( hexstr, 0, 16 );
			*p ++ = c ;
			str += 3 ;
		}
		else if( *str == '+' )
		{
			*p ++ = ' ' ;
			str ++ ;
		}
		else
		{
			*p ++ = *str ;
			str ++ ;
		}
	}
	*p = 0 ;
	res = strdup( tmp );
	free( tmp );
	return( res );
}

char *
getparam( int qc, char *qv[], char *name )
{
	int i;
	size_t len;

	len = strlen( name );
	for( i=0; i