/* * This program reads a form submission and uses it to populate a * database. The program performs a set_symbol call to set symbol * ICSMA_REFERENCE to the name of the file created. */ #include #include #include #include #include #include #include #include "scriptlib.h" #include "cgilib.h" static $DESCRIPTOR(ref_symbol_dx, "ICSMA_REFERENCE"); static char ref_string[256]; static $DESCRIPTOR(ref_string_dx, ref_string ); int LIB$SET_SYMBOL(), LIB$GETJPI(); /****************************************************************************/ /* Save key list into specially formatted data base: * +key1=value2 * +key2=line1 * -line2 * -line3 * +key3=value3 * * each line begins with either a '+' to start a new key/value pair or * a - to continue a previous. * * Return value is 1 for success, 0 for failure. */ static int dump_key_list ( char *fname, int count, char **key, char **value ) { FILE *out; int status, i, j, pos, is_ok, length; char c, line[1024]; /* * Open output file. */ out = fopen ( fname, "w" ); if ( !out ) return 0; /* * Write entry for each value. */ for ( i = 0, is_ok=1; is_ok && (i < count); i++ ) { /* * Build output lines. Start with '+keyword=', upcasing the * keyword and truncating it at 63 characters. */ pos = 1; line[0] = '+'; for (j=0; (c=key[i][j]) && (j < 64); j++) line[pos++] = toupper(c); line[pos++] = '='; /* * Append the value the output line, reseting to multiple lines * if carriage control seen. */ for ( j = 0; (c = value[i][j]); j++ ) { if ( c == '\r' ) { /* Skip over CR preceding LF */ if ( value[i][j+1] == '\n' ) { j++; c = '\n'; } } line[pos++] = c; if ( (1+pos) >= sizeof(line) ) { status = fwrite ( line, sizeof(char), pos, out ); if ( status < pos ) { is_ok = 0; break; } fwrite ( "\n", sizeof(char), 1, out ); pos = 1; line[0] = '='; } else if ( c == '\n' ) { /* write line */ status = fwrite ( line, sizeof(char), pos, out ); if ( status < pos ) { is_ok = 0; break; } pos = 1; line[0] = '-'; } } /* * Flush final line. */ if ( pos > 1 ) { line[pos++] = '\n'; status = fwrite ( line, 1, pos, out ); if ( status < pos ) is_ok = 0; } } status = fclose ( out ); return 1; } /****************************************************************************/ /* Read form content and parse. Return value is number of keywords parsed, * -1 for error. Key_limit is size of key and value arrays. */ static int parse_form ( int key_limit, char **key, char **value ) { int i, j, content_length, length, count, start, finish, flen; char *var, *fdata; /* * Read form content into memory in preparation for parsing. */ count = 0; var = cgi_info ( "CONTENT_LENGTH" ); content_length = var ? atoi(var) : 0; if ( content_length > 0 ) { /* * Allocate buffer and read entire form data into it, forcing final &. */ fdata = malloc ( content_length+1 ); if ( !fdata ) return -1; length = cgi_read ( fdata, content_length ); } else { /* See if form method was GET by mistake. */ var = cgi_info ( "QUERY_STRING" ); if ( var ) { length = strlen ( var ); fdata = malloc ( length + 1 ); if ( !fdata ) return -1; strcpy ( fdata, var ); } else length = 0; } if ( length <= 0 ) return length; /* fdata[length] = '\0'; printf("Raw form data: %s\n", fdata ); */ /* * Parse into keyword/value pairs, ampersands delimit the pairs. */ if ( fdata[length-1] != '&' ) fdata[length++] = '&'; start = finish = 0; for ( i = 0; i < length; i++ ) if ( !fdata[i] || (fdata[i] == '&') ) { /* * Value parsed. Unescape string and look for first equals to * to delimit field name from value. */ flen = i - start; for ( j = start; j < i; j++ ) if ( fdata[j] == '+' ) fdata[j] = ' '; net_unescape_string ( &fdata[start], &flen ); finish = start + flen; fdata[finish] = '\0'; for ( j = start; j < finish; j++ ) if ( fdata[j] == '=' ) { /* Save pointers to pair in callers buffer, terminate strings */ key[count] = &fdata[start]; fdata[j] = '\0'; value[count] = &fdata[j+1]; count++; if ( count >= key_limit ) return count; break; } else { /* Make characters in field name upper case */ /* fdata[j] = _toupper(fdata[j]); */ } start = i + 1; } return count; } /**************************************************************************/ int main ( int argc, char **argv ) { int field_count, status, i, code; char *db_root; char *key[50], *value[50]; char fname[512]; time_t now; long pid, tmp; /* * Initialize CGI environment, path_translated is database location. */ status = cgi_init ( argc, argv ); if ( (status&1) == 0 ) exit ( status ); db_root = cgi_info ( "PATH_TRANSLATED" ); if ( !db_root ) { cgi_printf ( "content-type: text/plain\n" ); cgi_printf ( "status: 500 bad info\n\nMissing or invalid path info\n"); cgi_printf ( "Must supply template file name\n"); exit ( 1 ); } if ( !*db_root ) { cgi_printf ( "content-type: text/plain\n" ); cgi_printf ( "status: 500 bad info\n\nNull or invalid path info\n"); cgi_printf ( "Must supply template file name\n"); exit ( 1 ); } /* * Get posted data. */ field_count = parse_form ( 50, key, value ); cgi_printf ( "content-type: text/html\n" ); /* for ( i = 0; i < field_count; i++ ) { cgi_printf ( "%s = '%s'\n", key[i], value[i] ); } */ /* * Generate reference number from data and 'random' data. */ now = time(&now); code = JPI$_PID; status = LIB$GETJPI ( &code, 0, 0, &pid, 0, 0 ); if ( (status&1) == 0 ) pid = 0; now = (time_t) (((int) now) ^ 0x0F1238423); sprintf(ref_string,"%u-%u", pid, now ); sprintf(fname,"ICSMA_DATA:%s.ABSTRACT", ref_string ); ref_string_dx.dsc$w_length = strlen(ref_string); code = 1; /* local table */ status = LIB$SET_SYMBOL ( &ref_symbol_dx, &ref_string_dx, &code ); /* * Save submitted data. */ if ( (status&1) ) status = dump_key_list ( fname, field_count, key, value ); if ( status&1 ) { cgi_printf("\nAbstract Submission success"); cgi_printf("\n"); cgi_printf("You submission was entered into system for processing,"); cgi_printf("the reference number is %s.\n", ref_string ); cgi_printf("\n"); } else { cgi_printf("status: 500 Internal failure\n"); cgi_printf("\nAbstract Submission failure"); cgi_printf("\n"); cgi_printf("An error occurred during the processing of your submission\n"); cgi_printf("\n"); } return 1; }