diff -ruN specter-1.4.org/plugins/bit_arr.h specter-1.4.new/plugins/bit_arr.h --- specter-1.4.org/plugins/bit_arr.h Wed Dec 31 16:00:00 1969 +++ specter-1.4.new/plugins/bit_arr.h Tue Sep 19 14:12:08 2006 @@ -0,0 +1,33 @@ +/********************************************************************** + * Bit array manipulator macros * + * Written by Jonathan A. Foster * + * Started September 15th, 2006 * + * Copyright JF Possibilities, Inc. * + * * + * This provides a set of macros for working on an array of ints as * + * an array of bits. All values coming in and out are kept to 0 and 1 * + * by testing inputs as is if they were booleans. A 32 bit integer is * + * assumed in all of these macros. The code will have to be adapted * + * accordingly for different integer sizes. * + * * + * In these macros the following names are use for the following * + * purposes: * + * arr: The bit array. * + * i: The index into the array. * + * v: The value of the bit at that index. * + * * + **********************************************************************/ + +/* offset within an int */ +#define barr_int_off(i) ((i) & 0x1f) + +/* which int contains i */ +#define barr_int_idx(i) ((i)>>5) + +/* set bit to v!=0 */ +#define barr_set(arr, i, v) (arr[barr_int_idx(i)]=(arr[barr_int_idx(i)] \ + & (0xffffffff ^ (1< #include #include "sql.h" +#include "lret.h" +#include "bit_arr.h" /* our configuration directives */ @@ -54,6 +56,7 @@ char *buff_start; char *buff_cur; size_t length; + int *mandatory_fields; }; @@ -64,6 +67,9 @@ MYSQL_FIELD *field; char **columns; int ctr; + int *manfls; + int manfls_ct; + int x; if ((data = malloc(sizeof(struct my_data))) == NULL) { specter_log(SPECTER_FATAL, "Couldn't allocate data: %s.\n", @@ -109,22 +115,48 @@ goto out_free_result; } - for (ctr = 0; (field = mysql_fetch_field(result)) != NULL; ctr++) + if ((manfls = calloc(((mysql_num_fields(result) + 1) >> 5) + 1, sizeof(int))) == NULL) { + specter_log(SPECTER_FATAL, "Couldn't allocate data: %s.\n", + strerror(errno)); + goto out_free_columns; + } + + for (manfls_ct = ctr = 0; (field = mysql_fetch_field(result)) != NULL; ctr++) { columns[ctr] = field->name; + if(sql_find_iret(field->name)) { + if(IS_NOT_NULL(field->flags)) barr_set(manfls, manfls_ct, 1); + manfls_ct++; + } + } columns[ctr] = NULL; + data->mandatory_fields = manfls; data->length = GET_CE(ce,5)->u.value; data->buff_cur = alloc_sql_insert(columns, GET_CE(ce,4)->u.string, &data->buff_start, &data->length, &data->f); /* alloc_sql_insert already printed error message */ if (data->buff_cur == NULL) - goto out_free_columns; + goto out_free_manfls; + + /* Everything is good but we need to reverse manfls to match the + * sql.c ordering + */ + ctr=manfls_ct>>1; + for(manfls_ct-=ctr; ctr; manfls_ct++) { + ctr--; + x = barr_get(manfls, ctr); + barr_set(manfls, ctr, barr_get(manfls, manfls_ct)); + barr_set(manfls, manfls_ct, x); + } /* all done */ free(columns); mysql_free_result(result); return data; +out_free_manfls: + free(manfls); + out_free_columns: free(columns); @@ -161,7 +193,21 @@ { struct my_data *md = data; char *end; + struct sql_field *f = md->f; + int x; + + /*** Test for all required fields ***/ + + for(x=0; f; x++) { + if(barr_get(md->mandatory_fields, x) && !IS_VALID(f->iret)) { + specter_log(SPECTER_DEBUG, "Not all mandatory fields are present. Skipping.\n"); + return 0; + } + f = f->next; + } + /*** Build query ***/ + global_mysql_dbh = md->dbh; if ((end = fill_sql_insert(md->f, md->buff_cur, md->length - (md->buff_cur - md->buff_start), diff -ruN specter-1.4.org/plugins/sql.c specter-1.4.new/plugins/sql.c --- specter-1.4.org/plugins/sql.c Sun Jul 3 04:58:17 2005 +++ specter-1.4.new/plugins/sql.c Wed Oct 4 09:14:18 2006 @@ -52,7 +52,6 @@ { size_t size_min, size_avg; char *buff_cur, *buff_end; - char tmp[SPECTER_IRET_NAME_LEN]; struct sql_field *f; if (fields == NULL) { @@ -60,26 +59,13 @@ return NULL; } - /* allocate field structures trying to calculate size of buffer */ - memset(tmp, 0x0, SPECTER_IRET_NAME_LEN); *ret_field = NULL; /* constant string "INSERT INTO %table () VALUES ()" */ size_min = size_avg = (25 + strlen(table)); do { - char *underscore; specter_iret_t *iret; - strncpy(tmp, *fields, SPECTER_IRET_NAME_LEN-1); - /* replace first underscore with a dot */ - if ((underscore = strchr(tmp, '_')) != NULL) - *underscore = '.'; - - if ((iret = find_iret(tmp)) == NULL) { - specter_log(SPECTER_DEBUG, "Couldn't find \"%s\" field.\n", tmp); - continue; - } - - specter_log(SPECTER_DEBUG, "Field \"%s\" found.\n", tmp); + if ((iret = sql_find_iret(*fields)) == NULL) continue; /* add field's name and a comma */ size_min += strlen(*fields) + 1; @@ -147,7 +133,7 @@ f = (struct sql_field *) malloc(sizeof(struct sql_field)); if (f == NULL) { specter_log(SPECTER_FATAL, - "Couldn't allocated space for sql_field structure: %s.\n", + "Couldn't allocate space for sql_field structure: %s.\n", strerror(errno)); goto out_free_fields; } @@ -320,3 +306,31 @@ free(buff); } +/*** + * sql_find_field - looks up the specter_iret_t of a field + * @name: the SQL field name + * + * This function converts the SQL field name to the specter version before + * performing the lookup. + * + * Returns a pointer to the specter_iret_t for the field or NULL if not + * found. + */ +specter_iret_t *sql_find_iret(char *name) { + char tmp[SPECTER_IRET_NAME_LEN]; + char *underscore; + specter_iret_t *iret; + + tmp[SPECTER_IRET_NAME_LEN-1] = 0; + strncpy(tmp, name, SPECTER_IRET_NAME_LEN-1); + + /* replace first underscore with a dot */ + if ((underscore = strchr(tmp, '_')) != NULL) + *underscore = '.'; + + if ((iret = find_iret(tmp)) == NULL) + specter_log(SPECTER_DEBUG, "Couldn't find \"%s\" field.\n", tmp); + else + specter_log(SPECTER_DEBUG, "Field \"%s\" found.\n", tmp); + return iret; +} diff -ruN specter-1.4.org/plugins/sql.h specter-1.4.new/plugins/sql.h --- specter-1.4.org/plugins/sql.h Sun Jul 3 04:58:17 2005 +++ specter-1.4.new/plugins/sql.h Wed Oct 4 08:44:32 2006 @@ -35,4 +35,4 @@ char *fill_sql_insert(const struct sql_field *f, char *buff, const size_t length, size_t (*escape)(char *, const char *, size_t)); void free_sql_insert(char *buff, struct sql_field *f); - +specter_iret_t *sql_find_iret(char *name);