#include #include #include #include #include #include #include "common.h" $include sqltypes.h; $include sqlda.h; #define FALSE 0 #define NEW_FORM TRUE #define NOT_NEW_FORM FALSE #define INFORMIXDIR "INFORMIXDIR=/opt/informix" #define INFORMIXSERVER "INFORMIXSERVER=cm" $define LED "led"; FILE *log; int wchRecord = 0; $int rcdCount; static char m_script_name [256]; static t_cgi_entry genericEntry; static char genStr [20]; static char nameSav [20]; extern int errno; /************************************************************************/ /* */ /* FUNCTION: informixEnv AUTHOR: Matthew Eichler@Informix */ /* DESCRIPTION: Sets the Informix environment */ /* DATE CREATED: 06/07/1995 LAST UPDATED: 08/27/1996 */ /* */ /************************************************************************/ int informixEnv (void) { if ((putenv (INFORMIXDIR)) || (putenv (INFORMIXSERVER))) return (TRUE); return (FALSE); } /************************************************************************/ /* */ /* FUNCTION: htmlErrorMsg AUTHOR: Matthew Eichler@Informix */ /* DESCRIPTION: Prints message if fatal error occurred */ /* DATE CREATED: 06/07/1995 LAST UPDATED: 08/27/1996 */ /* */ /************************************************************************/ void htmlErrorMsg (void) { char str_buf [2048]; char sql_msg [2560]; int msg_len = 0; fclose (log); cgi_print_text (""); cgi_print_text (cgi_env.script_name); cgi_print_text (" Error\n"); cgi_print_text ("

"); cgi_print_text (cgi_env.script_name); cgi_print_text (": Error, contact Webmaster.

\n"); /* See if there's an SQL code and/or message to print */ if (sqlca.sqlcode != 0) { sprintf (str_buf, "SQL ERROR = %d \n", sqlca.sqlcode); cgi_print_text (str_buf); if (rgetlmsg (sqlca.sqlcode, str_buf, 2048, &msg_len) == 0) { cgi_print_text ("
"); sprintf (sql_msg, str_buf, sqlca.sqlerrm); cgi_print_text (sql_msg); cgi_print_text ("
"); } } /* See if there's an ISAM error code and message to print */ if (sqlca.sqlerrd [1] != 0) { sprintf (str_buf, "ISAM ERROR = %d \n", sqlca.sqlerrd [1]); cgi_print_text (str_buf); if (rgetlmsg (sqlca.sqlerrd [1], sql_msg, 2048, &msg_len) == 0) { cgi_print_text ("
"); cgi_print_text (sql_msg); cgi_print_text ("
"); } } /* Rollback any transactions that were in progress */ $ WHENEVER SQLERROR CONTINUE; $ WHENEVER SQLWARNING CONTINUE; $ ROLLBACK WORK; /* Exit program */ exit (0); } /************************************************************************/ /* */ /* FUNCTION: main AUTHOR: Tim Sabin/Matthew Eichler */ /* DESCRIPTION: main controls what this CGI program does. If the user */ /* has requested this form for the first time, an empty form will be */ /* displayed. Otherwise, either an appropriate SELECT or INSERT */ /* statement will be generated, and the results will be displayed. */ /* DATE CREATED: 06/07/1995 LAST UPDATED: 10/14/1996 */ /* */ /************************************************************************/ main (int argc, char **argv) { FILE *uid; char *user, line [81], *linePtr, *name, *token, *ptr; int uidNo; /* Change the user ID according to the user name */ sprintf (line, "/netscape_docs/cgi-bin/%c-log.log", argv [0][0]); log = fopen (line, "a"); /* Find out our user ID */ uid = fopen ("/etc/passwd", "r"); for (linePtr = fgets (line, 80, uid); linePtr; linePtr = fgets (line, 80, uid)) { name = strtok (line, ":"); token = strtok (NULL, ":"); token = strtok (NULL, ":"); if (atoi (token) == getuid ()) break; } fclose (uid); strcpy (nameSav, name); /* IF this is the 1st time through (the userID is netscape) THEN */ if (!strcmp (name, "netscape")) { /* Make sure that anyone can write to the log */ fchmod (fileno (log), 0666); /* Find out the UNIX user name */ uid = fopen ("/netscape_docs/etc/passwd", "r"); for (linePtr = fgets (line, 80, uid); linePtr; linePtr = fgets (line, 80, uid)) { name = strtok (line, ":"); if (!strcmp (name, getenv ("REMOTE_USER"))) break; } fclose (uid); token = strtok (NULL, ":"); token [strlen (token) -1] = '\0';/* Get rid trailing newline */ /* Clean up */ /* Change user ID through an intermediate process */ execl ("/netscape_docs/./etc/./para", "/netscape_docs/./etc/./para", "-d", ".", "-lrm", token, "rte", "-f", argv [0], NULL); /* ENDIF */ } /* Always send the content type first so CGI will know what you're sending*/ cgi_mimetype ("text/html"); /* Get things started */ if (cgi_start () != 0) htmlErrorMsg (); sprintf (m_script_name, "\"%s\"", cgi_env.script_name); if (informixEnv ()) htmlErrorMsg (); $ WHENEVER SQLERROR CALL htmlErrorMsg; $ DATABASE LED; /* How were we called? "GET" & No Query means 1st fetch. Else, should be */ /* "POST". Anything else is an error. */ if ((strncasecmp (cgi_env.request_method, "GET", 3) == 0) && (cgi_env.query_string [0] == NULL)) { createForm (NEW_FORM); } else if (strncasecmp (cgi_env.request_method, "POST", 4) == 0) { evaluateForm (); } else htmlErrorMsg (); $ CLOSE DATABASE; cgi_free (); fclose (log); return; } /************************************************************************/ /* */ /* FUNCTION: boldPrint AUTHOR: Tim Sabin */ /* DESCRIPTION: Print the passed message in bold print. */ /* DATE CREATED:09/03/1996 LAST UPDATED: 09/03/1996 */ /* */ /************************************************************************/ void boldPrint (char *msg) { cgi_print_text (""); cgi_print_text (msg); cgi_print_text (""); } /************************************************************************/ /* */ /* FUNCTION: htmlTitle AUTHOR: Tim Sabin */ /* DESCRIPTION: Issue the HTML for the browser and page titles. */ /* DATE CREATED: 08/28/1996 LAST UPDATED: 09/20/1996 */ /* */ /************************************************************************/ void htmlTitle (char *brTitle, char *backFile, char *iconFile, char *pgTitle1, char *pgTitle2) { cgi_print_text ("\n"); cgi_print_text (brTitle); cgi_print_text ("\n\n\n
\n"); if (iconFile) { cgi_print_text ("\n   \n"); cgi_print_text (""); cgi_print_text (pgTitle1); if (pgTitle2) { cgi_print_text ("
\n"); cgi_print_text (pgTitle2); } cgi_print_text ("
"); paragraph (); } /************************************************************************/ /* */ /* FUNCTION: sectionTitle AUTHOR: Tim Sabin */ /* DESCRIPTION: Issue the HTML for the section title. */ /* DATE CREATED: 08/28/1996 LAST UPDATED: 08/28/1996 */ /* */ /************************************************************************/ void sectionTitle (char *title) { cgi_print_text ("

"); cgi_print_text (title); cgi_print_text ("

"); paragraph (); } /************************************************************************/ /* */ /* FUNCTION: formBegin AUTHOR: Tim Sabin */ /* DESCRIPTION: Issue HTML to start a web form. */ /* DATE CREATED: 08/28/1996 LAST UPDATED: 09/20/1996 */ /* */ /************************************************************************/ void formBegin (void) { cgi_print_text ("
\n"); } /************************************************************************/ /* */ /* FUNCTIONS: fill* AUTHOR: Tim Sabin */ /* DESCRIPTION: The fill* group of functions create and fill HTML GUI */ /* elements. A parameter is passed if this is a new form (in which */ /* case, don't fill) and a pointer to Informix elements to fill. */ /* DATE CREATED: 08/28/1996 LAST UPDATED: 11/04/1996 */ /* */ /************************************************************************/ void fillHidden (char *name, char *textFill) { char str [15]; cgi_print_text ("\n"); } void fillText (int newForm, char *name, int size, int maxSize, char *textFill) { char str [15]; cgi_print_text ("\n"); } void fillPassword (char *name, int size, int maxSize) { char str [15]; cgi_print_text ("\n"); } void fillTextArea (int newForm, char *name, int rows, int cols, char *textFill){ char str [15]; cgi_print_text ("\n"); } void fillSelectBegin (char *name, int size) { char str [15]; cgi_print_text (""); cgi_print_text (title); cgi_print_text ("\n"); } void fillRadiobutton (char *boxName, char *buttonLabel, int def) { cgi_print_text (""); cgi_print_text (buttonLabel); cgi_print_text ("\n"); } void fillReset (char *name) { cgi_print_text ("\n"); } void fillButton (char *name) { cgi_print_text ("\n"); } void fillHelp (char *name) { cgi_print_text ("

Help!!

"); } /************************************************************************/ /* */ /* FUNCTION: traverseButtons AUTHOR: Tim Sabin */ /* DESCRIPTION: Create buttons used for traversing record lists. */ /* DATE CREATED: 09/05/1996 LAST UPDATED: 10/25/1996 */ /* */ /************************************************************************/ void traverseButtons (void) { fillButton ("NextRecord"); fillButton ("PreviousRecord"); fillButton ("FirstRecord"); fillButton ("LastRecord"); cgi_print_text ("
\n"); fillButton ("RecordNumber"); fillText (NEW_FORM, "recdNum", 5, 5, NULL); } /************************************************************************/ /* */ /* FUNCTIONS: remainCount AUTHOR: Tim Sabin */ /* DESCRIPTION: Display which record in the current list is being */ /* displayed. */ /* DATE CREATED: 09/03/1996 LAST UPDATED: 09/30/1996 */ /* */ /************************************************************************/ void remainCount (char *table, int newForm) { char numberWch [10], numberOf [10]; char widgetWch [100], widgetOf [100]; t_cgi_entry *button; sprintf (numberWch, "%d", wchRecord); sprintf (widgetWch, "%s_wchRecord", table); sprintf (numberOf, "%d", rcdCount); sprintf (widgetOf, "%s_rcdCount", table); /* IF Query was pressed, but nothing found THEN */ if ((button = cgi_get_form_entry ("Query")) && !rcdCount) { /* Print "No records found." */ cgi_print_text ("

No records found.

\n"); /* ELSE IF a Traversal button was pressed AND the list is empty THEN */ } else if (traverseOn () && !rcdCount) { /* Print "Cannot traverse empty record list." */ cgi_print_text ("

Cannot traverse empty record list.

\n"); /* ELSE IF ClearForm was pressed OR this is a new form THEN */ } else if (newForm == NEW_FORM) { /* Print "No list of records. Please query." */ cgi_print_text ("

No list of records. Please query.

\n"); /* ELSE */ } else { /* Print "This is record xx of xx in the current list." */ cgi_print_text ("

This is record "); cgi_print_text (numberWch); cgi_print_text (" of "); cgi_print_text (numberOf); cgi_print_text (" in the current list.

\n"); /* ENDIF */ } /* Send the hidden fields in HTML */ fillHidden (widgetWch, numberWch); fillHidden (widgetOf, numberOf); } /************************************************************************/ /* */ /* FUNCTION: getCount AUTHOR: Tim Sabin */ /* DESCRIPTION: getCount fetches the record information (which one, how */ /* many) from the submitted form, and stores. */ /* DATE CREATED: 10/30/1996 LAST UPDATED: 10/30/1996 */ /* */ /************************************************************************/ void getCount (char *table) { t_cgi_entry *entry; char widget [40]; /* Fetch the saved list information first */ sprintf (widget, "%s_wchRecord", table); entry = cgi_get_form_entry (widget); sscanf (entry->value, "%d", &wchRecord); sprintf (widget, "%s_rcdCount", table); entry = cgi_get_form_entry (widget); sscanf (entry->value, "%d", &rcdCount); } /************************************************************************/ /* */ /* FUNCTION: traverseOn AUTHOR: Tim Sabin */ /* DESCRIPTION: Detects if one of the traverse buttons waspressed, and */ /* sends back which one. */ /* DATE CREATED: 09/05/1996 LAST UPDATED: 10/25/1996 */ /* */ /************************************************************************/ int traverseOn (void) { t_cgi_entry *button; if (button = cgi_get_form_entry ("NextRecord")) return (NEXT_RECORD); if (button = cgi_get_form_entry ("PreviousRecord")) return (PREV_RECORD); if (button = cgi_get_form_entry ("FirstRecord")) return (FIRST_RECORD); if (button = cgi_get_form_entry ("LastRecord")) return (LAST_RECORD); if (button = cgi_get_form_entry ("RecordNumber")) return (NUM_RECORD); return (0); /* No traverse button was pressed */ } /************************************************************************/ /* */ /* FUNCTION: traverseList AUTHOR: Tim Sabin */ /* DESCRIPTION: Traverse the current list of primary records according */ /* to which button was pressed. */ /* DATE CREATED: 09/13/1996 LAST UPDATED: 10/30/1996 */ /* */ /************************************************************************/ int traverseList (int buttonNum, char *table, ...){ va_list ap; t_cgi_entry *entry; int rec; /* Fetch the saved list information first */ getCount (table); /* IF the record list is empty THEN return for a new form */ if (!rcdCount) return (NEW_FORM); /* Position yourself depending upon the pressed traversal button */ switch (buttonNum) { case NEXT_RECORD: if (wchRecord != rcdCount) wchRecord++; break; case PREV_RECORD: if (wchRecord != 1) wchRecord--; break; case FIRST_RECORD: wchRecord = 1; break; case LAST_RECORD: wchRecord = rcdCount; break; case NUM_RECORD: entry = cgi_get_form_entry ("recdNum"); rec = atol (entry->value); if ((rec < 1) || (rec > rcdCount)) break; /* Bad count means nothing done */ wchRecord = rec; break; default: break; /* A bad button ID was passed */ } va_start (ap, table); fetch (table, wchRecord, LIST, ap); return (NOT_NEW_FORM); } /************************************************************************/ /* */ /* FUNCTION: initSqlTable AUTHOR: Tim Sabin */ /* DESCRIPTION: Initialize an Informix table or view for this form. */ /* DATE CREATED: 09/06/1996 LAST UPDATED: 10/14/1996 */ /* */ /************************************************************************/ void initSqlTable (char *table) { $char dropStmt [50]; /* Drop any already-existing temp view for this table */ sprintf (dropStmt, "DROP VIEW %s", hashName (table, nameSav)); $ WHENEVER SQLERROR CONTINUE; /* If view doesn't exist, so what? */ $ PREPARE dropView FROM $dropStmt; $ EXECUTE dropView; $ WHENEVER SQLERROR CALL htmlErrorMsg; /* Reset error handling for rest of program */ } /************************************************************************/ /* */ /* FUNCTION: sqlStatement AUTHOR: Tim Sabin */ /* DESCRIPTION: Put together the "guts" of an SQL statement. */ /* DATE CREATED: 09/06/1996 LAST UPDATED: 11/19/1996 */ /* */ /************************************************************************/ static void sqlStatement (char *sqlStat, char *table, char *linkTable, va_list ap) { char *fieldName, *fieldVal; int fieldType; t_cgi_entry *fieldEntry; char *loVal, *hiVal; /* DO FOR the number of passed arguments */ for (fieldName = va_arg (ap, char *); fieldName; fieldName = va_arg (ap, char *)) { /* Fetch the other arguments (type, value) */ fieldType = va_arg (ap, int); /* IF this is a LINK THEN */ if (fieldType == LINK) { fieldVal = va_arg (ap, char *); /* Add in a simple LINK WHEN clause addition */ strcat (sqlStat, " AND "); if (linkTable) { strcat (sqlStat, table); strcat (sqlStat, "."); } strcat (sqlStat, fieldName); strcat (sqlStat, " "); /* Finish off the link */ strcat (sqlStat, fieldVal); /* ELSE (this is a field) */ } else { fieldEntry = va_arg (ap, t_cgi_entry *); unWordWrap (fieldEntry->value); /* IF the user entered something THEN */ if (fieldEntry->value && fieldEntry->value [0]) { /* IF there was a wildcard THEN */ if (strchr (fieldEntry->value, '*')) { /* Insert a 'MATCHES' clause */ strcat (sqlStat, " AND "); strcat (sqlStat, fieldName); strcat (sqlStat, " MATCHES "); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); strcat (sqlStat, fieldEntry->value); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); /* ELSE IF there was a ':' THEN */ } else if (strchr (fieldEntry->value, ':')) { /* Parse the two values */ loVal = strtok (fieldEntry->value, ":"); hiVal = strtok (NULL, ":"); /* Insert a 'BETWEEN' clause */ strcat (sqlStat, " AND "); strcat (sqlStat, fieldName); strcat (sqlStat, " BETWEEN "); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); strcat (sqlStat, loVal); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); strcat (sqlStat, " AND "); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); strcat (sqlStat, hiVal); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); /* ELSE */ } else { /* Insert an ordinary '=' clause */ strcat (sqlStat, " AND "); strcat (sqlStat, fieldName); strcat (sqlStat, " = "); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); strcat (sqlStat, fieldEntry->value); if (fieldType == SQLCHAR) strcat (sqlStat, "\""); /* ENDIF */ } /* ENDIF */ } /* ENDIF */ } /* ENDFOR*/ } } /************************************************************************/ /* */ /* FUNCTION: queryTable AUTHOR: Tim Sabin */ /* DESCRIPTION: Query an Informix table, putting results in a temp view.*/ /* DATE CREATED: 09/06/1996 LAST UPDATED: 11/19/1996 */ /* */ /************************************************************************/ void queryTable (char *table, char *linkTable, char *fields, ...) { va_list ap; $char sqlStat [2000]; va_start (ap, fields); /* Start the "CREATE VIEW" SQL statement */ sprintf (sqlStat, "CREATE VIEW %s AS SELECT %s FROM %s%s%s " "WHERE 1 = 1", hashName (table, nameSav), fields ? fields : "*", table, linkTable ? "," : "", linkTable ? linkTable : ""); /* Finish the SQL query */ sqlStatement (sqlStat, table, linkTable, ap); fprintf (log, "queryTable: generated SQL: %s\n", sqlStat); /* Prepare and execute the SQL query */ $ EXECUTE IMMEDIATE $sqlStat; } /************************************************************************/ /* */ /* FUNCTION: fetch AUTHOR: Tim Sabin */ /* DESCRIPTION: fetch gets the specified record from the current list. */ /* DATE CREATED: 09/09/1996 LAST UPDATED: 09/19/1996 */ /* */ /************************************************************************/ int fetch (char *table, int whichRecord, ...) { va_list ap; int i, flag, code; $int whichRecordDup; char *fieldPtr [20]; char *fieldName [20]; char *order; $char sqlStmt [2000]; $char viewName [30]; struct sqlda *udesc; struct sqlvar_struct *col; /* Check for an argument list */ va_start (ap, whichRecord); flag = va_arg (ap, int); if (flag == LIST) ap = va_arg (ap, va_list); else va_start (ap, whichRecord); /* Point to the temporary view for our records */ sprintf (viewName, "%s", hashName (table, nameSav)); /* Select the requested fields from the view */ strcpy (sqlStmt, "SELECT "); for (i = 0, fieldPtr [i] = va_arg (ap, char *); fieldPtr [i]; i++, fieldPtr [i] = va_arg (ap, char *)) { /* Separate field names in SQL statement */ if (i) strcat (sqlStmt, ", "); fieldName [i] = va_arg (ap, char *); strcat (sqlStmt, fieldName [i]); } /* o NULL-terminate fieldName */ fieldName [i] = NULL; /* Add the view we're fetching from */ strcat (sqlStmt, " FROM "); strcat (sqlStmt, viewName); /* Order the results, if requested */ order = va_arg (ap, char *); if (order) { strcat (sqlStmt, " ORDER BY "); strcat (sqlStmt, order); } fprintf (log, "fetch: fetch SQL statement:\n %s\n", sqlStmt); fflush (log); $ PREPARE sel_stmt FROM $sqlStmt; $ DESCRIBE sel_stmt INTO udesc; /*if (i == 10) { fprintf (log, "fetch: aspec_test: qual of test_datetime: %x\n", ((dtime_t *)udesc->sqlvar [5].sqldata)->dt_qual); fflush (log); }*/ $ DECLARE find_cursor SCROLL CURSOR WITH HOLD FOR sel_stmt; $ OPEN find_cursor; /* IF this cursor is creating a list THEN */ if (rcdCount == 0) { /* Set the record count variables */ sprintf (sqlStmt, "SELECT count(*) FROM %s", viewName); $ PREPARE cnt_stmt FROM $sqlStmt; $ DECLARE cnt_cursor CURSOR WITH HOLD FOR cnt_stmt; $ OPEN cnt_cursor; $ FETCH cnt_cursor INTO $rcdCount; $ CLOSE cnt_cursor; wchRecord = 1; /* ENDIF */ } /* Fetch the specified record, placing needed fields in the passed */ /* host variables */ for (col = udesc->sqlvar, i = 0; fieldName [i]; col++, i++) { col->sqldata = (char *)fieldPtr [i]; switch (col->sqltype) { case SQLSMFLOAT: col->sqltype = CFLOATTYPE; break; case SQLFLOAT: col->sqltype = CDOUBLETYPE; break; case SQLCHAR: col->sqltype = CCHARTYPE; break; case SQLSMINT: col->sqltype = CSHORTTYPE; break; case SQLINT: case SQLSERIAL: case SQLDATE: col->sqltype = CINTTYPE; break; case SQLDTIME: col->sqltype = CDTIMETYPE; /*fprintf (log, "fetch: datetime type for %s, original len=%d\n", col->sqlname, col->sqllen); fflush (log);*/ break; } col->sqllen = rtypmsize (col->sqltype, col->sqllen); col->sqlind = NULL; } whichRecordDup = whichRecord; $ FETCH ABSOLUTE $whichRecordDup find_cursor USING DESCRIPTOR udesc; code = sqlca.sqlcode; fprintf (log, "fetch: %d of %d: $FETCH error code=%d\n", whichRecord, rcdCount, code); fflush (log); $ CLOSE find_cursor; /* Return if the record was found */ return ((code == SQLNOTFOUND) ? FALSE : TRUE); } /************************************************************************/ /* */ /* FUNCTION: query* AUTHOR: Tim Sabin */ /* DESCRIPTION: Parameters from the Web are all in character format. */ /* This routine translates a non-character parameter into char format.*/ /* DATE CREATED: 09/12/1996 LAST UPDATED: 09/12/1996 */ /* */ /************************************************************************/ t_cgi_entry *queryFloat (float flNum) { sprintf (genStr, "%f", flNum); genericEntry.value = genStr; return (&genericEntry); } t_cgi_entry *queryDouble (double dblNum) { sprintf (genStr, "%lf", dblNum); genericEntry.value = genStr; return (&genericEntry); } t_cgi_entry *queryShort (short shNum) { sprintf (genStr, "%hd", shNum); genericEntry.value = genStr; return (&genericEntry); } t_cgi_entry *queryInt (int intNum) { sprintf (genStr, "%d", intNum); genericEntry.value = genStr; return (&genericEntry); } /************************************************************************/ /* */ /* FUNCTION: clearList AUTHOR: Tim Sabin */ /* DESCRIPTION: Reset the database list to empty, reset the counters. */ /* DATE CREATED: 09/13/1996 LAST UPDATED: 09/13/1996 */ /* */ /************************************************************************/ void clearList (void) { rcdCount = wchRecord = 0; } /************************************************************************/ /* */ /* FUNCTION: wordWrap AUTHOR: Tim Sabin */ /* DESCRIPTION: Break a string into displayable "lines", according to */ /* max line length passed. */ /* DATE CREATED: 09/16/1996 LAST UPDATED: 09/16/1996 */ /* */ /************************************************************************/ void wordWrap (char *str, int maxLength) { int i; /* DO UNTIL all of the passed string has been processd */ for (;;) { /* Search for the maximum length. Exit the loop early on string end. */ for (i = 0; i < maxLength; i++) { if (!str [i]) return; } /* Backtrck to the space preceding the last word segment */ for (; (str [i] != ' ') && (str [i] != '\t'); i--) ; /* Replace the space with a newline character */ str [i] = '\n'; /* Point to the next character (word begin) */ str = &str [i+1]; /* END DO */ } } /************************************************************************/ /* */ /* FUNCTION: unWordWrap AUTHOR: Tim Sabin */ /* DESCRIPTION: Merge the logical lines of a field into one long string.*/ /* DATE CREATED: 09/16/1996 LAST UPDATED: 11/15/1996 */ /* */ /************************************************************************/ void unWordWrap (char *str) { /* DO FOR the entire length of the string */ for (; *str; str++) { /* Compress when a return is seen */ if (*str == '\r') { strcpy (str, &str [1]); str--;/* In case 2 returns in a row */ } /* Replace newlines with spaces */ if (*str == '\n') *str = ' '; /* END DO */ } } /************************************************************************/ /* */ /* FUNCTION: link AUTHOR: Tim Sabin */ /* DESCRIPTION: Create a hyperlink via HTML. */ /* DATE CREATED: 10/07/1996 LAST UPDATED: 10/07/1996 */ /* */ /************************************************************************/ void link (char *before, char *hyper, char *where, char *after) { cgi_print_text (before); cgi_print_text (""); cgi_print_text (where); cgi_print_text (""); cgi_print_text (after); } /************************************************************************/ /* */ /* FUNCTION: hashName AUTHOR: Tim Sabin */ /* DESCRIPTION: Create a 9-character view name. Dependent on table and */ /* user name. */ /* DATE CREATED: 10/24/1996 LAST UPDATED: 10/24/1996 */ /* */ /************************************************************************/ char *hashName (char *table, char *user) { unsigned int hashInt, useChar, tempChar; short int shiftAmt, i, j; static char viewName [20]; /* Initialize the hash integer */ hashInt = 0; /* DO FOR the length of the table name */ for (i = 0; table [i]; i++) { useChar = table [i]; /* Shift the character into the proper position */ shiftAmt = (i << 2) % 32; tempChar = 0; if (shiftAmt == 28) tempChar = table [i] >> 4; useChar = (table [i] << shiftAmt) + tempChar; /* XOR the character into the hash integer */ hashInt = hashInt ^ useChar; /* ENDDO */ } /* DO FOR the length of the user ID */ for (j = 0; user [j]; i++, j++) { useChar = user [j]; /* Shift the character into the proper position */ shiftAmt = (i << 2) % 32; tempChar = 0; if (shiftAmt == 28) tempChar = user [j] >> 4; useChar = (user [j] << shiftAmt) + tempChar; /* XOR the character into the hash integer */ hashInt = hashInt ^ useChar; /* ENDDO */ } /* Turn the hash integer into a view name that can be used by Informix */ sprintf (viewName, "tv%x", hashInt); /* Return the generated view name */ return (viewName); } /************************************************************************/ /* */ /* FUNCTION: spaceFill AUTHOR: Tim Sabin */ /* DESCRIPTION: spaceFill appends spaces to the end of a C string. This */ /* makes the string totally compatible with a CHAR field. */ /* DATE CREATED: 11/04/1996 LAST UPDATED: 11/04/1996 */ /* */ /************************************************************************/ void spaceFill (char *string, int howLong) { int i; for (i = 0; (string [i] != '\0') && (i < howLong); i++) ; for (; i < howLong; i++) string [i] = ' '; string [howLong] = '\0'; } /************************************************************************/ /* */ /* FUNCTION: add AUTHOR: Tim Sabin */ /* DESCRIPTION: add adds a record to the specified table. */ /* DATE CREATED: 11/15/1996 LAST UPDATED: 11/15/1996 */ /* */ /************************************************************************/ int add (char *table, ...) { va_list ap; int i, sqlLen, code; t_cgi_entry *fieldPtr; char *fieldName; int fieldType; $char *sqlStmt; /* Find out how large an sql buffer is needed. This requires stepping */ /* through the strings passed. */ va_start (ap, table); for (sqlLen = i = 0, fieldPtr = va_arg (ap, t_cgi_entry *); fieldPtr; i++, fieldPtr = va_arg (ap, t_cgi_entry *)) { sqlLen += strlen (fieldPtr->value); fieldType = va_arg (ap, int); fieldName = va_arg (ap, char *); sqlLen += strlen (fieldName); } sqlStmt = (char *)malloc (sqlLen + 1 + (4 * i) + strlen (table) + 25); /* 25 is len of "INSERT INTO () VALUES ()" */ /* Start creation of an "insert" string */ sprintf (sqlStmt, "INSERT INTO %s (", table); va_start (ap, table); /* Insert the string names */ for (i = 0, fieldPtr = va_arg (ap, t_cgi_entry *); fieldPtr; i++, fieldPtr = va_arg (ap, t_cgi_entry *)) { fieldType = va_arg (ap, int); fieldName = va_arg (ap, char *); if (strlen (fieldPtr->value)) { if (i) strcat (sqlStmt, ", "); strcat (sqlStmt, fieldName); } else i--; } strcat (sqlStmt, ") VALUES ("); va_start (ap, table); /* Insert the string values */ for (i = 0, fieldPtr = va_arg (ap, t_cgi_entry *); fieldPtr; i++, fieldPtr = va_arg (ap, t_cgi_entry *)) { fieldType = va_arg (ap, int); fieldName = va_arg (ap, char *); if (strlen (fieldPtr->value)) { if (i) strcat (sqlStmt, ", "); if ((fieldType == CCHARTYPE) || (fieldType == CVCHARTYPE) || (fieldType == CDATETYPE) || (fieldType == CSTRINGTYPE) || (fieldType == CDTIMETYPE) || (fieldType == CINVTYPE)) strcat (sqlStmt, "\""); strcat (sqlStmt, fieldPtr->value); if ((fieldType == CCHARTYPE) || (fieldType == CVCHARTYPE) || (fieldType == CDATETYPE) || (fieldType == CSTRINGTYPE) || (fieldType == CDTIMETYPE) || (fieldType == CINVTYPE)) strcat (sqlStmt, "\""); } else i--; } strcat (sqlStmt, ")"); $ WHENEVER SQLERROR CONTINUE; $ EXECUTE IMMEDIATE $sqlStmt; code = sqlca.sqlcode; fprintf (log, "add: back from Informix, code = %d\n", code); fflush (log); $ WHENEVER SQLERROR CALL htmlErrorMsg; /* Return if the record was added successfully */ free (sqlStmt); return ((code < 0) ? FALSE : TRUE); } /************************************************************************/ /* */ /* FUNCTION: removeRec AUTHOR: Tim Sabin */ /* DESCRIPTION: removes one or more records from the specified table. */ /* DATE CREATED: 11/16/1996 LAST UPDATED: 11/16/1996 */ /* */ /************************************************************************/ int removeRec (char *table, ...) { va_list ap; int i, sqlLen, code; t_cgi_entry *fieldPtr; char *fieldName; int fieldType; $char sqlStmt [2000]; /* Start the SQL statement to remove one or more records */ sprintf (sqlStmt, "DELETE FROM %s WHERE 1 = 1", table); va_start (ap, table); /* Insert the values */ sqlStatement (sqlStmt, table, NULL, ap); fprintf (log, "remove: SQL statement %s\n", sqlStmt); fflush (log); $ WHENEVER SQLERROR CONTINUE; $ EXECUTE IMMEDIATE $sqlStmt; code = sqlca.sqlcode; fprintf (log, "remove: back from Informix, code = %d\n", code); fflush (log); $ WHENEVER SQLERROR CALL htmlErrorMsg; /* Return if the record was added successfully */ return ((code < 0) ? FALSE : TRUE); } /************************************************************************/ /* */ /* FUNCTION: updateRec AUTHOR: Tim Sabin */ /* DESCRIPTION: updates the current record in the specified table. */ /* DATE CREATED: 11/25/1996 LAST UPDATED: 11/25/1996 */ /* */ /************************************************************************/ int updateRec (char *table, int recNum, ...) { va_list ap; $int rowID; int i, code; $char sqlStmt [2000]; $string testCase [15+1]; char *fieldName, intAsc [12]; t_cgi_entry *fieldPtr; /* Fetch the record to be updated */ va_start (ap, recNum); fprintf (log, "updateRec: updating record %d of table %s\n", recNum, table); fflush (log); fetch (table, recNum, testCase, "test_case_no", &rowID, "rowid", NULL, "test_case_no"); /* Put together an SQL UPDATE statement */ sprintf (sqlStmt, "UPDATE %s SET ", table); /* Insert the field names */ for (i = 0; fieldPtr = va_arg (ap, t_cgi_entry *); i++) { fieldName = va_arg (ap, char *); fprintf (log, "updateRec: field %s, content \"%s\"\n", fieldName, fieldPtr->value); fflush (log); if (fieldPtr->value [0] != '\0') { if (i != 0) strcat (sqlStmt, ","); strcat (sqlStmt, fieldName); strcat (sqlStmt, " = "); strcat (sqlStmt, "\""); strcat (sqlStmt, fieldPtr->value); strcat (sqlStmt, "\""); } } fprintf (log, "updateRec: generated SQL, no WHERE:\n%s\n", sqlStmt); fflush (log); strcat (sqlStmt, " WHERE rowid = "); sprintf (intAsc, "%d", rowID); strcat (sqlStmt, intAsc); fprintf (log, "updateRec: generated SQL:\n%s\n", sqlStmt); fflush (log); /* Execute the UPDATE */ $ WHENEVER SQLERROR CONTINUE; $ EXECUTE IMMEDIATE $sqlStmt; code = sqlca.sqlcode; fprintf (log, "updateRec: back from Informix, code = %d\n", code); fflush (log); $ WHENEVER SQLERROR CALL htmlErrorMsg; /* Return if the record was updated successfully */ return ((code < 0) ? FALSE : TRUE); }