From f4c20290509d7ed3a8fd5304577e7a4cc0b9d974 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 3 Apr 2007 03:49:53 +0000 Subject: Ok, no code is left in src, it's all in src/old. We'll gradually move code back into src as it's fixed and re-org'd. This includes tests, which, I may write a unit test system into libbu++ just to make my life easier. --- src/old/cgi.cpp | 644 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 644 insertions(+) create mode 100644 src/old/cgi.cpp (limited to 'src/old/cgi.cpp') diff --git a/src/old/cgi.cpp b/src/old/cgi.cpp new file mode 100644 index 0000000..1fecbbe --- /dev/null +++ b/src/old/cgi.cpp @@ -0,0 +1,644 @@ +#include +#include +#include +#include +#include + +#include "cgi.h" + +Cgi::Cgi( const char *strSource ) : + aContent( new HashFunctionString(), 151, true ) +{ + int length, j, k, mode = 0, slen = 0; + char hexbuf[3] = { 0, 0, 0 }; + char *buf, chr; + Item *cur = NULL; + int nCur = 0; + + if( strSource != NULL ) + { + loadContent( strSource ); + } + + if( ( getenv( "CONTENT_LENGTH" ) ) ) + { + if( !strcmp + ( getenv( "CONTENT_TYPE" ), + "application/x-www-form-urlencoded" ) ) + { + length = atoi( getenv( "CONTENT_LENGTH" ) ); + buf = new char[length + 1]; + fread( buf, 1, length, stdin ); + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_STDINPUT; + for( j = 0; j < length; j++ ) + { + switch ( buf[j] ) + { + case '=': + cur->name = new char[slen + 1]; + slen = 0; + break; + + case '&': + cur->value = new char[slen + 1]; + cur->len = slen; + slen = 0; + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_STDINPUT; + break; + + default: + switch ( buf[j] ) + { + case '%': /* per-cents mean a hex-code for an ASCII char */ + j += 2; + slen++; + break; + + default: /* Nothing special, move along, folks... */ + slen++; + break; + } + break; + } + } + cur->value = new char[slen + 1]; + cur->len = slen; + slen = 0; + mode = 0; + cur = ( Item * ) aVars.getAt( 0 ); + k = 0; + nCur = 0; + for( j = 0; j < length; j++ ) + { + switch ( buf[j] ) + { + case '=': + mode = 1; + k = 0; + break; + + case '&': + mode = 0; + k = 0; + nCur++; + cur = ( Item * ) aVars.getAt( nCur ); + break; + + default: + switch ( buf[j] ) + { + case '%': /* per-cents mean a hex-code for an ASCII char */ + hexbuf[0] = buf[++j]; + hexbuf[1] = buf[++j]; + chr = ( char ) ( strtol( hexbuf, NULL, 16 ) ); + break; + + case '+': /* Pluses mean spaces, odd, I know... */ + chr = ' '; + break; + + default: /* Nothing special, move along, folks... */ + chr = buf[j]; + break; + } + if( mode == 0 ) + { + cur->name[k] = chr; + cur->name[++k] = '\0'; + } + else + { + cur->value[k] = chr; + cur->value[++k] = '\0'; + } + break; + } + } + delete buf; + } + else if( !strncmp + ( getenv( "CONTENT_TYPE" ), "multipart/form-data;", 20 ) ) + { + char *boundary, *oname; + int blen, j, k, olen; + + length = atoi( getenv( "CONTENT_LENGTH" ) ); + buf = new char[length + 1]; + fread( buf, 1, length, stdin ); + for( blen = 0; buf[blen + 1] != '\n'; blen++ ); + boundary = new char[blen + 1]; + memcpy( boundary, buf, blen ); + boundary[blen] = '\0'; + j = blen + 2; + for( ;; ) + { + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_STDINPUT; + if( !strncmp + ( buf + j, "Content-Disposition: form-data; name=\"", + 38 ) ) + { + j += 38; + for( k = 0; buf[j + k] != '\"'; k++ ); + oname = cur->name = new char[k + 1]; + memcpy( cur->name, buf + j, k ); + olen = k; + cur->name[k] = '\0'; + j += k + 1; + if( !strncmp( buf + j, "; filename=\"", 12 ) ) /* Must be a file */ + { + /* Acquire file name */ + j += 12; + for( k = 0; buf[j + k] != '\"'; k++ ); + cur->value = new char[k + 1]; + memcpy( cur->value, buf + j, k ); + cur->value[k] = '\0'; + cur->len = k; + j += k + 3; + + /* Acquire content type */ + if( !strncmp( "Content-Type: ", buf + j, 14 ) ) + { + j += 14; + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_STDINPUT; + cur->name = new char[olen + 1]; + memcpy( cur->name, oname, olen + 1 ); + for( k = 0; buf[j + k + 1] != '\n'; k++ ); + cur->value = new char[k + 1]; + memcpy( cur->value, buf + j, k ); + cur->value[k] = '\0'; + cur->len = k; + j += k; + } + else + { + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_STDINPUT; + cur->name = new char[olen + 1]; + memcpy( cur->name, oname, olen + 1 ); + cur->value = new char[1]; + cur->value[0] = '\0'; + cur->len = 0; + } + j += 4; + + /* Acquire content */ + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_STDINPUT; + cur->name = new char[olen + 1]; + memcpy( cur->name, oname, olen + 1 ); + if( !strncmp( buf + j + k, boundary, blen ) ) + { + cur->value = new char[1]; + cur->value[0] = '\0'; + j += blen + 4; + } + else if( !strncmp( buf + j + k + 1, boundary, blen ) ) + { + cur->value = new char[1]; + cur->value[0] = '\0'; + j += blen + 5; + } + else + { + for( k = 0; + strncmp( buf + j + k + 2, boundary, blen ); + k++ ); + cur->value = new char[k + 1]; + memcpy( cur->value, buf + j, k ); + cur->value[k] = '\0'; + cur->len = k; + j += k + blen + 4; + } + } + else + { + j += 4; + for( k = 0; + strncmp( buf + j + k + 2, boundary, blen ); + k++ ); + cur->value = new char[k + 1]; + memcpy( cur->value, buf + j, k ); + cur->value[k] = '\0'; + cur->len = k; + j += k + blen + 4; + } + if( buf[j + 1] == '\n' ) + j += 2; + if( j >= length ) + break; + } + else + { + cur->name = ( char * ) "ERROR"; + cur->value = ( char * ) "Error here"; + } + } + } + delete buf; + } + + if( ( buf = getenv( "HTTP_COOKIE" ) ) ) + { + int lbase = aVars.getSize( ); + length = strlen( buf ); + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_COOKIE; + for( j = 0; j < length; j++ ) + { + switch ( buf[j] ) + { + case '=': + cur->name = new char[slen + 1]; + slen = 0; + break; + + case ';': + cur->value = new char[slen + 1]; + cur->len = slen; + slen = 0; + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_COOKIE; + break; + + default: + switch ( buf[j] ) + { + case '%': /* per-cents mean a hex-code for an ASCII char */ + j += 2; + slen++; + break; + + default: /* Nothing special, move along, folks... */ + slen++; + break; + } + break; + } + } + cur->value = new char[slen + 1]; + cur->len = slen; + slen = 0; + cur = ( Item * ) aVars.getAt( lbase ); + mode = 0; + k = 0; + nCur = lbase; + for( j = 0; j < length; j++ ) + { + switch ( buf[j] ) + { + case '=': + mode = 1; + k = 0; + break; + + case ';': + mode = 0; + k = 0; + nCur++; + cur = ( Item * ) aVars.getAt( nCur ); + break; + + default: + switch ( buf[j] ) + { + case '%': /* per-cents mean a hex-code for an ASCII char */ + hexbuf[0] = buf[++j]; + hexbuf[1] = buf[++j]; + chr = ( char ) ( strtol( hexbuf, NULL, 16 ) ); + break; + + case '+': /* Pluses mean spaces, odd, I know... */ + chr = ' '; + break; + + case ' ': + continue; + break; + + default: /* Nothing special, move along, folks... */ + chr = buf[j]; + break; + } + if( mode == 0 ) + { + cur->name[k] = chr; + cur->name[++k] = '\0'; + } + else + { + cur->value[k] = chr; + cur->value[++k] = '\0'; + } + break; + } + } + } + + if( ( buf = getenv( "QUERY_STRING" ) ) ) + { + if( strlen( buf ) > 0 ) + { + int lbase = aVars.getSize( ); + length = strlen( buf ); + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_CMDLINE; + for( j = 0; j < length; j++ ) + { + switch ( buf[j] ) + { + case '=': + cur->name = new char[slen + 1]; + slen = 0; + break; + + case '&': + cur->value = new char[slen + 1]; + cur->len = slen; + slen = 0; + cur = new Item( ); + aVars.append( cur ); + cur->type = VAR_CMDLINE; + break; + + default: + switch ( buf[j] ) + { + case '%': /* per-cents mean a hex-code for an ASCII char */ + j += 2; + slen++; + break; + + default: /* Nothing special, move along, folks... */ + slen++; + break; + } + break; + } + } + cur->value = new char[slen + 1]; + cur->len = slen; + slen = 0; + cur = ( Item * ) aVars.getAt( lbase ); + nCur = lbase; + mode = 0; + k = 0; + for( j = 0; j < length; j++ ) + { + switch ( buf[j] ) + { + case '=': + mode = 1; + k = 0; + break; + + case '&': + mode = 0; + k = 0; + nCur++; + cur = ( Item * ) aVars.getAt( nCur ); + break; + + default: + switch ( buf[j] ) + { + case '%': /* per-cents mean a hex-code for an ASCII char */ + hexbuf[0] = buf[++j]; + hexbuf[1] = buf[++j]; + chr = ( char ) ( strtol( hexbuf, NULL, 16 ) ); + break; + + case '+': /* Pluses mean spaces, odd, I know... */ + chr = ' '; + break; + + default: /* Nothing special, move along, folks... */ + chr = buf[j]; + break; + } + if( mode == 0 ) + { + cur->name[k] = chr; + cur->name[++k] = '\0'; + } + else + { + cur->value[k] = chr; + cur->value[++k] = '\0'; + } + break; + } + } + } + } +} + +Cgi::~Cgi( ) +{ +} + +char *Cgi::getVarValue( const char *name, int skip, unsigned char type ) +{ + for( int j = 0; j < aVars.getSize( ); j++ ) + { + Item *cur = ( Item * ) aVars.getAt( j ); + if( !strcmp( cur->name, name ) ) + { + if( ( cur->type & type ) ) + { + if( skip <= 0 ) + { + return cur->value; + } + else + { + skip--; + } + } + } + } + return NULL; +} + +int Cgi::getVarLength( const char *name, int skip, unsigned char type ) +{ + for( int j = 0; j < aVars.getSize( ); j++ ) + { + Item *cur = ( Item * ) aVars.getAt( j ); + if( !strcmp( cur->name, name ) ) + { + if( ( cur->type & type ) ) + { + if( skip <= 0 ) + { + return cur->len; + } + else + { + skip--; + } + } + } + } + return -1; +} + +void Cgi::writeDebugInfo() +{ + printf( "
\n" );
+    printf( "0x%02X - stdInput | 0x%02X - cookie | 0x%02X - cmdLine\n\n",
+             VAR_STDINPUT, VAR_COOKIE, VAR_CMDLINE );
+    for( int j = 0; j < aVars.getSize(  ); j++ )
+    {
+        Item *item = ( Item * ) aVars.getAt( j );
+        printf("[%s] = \"%s\" [0x%02X]\n", item->name,
+                 item->value, item->type );
+    }
+    printf( "
\n" ); +} + +void Cgi::writeContentHeader( int type ) +{ + switch( type ) + { + case headerHTML: + printf("Content-type: text/html\n\n"); + break; + } +} + +void Cgi::writeContent( const char *name, ...) +{ + char *templ = (char *)aContent.get(name); + + if( templ ) + { + va_list ap; + + va_start (ap, name); + vprintf (templ, ap); + va_end (ap); + } + else + { + printf("Error finding content labeled \"%s\"\n", name ); + } +} + +void Cgi::loadContent( const char *strSource ) +{ + FILE *fh = NULL; + if( strSource == NULL ) + { + extern char *program_invocation_short_name; + char *tmpName = new char[strlen(program_invocation_short_name)+10]; + memset( tmpName, 0, strlen(program_invocation_short_name)+10 ); + strcpy( tmpName, program_invocation_short_name ); + strcat( tmpName, ".content" ); + fh = fopen( tmpName, "rt" ); + delete tmpName; + } + else + { + fh = fopen( strSource, "rt" ); + } + + if( fh == NULL ) return; + + struct stat xStats; + + fstat( fileno( fh ), &xStats ); + + char *bigBuf = new char[xStats.st_size+1]; + memset( bigBuf, 0, xStats.st_size+1 ); + fread( bigBuf, 1, xStats.st_size, fh ); + fclose( fh ); + + // Now we can actually load stuff from the file, first we need to make us up a format... + int lSize=0; + struct Content + { + char *name; + char *value; + } xCont; + int j = 0; + while( j < xStats.st_size ) + { + // We're looking for a content-block init statement + for( ; j < xStats.st_size; j++ ) + { + if( bigBuf[j] == '#' ) + { + if( bigBuf[j+1] == '{' ) + { + break; + } + } + } + j=j+2; + if( j >= xStats.st_size ) break; + for( ; bigBuf[j] == ' ' || bigBuf[j] == '\t'; j++ ); + for( lSize = 0; lSize+j < xStats.st_size && bigBuf[lSize+j] != '\n' && bigBuf[lSize+j] != '\r'; lSize++ ); + xCont.name = new char[lSize+1]; + memset( xCont.name, 0, lSize+1 ); + memcpy( xCont.name, &bigBuf[j], lSize ); + j += lSize+1; + + for( lSize = 0; lSize+j < xStats.st_size; lSize++ ) + { + if( bigBuf[lSize+j] == '#' ) + { + if( bigBuf[lSize+j+1] == '}' ) + { + break; + } + } + } + xCont.value = new char[lSize+1]; + memset( xCont.value, 0, lSize+1 ); + memcpy( xCont.value, &bigBuf[j], lSize ); + + aContent.insert( xCont.name, xCont.value ); + + j += lSize + 2; + } +} + +void Cgi::writeCookie( char const *name, char const *value, char const *expires, char const *path, char const *domain, bool secure ) +{ + printf("Set-Cookie: %s=%s", name, value ); + + if( expires != NULL ) + { + printf("; expires=%s", expires ); + } + + if( path != NULL ) + { + printf("; path=%s", path ); + } + + if( domain != NULL ) + { + printf("; domain=%s", domain ); + } + + if( secure ) + { + printf("; secure"); + } + + printf("\n"); +} -- cgit v1.2.3