modules/qi/query_instructions.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- log_inst_print
- create_name_query
- create_query
- write_results
- write_objects
- insert_radix_serials
- map_qc2rx
- QI_execute
- instruction_free
- QI_free
- QI_new
/***************************************
$Revision: 1.15 $
Sql module (sq). This is a mysql implementation of an sql module.
Status: NOT REVUED, NOT TESTED
Note: this code has been heavily coupled to MySQL, and may need to be changed
(to improve performance) if a new RDBMS is used.
******************/ /******************
Filename : query_instructions.c
Author : ottrey@ripe.net
OSs Tested : Solaris
Problems : Moderately linked to MySQL. Not sure which inverse
attributes each option has. Would like to modify this
after re-designing the objects module.
Comments : Not sure about the different keytypes.
******************/ /******************
Copyright (c) 1999 RIPE NCC
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the author not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
***************************************/
#include <stdio.h>
#include "which_keytypes.h"
#include "query_instructions.h"
#include "mysql_driver.h"
#include "attributes.h"
#include "rxroutines.h"
#include "stubs.h"
#include "constants.h"
/*+ String sizes +*/
#define STR_S 63
#define STR_M 255
#define STR_L 1023
#define STR_XL 4095
#define STR_XXL 16383
/*+ Definition of SQL query to be made +*/
struct _Instruction {
WK_Type keytype;
const char *sql_primary_query;
const char *sql_inverse_query;
};
/*+ SQL query to be made for each keytype: +*/
static struct _Instruction Instructions[] = {
{ WK_NAME, Q_PRI_NAME, Q_INV_NAME }, /* A name */
{ WK_NICHDL, Q_PRI_NICHDL, Q_INV_NICHDL }, /* NICHDL */
{ WK_EMAIL, Q_PRI_EMAIL, Q_INV_EMAIL }, /* RFC822 e-mail address */
{ WK_MAINT, Q_PRI_MAINT, Q_INV_MAINT }, /* Maintainer name */
{ WK_KEYCERT, Q_PRI_KEYCERT, Q_INV_KEYCERT }, /* PGPKEY (see i-d for syntax) */
{ WK_IPRANGE, Q_PRI_IPRANGE, Q_INV_IPRANGE }, /* IP range (*) needs modification */
{ WK_IP6RANGE, Q_PRI_IP6RANGE, Q_INV_IP6RANGE }, /* IPv6 range (*) needs modification */
{ WK_NETNAME, Q_PRI_NETNAME, Q_INV_NETNAME }, /* Network name */
{ WK_ASNUM, Q_PRI_ASNUM, Q_INV_ASNUM }, /* AS number */
{ WK_ASSETNAME, Q_PRI_ASSETNAME, Q_INV_ASSETNAME }, /* AS set name */
{ WK_ROUTESETNAME, Q_PRI_ROUTESETNAME, Q_INV_ROUTESETNAME }, /* Route set name */
{ WK_DOMNAME, Q_PRI_DOMNAME, Q_INV_DOMNAME }, /* Domain name */
{ WK_HOSTNAME, Q_PRI_HOSTNAME, Q_INV_HOSTNAME }, /* Host name */
{ WK_LIMERICKNAME, Q_PRI_LIMERICKNAME, Q_INV_LIMERICKNAME }, /* Limerick name */
NULL
};
/* log_inst_print() */
/*++++++++++++++++++++++++++++++++++++++
Log the instruction.
char *str instruction to be logged.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static void log_inst_print(char *str) {
/* [<][>][^][v][top][bottom][index][help] */
FILE *logf;
if (CO_get_instr_logging() == 1) {
if (strcmp(CO_get_instr_logfile(), "stdout") == 0) {
printf("%s", str);
}
else {
logf = fopen(CO_get_instr_logfile(), "a");
fprintf(logf, "%s", str);
fclose(logf);
}
}
} /* log_inst_print() */
/* create_name_query() */
/*++++++++++++++++++++++++++++++++++++++
Create an sql query for the names table.
char *query_str
const char *sql_query
const char *keys
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static void create_name_query(char *query_str, const char *sql_query, const char *keys) {
/* [<][>][^][v][top][bottom][index][help] */
int i;
char *word;
char from_clause_atom[STR_XL];
char from_clause[STR_XXL];
char where_clause_atom[STR_XL];
char where_clause[STR_XXL];
char *keys_tmp;
strcpy(from_clause, "");
strcpy(where_clause, "");
keys_tmp = (char *)calloc(1, strlen(keys)+1);
strcpy(keys_tmp, keys);
word = (char *)strtok(keys_tmp, " ");
sprintf(from_clause_atom, "names N%.2d", 0);
sprintf(where_clause_atom, "N%.2d.name='%s'", 0, word);
strcat(from_clause, from_clause_atom);
strcat(where_clause, where_clause_atom);
for (i=1; (word=(char *)strtok(NULL, " ")) != NULL; i++) {
sprintf(from_clause_atom, ", names N%.2d", i);
sprintf(where_clause_atom, " AND N%.2d.name='%s' AND N00.pe_ro_id = N%.2d.pe_ro_id", i, word, i);
strcat(from_clause, from_clause_atom);
strcat(where_clause, where_clause_atom);
strcpy(from_clause_atom, "");
strcpy(where_clause_atom, "");
}
sprintf(query_str, sql_query, from_clause, where_clause);
/* XXX Free here */
/*
free(keys_tmp);
*/
} /* create_name_query() */
/* create_query() */
/*++++++++++++++++++++++++++++++++++++++
Create an sql query from the query_command and the matching keytype and the
selected inverse attributes.
Note this clears the first inv_attribute it sees, so is called sequentially
until there are no inv_attributes left.
WK_Type keytype The matching keytype.
const Query_command *qc The query command.
mask_t *inv_attrs_bitmap The selected inverse attributes.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static char *create_query(WK_Type keytype, const Query_command *qc, mask_t *inv_attrs_bitmap) {
/* [<][>][^][v][top][bottom][index][help] */
char query_str_buf[STR_XXL];
char query_str_buf_stage1[STR_XXL];
char query_str_buf_filter[STR_XXL];
char *query_str;
const char *sql_query;
char *str;
int inverse_query;
if ( MA_bitcount(*inv_attrs_bitmap) == 0 ) {
sql_query = Instructions[keytype].sql_primary_query;
inverse_query = 0;
}
else {
sql_query = Instructions[keytype].sql_inverse_query;
inverse_query = 1;
}
strcpy(query_str_buf, "");
strcpy(query_str_buf_stage1, "");
switch ( keytype ) {
case WK_NAME:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
create_name_query(query_str_buf, sql_query, qc->keys);
/* XXX There is no way to filter -Tpn WK_NAME in the current schema design. */
}
else {
/* Inverse name query */
if ( MA_isset(*inv_attrs_bitmap, A_AC) == 1 ) {
MA_set(inv_attrs_bitmap, A_AC, 0);
sprintf(query_str_buf_stage1, sql_query, "admin_c", "admin_c", "admin_c");
create_name_query(query_str_buf, query_str_buf_stage1, qc->keys);
}
else if ( MA_isset(*inv_attrs_bitmap, A_TC) == 1 ) {
MA_set(inv_attrs_bitmap, A_TC, 0);
sprintf(query_str_buf_stage1, sql_query, "tech_c", "tech_c", "tech_c");
create_name_query(query_str_buf, query_str_buf_stage1, qc->keys);
}
else if ( MA_isset(*inv_attrs_bitmap, A_ZC) == 1 ) {
MA_set(inv_attrs_bitmap, A_ZC, 0);
sprintf(query_str_buf_stage1, sql_query, "zone_c", "zone_c", "zone_c");
create_name_query(query_str_buf, query_str_buf_stage1, qc->keys);
}
else {
MA_clear(inv_attrs_bitmap);
}
}
}
else {
MA_clear(inv_attrs_bitmap);
}
break;
case WK_NICHDL:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
sprintf(query_str_buf, sql_query, qc->keys);
if ( (MA_isset(qc->object_type_bitmap, A_PN) == 1)
&& (MA_isset(qc->object_type_bitmap, A_RO) == 0) ) {
strcat(query_str_buf, " AND is_person = 1");
}
else if ( (MA_isset(qc->object_type_bitmap, A_RO) == 1)
&& (MA_isset(qc->object_type_bitmap, A_PN) == 0) ) {
strcat(query_str_buf, " AND is_person = 0");
}
}
else {
/* Inverse NICHDL query */
if ( MA_isset(*inv_attrs_bitmap, A_AC) == 1 ) {
MA_set(inv_attrs_bitmap, A_AC, 0);
sprintf(query_str_buf, sql_query, "admin_c", "admin_c", qc->keys, "admin_c");
}
else if ( MA_isset(*inv_attrs_bitmap, A_TC) == 1 ) {
MA_set(inv_attrs_bitmap, A_TC, 0);
sprintf(query_str_buf, sql_query, "tech_c", "tech_c", qc->keys, "tech_c");
}
else if ( MA_isset(*inv_attrs_bitmap, A_ZC) == 1 ) {
MA_set(inv_attrs_bitmap, A_ZC, 0);
sprintf(query_str_buf, sql_query, "zone_c", "zone_c", qc->keys, "zone_c");
}
else {
MA_clear(inv_attrs_bitmap);
}
if ( (MA_isset(qc->object_type_bitmap, A_PN) == 1)
&& (MA_isset(qc->object_type_bitmap, A_RO) == 0) ) {
/* XXX This is backwards. */
strcat(query_str_buf, " AND is_person = 0");
}
else if ( (MA_isset(qc->object_type_bitmap, A_RO) == 1)
&& (MA_isset(qc->object_type_bitmap, A_PN) == 0) ) {
/* XXX This is backwards. */
strcat(query_str_buf, " AND is_person = 1");
}
}
}
else {
MA_clear(inv_attrs_bitmap);
}
break;
case WK_EMAIL:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
/* Inverse EMAIL query */
if ( MA_isset(*inv_attrs_bitmap, A_NY) == 1 ) {
MA_set(inv_attrs_bitmap, A_NY, 0);
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
MA_clear(inv_attrs_bitmap);
}
}
}
else {
MA_clear(inv_attrs_bitmap);
}
break;
case WK_MAINT:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
/* Inverse MAINT query */
if ( MA_isset(*inv_attrs_bitmap, A_MB) == 1 ) {
MA_set(inv_attrs_bitmap, A_MB, 0);
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
MA_clear(inv_attrs_bitmap);
}
}
}
else {
MA_clear(inv_attrs_bitmap);
}
break;
case WK_ASNUM:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
/* Inverse ASNUM query */
if ( MA_isset(*inv_attrs_bitmap, A_OR) == 1 ) {
MA_set(inv_attrs_bitmap, A_OR, 0);
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
MA_clear(inv_attrs_bitmap);
}
}
}
else {
MA_clear(inv_attrs_bitmap);
}
break;
case WK_DOMNAME:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
/* Inverse DOMNAME query */
if ( MA_isset(*inv_attrs_bitmap, A_SD) == 1 ) {
MA_set(inv_attrs_bitmap, A_OR, 0);
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
MA_clear(inv_attrs_bitmap);
}
}
}
else {
MA_clear(inv_attrs_bitmap);
}
break;
default:
if (sql_query != NULL) {
if ( inverse_query == 0 ) {
sprintf(query_str_buf, sql_query, qc->keys);
}
else {
/* No Inverse query */
MA_clear(inv_attrs_bitmap);
}
}
else {
MA_clear(inv_attrs_bitmap);
}
} /* switch() */
if (strcmp(query_str_buf, "") == 0) {
query_str = NULL;
}
else {
query_str = (char *)calloc(1, strlen(query_str_buf)+1);
strcpy(query_str, query_str_buf);
}
return query_str;
} /* create_query() */
/* write_results() */
/*++++++++++++++++++++++++++++++++++++++
Write the results to the client socket.
SQ_result_set_t *result The result set returned from the sql query.
int sock The socket that the client is connected to.
XXX NB. this is very dependendant on what rows are returned in the result!!!
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static int write_results(SQ_result_set_t *result, int sock) {
/* [<][>][^][v][top][bottom][index][help] */
SQ_row_t *row;
char *str;
char log_str[STR_L];
int retrieved_objects=0;
/* Get all the results - one at a time */
if (result != NULL) {
while ( (row = SQ_row_next(result)) != NULL) {
str = SQ_get_column_string(row, 0);
if (str != NULL) {
strcpy(log_str, "");
sprintf(log_str, "Retrieved serial id = %d\n", atoi(str));
log_inst_print(log_str);
}
free(str);
str = SQ_get_column_string(row, 2);
if (str != NULL) {
SK_puts(sock, str);
SK_puts(sock, "\n");
retrieved_objects++;
}
free(str);
}
}
return retrieved_objects;
} /* write_results() */
/* write_objects() */
/*++++++++++++++++++++++++++++++++++++++
This is linked into MySQL by the fact that MySQL doesn't have sub selects
(yet). The queries are done in two stages. Make some temporary tables and
insert into them. Then use them in the next select.
SQ_connection_t *sql_connection The connection to the database.
char *id_table The id of the temporary table (This is a result of the hacky
way we've tried to get MySQL to do sub-selects.)
unsigned int recursive A recursive query.
unsigned int sock The client socket.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
++++++++++++++++++++++++++++++++++++++*/
static void write_objects(SQ_connection_t *sql_connection, char *id_table, unsigned int recursive, unsigned int sock) {
/* [<][>][^][v][top][bottom][index][help] */
/* XXX This should really return a linked list of the objects */
SQ_result_set_t *result;
int retrieved_objects=0;
char sql_command[STR_XL];
char log_str[STR_L];
strcpy(sql_command, "");
/* XXX These may and should change a lot. */
sprintf(sql_command, Q_OBJECTS, id_table, id_table);
result = SQ_execute_query(sql_connection, sql_command);
retrieved_objects += write_results(result, sock);
SQ_free_result(result);
/* Now for recursive queries */
if (recursive == 1) {
strcpy(sql_command, "");
sprintf(sql_command, Q_REC, id_table, "admin_c", id_table, id_table);
SQ_execute_query(sql_connection, sql_command);
strcpy(sql_command, "");
sprintf(sql_command, Q_REC, id_table, "tech_c", id_table, id_table);
SQ_execute_query(sql_connection, sql_command);
strcpy(sql_command, "");
sprintf(sql_command, Q_REC, id_table, "zone_c", id_table, id_table);
SQ_execute_query(sql_connection, sql_command);
/* XXX These may and should change a lot. */
strcpy(sql_command, "");
sprintf(sql_command, Q_REC_OBJECTS, id_table, id_table, id_table);
result = SQ_execute_query(sql_connection, sql_command);
retrieved_objects += write_results(result, sock);
SQ_free_result(result);
/* Now drop the IDS recursive table */
strcpy(sql_command, "");
sprintf(sql_command, "DROP TABLE %s_R", id_table);
SQ_execute_query(sql_connection, sql_command);
}
/* If nothing is retreived default to return the 0th object - I.e "not found" */
if (retrieved_objects == 0) {
result = SQ_execute_query(sql_connection, Q_NO_OBJECTS);
write_results(result, sock);
SQ_free_result(result);
}
/* Now drop the IDS table */
strcpy(sql_command, "");
sprintf(sql_command, "DROP TABLE %s", id_table);
SQ_execute_query(sql_connection, sql_command);
strcpy(log_str, "");
sprintf(log_str, "%d object(s) retrieved\n\n", retrieved_objects);
log_inst_print(log_str);
if (CO_get_accounting() == 1) {
/* XXX - later man.
account(retrieved_objects);
*/
printf("account(retrieved_objects);\n");
}
} /* write_objects() */
/* insert_radix_serials() */
/*++++++++++++++++++++++++++++++++++++++
Insert the radix serial numbers into a temporary table in the database.
mask_t bitmap The bitmap of attribute to be converted.
SQ_connection_t *sql_connection The connection to the database.
char *id_table The id of the temporary table (This is a result of the hacky
way we've tried to get MySQL to do sub-selects.)
GList *datlist The list of data from the radix tree.
XXX Hmmmmm this isn't really a good place to free things... infact it's quite nasty. :-(
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
<LI><A HREF="http://www.gtk.org/rdp/glib/glib-doubly-linked-lists.html">Glist</A>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static void insert_radix_serials(SQ_connection_t *sql_connection, char *id_table, GList *datlist) {
/* [<][>][^][v][top][bottom][index][help] */
GList *qitem;
char sql_command[STR_XL];
int serial;
int i;
/*
TODO -- marek --- TODO
for( qitem = g_list_last(datlist); qitem != NULL; qitem = g_list_previous(qitem)) {
*/
for( qitem = g_list_first(datlist); qitem != NULL; qitem = g_list_next(qitem)) {
rx_datcpy_t *datcpy = qitem->data;
serial = datcpy->leafcpy.data_key;
strcpy(sql_command, "");
sprintf(sql_command, "INSERT INTO %s values (%d)\n", id_table, serial);
SQ_execute_query(sql_connection, sql_command);
/* XXX AAAARGH why here?!?! */
wr_free(datcpy->leafcpy.data_ptr);
}
/* XXX Possible memory leak here. -fix above?? */
g_list_foreach(datlist, rx_free_list_element, NULL);
g_list_free(datlist);
} /* insert_radix_serials() */
/* map_qc2rx() */
/*++++++++++++++++++++++++++++++++++++++
The mapping between a query_command and a radix query.
Query_instruction *qi The Query Instruction to be created from the mapping
of the query command.
const Query_command *qc The query command to be mapped.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static int map_qc2rx(Query_instruction *qi, const Query_command *qc) {
/* [<][>][^][v][top][bottom][index][help] */
int result=1;
qi->rx_keys = qc->keys;
if ( (qc->L == 0) && (qc->M == 0) && (qc->l == 0) && (qc->m == 0) ) {
qi->rx_srch_mode = RX_SRCH_EXLESS;
qi->rx_par_a = 0;
}
else if ( (qc->L == 1) && (qc->M == 0) && (qc->l == 0) && (qc->m == 0) ) {
qi->rx_srch_mode = RX_SRCH_LESS;
qi->rx_par_a = RX_ALL_DEPTHS;
}
else if ( (qc->L == 0) && (qc->M == 1) && (qc->l == 0) && (qc->m == 0) ) {
qi->rx_srch_mode = RX_SRCH_MORE;
qi->rx_par_a = RX_ALL_DEPTHS;
}
else if ( (qc->L == 0) && (qc->M == 0) && (qc->l == 1) && (qc->m == 0) ) {
qi->rx_srch_mode = RX_SRCH_LESS;
qi->rx_par_a = 1;
}
else if ( (qc->L == 0) && (qc->M == 0) && (qc->l == 0) && (qc->m == 1) ) {
qi->rx_srch_mode = RX_SRCH_MORE;
qi->rx_par_a = 1;
}
else {
result = -1;
}
return result;
} /* map_qc2rx() */
/* QI_execute() */
/*++++++++++++++++++++++++++++++++++++++
Execute the query instructions. This is called by a g_list_foreach
function, so each of the sources in the "database source" list can be passed
into this function.
void *database_voidptr Pointer to the database.
void *qis_voidptr Pointer to the query_instructions.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
<LI><A
HREF="http://www.gtk.org/rdp/glib/glib-singly-linked-lists.html#G-SLIST-FOREACH">g_list_foreach</A>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
void QI_execute(void *database_voidptr, void *qis_voidptr) {
/* [<][>][^][v][top][bottom][index][help] */
char *database = (char *)database_voidptr;
Query_instructions *qis = (Query_instructions *)qis_voidptr;
Query_instruction **ins=NULL;
char id_table[STR_S];
char sql_command[STR_XL];
GList *datlist=NULL;
int i;
char log_str[STR_L];
SQ_connection_t *sql_connection=NULL;
sql_connection = SQ_get_connection(CO_get_host(), CO_get_database_port(), database, CO_get_user(), CO_get_password() );
if (sql_connection == NULL) {
SK_puts(qis->sock, "% WARNING: Failed to make connection to ");
SK_puts(qis->sock, database);
SK_puts(qis->sock, " database mirror.\n\n");
}
else {
strcpy(sql_command, "");
/* XXX This is a really bad thing to do. It should'nt _have_ to be called here.
But unfortunately it does. -- Sigh. */
sprintf(id_table, "ID_%d", mysql_thread_id(sql_connection) );
strcpy(sql_command, "");
sprintf(sql_command, "CREATE TABLE %s ( id int ) TYPE=HEAP", id_table);
SQ_execute_query(sql_connection, sql_command);
if (qis->recursive == 1) {
strcpy(sql_command, "");
sprintf(sql_command, "CREATE TABLE %s_R ( id int ) TYPE=HEAP", id_table);
SQ_execute_query(sql_connection, sql_command);
}
ins = qis->instruction;
for (i=0; ins[i] != NULL; i++) {
switch ( (ins[i])->search_type ) {
case QI_SQL:
if ( (ins[i])->query_str != NULL ) {
strcpy(sql_command, "");
sprintf(sql_command, "INSERT INTO %s %s\n", id_table, (ins[i])->query_str);
SQ_execute_query(sql_connection, sql_command);
}
break;
/* XXX I don't like this bit much. This is one of the bits that needs re-designing. */
#define RIPE_REG 17
case QI_RADIX:
datlist = NULL;
printf("searching 'in'\n");
if ( RX_asc_search((ins[i])->rx_srch_mode, (ins[i])->rx_par_a, 0, (ins[i])->rx_keys, RIPE_REG, IP_V4, RX_FAM_IN, &datlist, RX_ANS_ALL) == RX_OK ) {
insert_radix_serials(sql_connection, id_table, datlist);
}
else {
/* Skip query */
strcpy(log_str, "");
sprintf(log_str, "rx: /* Skip in query */\n");
log_inst_print(log_str);
}
datlist = NULL;
printf("searching 'rt'\n");
if ( RX_asc_search((ins[i])->rx_srch_mode, (ins[i])->rx_par_a, 0, (ins[i])->rx_keys, RIPE_REG, IP_V4, RX_FAM_RT, &datlist, RX_ANS_ALL) == RX_OK ) {;
insert_radix_serials(sql_connection, id_table, datlist);
}
else {
/* Skip query */
strcpy(log_str, "");
sprintf(log_str, "rx: /* Skip rt query */\n");
log_inst_print(log_str);
}
break;
case QI_RADIX_IN:
datlist = NULL;
printf("searching 'in'\n");
if ( RX_asc_search((ins[i])->rx_srch_mode, (ins[i])->rx_par_a, 0, (ins[i])->rx_keys, RIPE_REG, IP_V4, RX_FAM_IN, &datlist, RX_ANS_ALL) == RX_OK ) {
insert_radix_serials(sql_connection, id_table, datlist);
}
else {
/* Skip query */
strcpy(log_str, "");
sprintf(log_str, "rx: /* Skip in query */\n");
log_inst_print(log_str);
}
break;
case QI_RADIX_RT:
datlist = NULL;
printf("searching 'rt'\n");
if ( RX_asc_search((ins[i])->rx_srch_mode, (ins[i])->rx_par_a, 0, (ins[i])->rx_keys, RIPE_REG, IP_V4, RX_FAM_RT, &datlist, RX_ANS_ALL) == RX_OK ) {;
insert_radix_serials(sql_connection, id_table, datlist);
}
else {
/* Skip query */
strcpy(log_str, "");
sprintf(log_str, "rx: /* Skip rt query */\n");
log_inst_print(log_str);
}
break;
default:
strcpy(log_str, "");
sprintf(log_str, "ERROR: bad search_type\n");
log_inst_print(log_str);
} /* switch */
}
write_objects(sql_connection, id_table, qis->recursive, qis->sock);
}
SQ_close_connection(sql_connection);
} /* QI_execute() */
/* instruction_free() */
/*++++++++++++++++++++++++++++++++++++++
Free the instruction.
Query_instruction *qi query_instruction to be freed.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
static void instruction_free(Query_instruction *qi) {
/* [<][>][^][v][top][bottom][index][help] */
if (qi != NULL) {
if (qi->query_str != NULL) {
free(qi->query_str);
}
free(qi);
}
} /* instruction_free() */
/* QI_free() */
/*++++++++++++++++++++++++++++++++++++++
Free the query_instructions.
Query_instructions *qis Query_instructions to be freed.
XXX This isn't working too well at the moment.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
void QI_free(Query_instructions *qis) {
/* [<][>][^][v][top][bottom][index][help] */
/* XXX huh!?H?
int i;
for (i=0; qis[i] != NULL; i++) {
instruction_free(*qis[i]);
}
*/
if (qis != NULL) {
free(qis);
}
} /* QI_free() */
/* QI_new() */
/*++++++++++++++++++++++++++++++++++++++
Create a new set of query_instructions.
mask_t bitmap The bitmap of attribute to be converted.
const Query_command *qc The query_command that the instructions are created
from.
unsigned int sock The client socket.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
Query_instructions *QI_new(const Query_command *qc, unsigned int sock) {
/* [<][>][^][v][top][bottom][index][help] */
Query_instructions *qis=NULL;
Query_instruction *qi=NULL;
int i_no=0,j;
WK_Type keytype;
char *query_str;
mask_t inv_attrs_bitmap;
mask_t wk_search_rx_bitmap, wk_search_sq_bitmap;
char log_str[STR_L];
wk_search_rx_bitmap = MA_new(WK_SEARCH_MASK_RX);
wk_search_sq_bitmap = MA_new(WK_SEARCH_MASK_SQ);
qis = (Query_instructions *)calloc(1, sizeof(Query_instructions));
qis->sock = sock;
qis->recursive = qc->recursive;
for (keytype=0; keytype < WK_END; keytype++) {
/* XXX This bit is really bad; and needs work - needs redesigning. */
/* if that keytype is one of the objects in the -T list. (NB. "NULL" implies all by default) */
switch (keytype) {
case WK_NAME:
case WK_NICHDL:
if ( (MA_isset(qc->object_type_bitmap, A_PN) != 1)
&& (MA_isset(qc->object_type_bitmap, A_RO) != 1) ) {
continue;
}
break;
case WK_EMAIL:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_MAINT:
if (MA_isset(qc->object_type_bitmap, A_MT) != 1) {
continue;
}
break;
case WK_KEYCERT:
if (MA_isset(qc->object_type_bitmap, A_KC) != 1) {
continue;
}
break;
case WK_IPRANGE:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_IP6RANGE:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_NETNAME:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_ASNUM:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_ASSETNAME:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_ROUTESETNAME:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_DOMNAME:
if (MA_isset(qc->object_type_bitmap, A_DN) != 1) {
continue;
}
break;
case WK_HOSTNAME:
/* XXX Hmmmm I don't know. Search it anyway. */
;
break;
case WK_LIMERICKNAME:
if (MA_isset(qc->object_type_bitmap, A_LI) != 1) {
continue;
}
break;
default:
printf("Error: bad keytype encountered in QI_new()\n");
}
/* If matched the keytype */
if ( MA_isset(qc->keytypes_bitmap, keytype) == 1) {
qi = (Query_instruction *)calloc(1, sizeof(Query_instruction));
/* SQL Query */
if ( MA_isset(wk_search_sq_bitmap, keytype) == 1 ) {
qi->search_type = QI_SQL;
inv_attrs_bitmap = qc->inv_attrs_bitmap;
j=0;
do {
query_str = create_query(keytype, qc, &inv_attrs_bitmap);
if (query_str != NULL) {
qi->query_str = query_str;
qis->instruction[i_no++] = qi;
}
j++;
if (j> 7) {
strcpy(log_str, "");
sprintf(log_str, "ERROR Too many loops .. bailing\n");
log_inst_print(log_str);
break;
}
} while (MA_bitcount(inv_attrs_bitmap));
}
/* Radix Query */
else if ( MA_isset(wk_search_rx_bitmap, keytype) == 1 ) {
if ( MA_isset(qc->object_type_bitmap, A_IN) == 1 ) {
qi->search_type = QI_RADIX_IN;
}
if ( MA_isset(qc->object_type_bitmap, A_RT) == 1 ) {
qi->search_type = QI_RADIX_RT;
}
if ( ( MA_isset(qc->object_type_bitmap, A_IN) == 1 )
&& ( MA_isset(qc->object_type_bitmap, A_RT) == 1 ) ) {
qi->search_type = QI_RADIX;
}
if (map_qc2rx(qi, qc) == 1) {
/* Add the query_instruction to the array */
qis->instruction[i_no++] = qi;
}
else {
strcpy(log_str, "");
sprintf(log_str, "ERROR in qc2rx mapping: bad combination of flags\n");
log_inst_print(log_str);
}
}
else {
strcpy(log_str, "");
sprintf(log_str, "ERROR: bad search_type\n");
log_inst_print(log_str);
}
}
}
qis->instruction[i_no++] = NULL;
return qis;
} /* QI_new() */