modules/qc/query_command.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- strsep
- my_getopt
- QC_environ_to_string
- QC_query_command_to_string
- log_command
- QC_environ_free
- QC_free
- QC_fill
- QC_environ_new
- QC_create
- QC_get_qrytype
1 /***************************************
2 $Revision: 1.31 $
3
4 Query command module (qc). This is what the whois query gets stored as in
5 memory.
6
7 Status: NOT REVUED, TESTED
8
9 ******************/ /******************
10 Filename : query_command.c
11 Authors : ottrey@ripe.net
12 marek@ripe.net
13 ******************/ /******************
14 Copyright (c) 1999 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #define QC_IMPL
39
40 #include "query_command.h"
41 #include "defs.h"
42 #include "constants.h"
43 #include "which_keytypes.h"
44 #include "memwrap.h"
45
46 #define MAX_OPT_ARG_C 20
47
48 /*+ String sizes +*/
49 #define STR_S 63
50 #define STR_M 255
51 #define STR_L 1023
52 #define STR_XL 4095
53 #define STR_XXL 16383
54
55 #ifdef HAVE_STRSEP
56 /* good */
57 #else
58 # if defined(HAVE_STRTOK_R) && !defined(HAVE_STRSEP)
59 /* emulate strsep with strtok_r
60 by making first arg to strtok_r point to the last
61 */
62 char *
63 strsep(char **stringp, const char *delim)
/* [<][>][^][v][top][bottom][index][help] */
64 {
65 return strtok_r( *stringp, delim, stringp);
66 }
67 # else
68 # error "must have strsep or strtok_r"
69 # endif
70 #endif
71
72
73 /* my_getopt() */
74 /*++++++++++++++++++++++++++++++++++++++
75 A thread safe version of getopt, used to get the options from the whois
76 query.
77
78 int opt_argc The number of query arguments.
79
80 char **opt_argv The query arguments.
81
82 char *optstring The string containing valid options.
83
84 int *my_optind_ptr A pointer to the index into the options of the option
85 returned.
86
87 char **my_optarg_ptr A pointer to the arguments to be returned.
88
89 More:
90 +html+ <PRE>
91 Authors:
92 ottrey
93 +html+ </PRE><DL COMPACT>
94 +html+ <DT>Online References:
95 +html+ <DD><UL>
96 +html+ <LI>man getopt
97 +html+ </UL></DL>
98
99 ++++++++++++++++++++++++++++++++++++++*/
100 static int my_getopt(int opt_argc, char **opt_argv, char *optstring, int *my_optind_ptr, char **my_optarg_ptr) {
/* [<][>][^][v][top][bottom][index][help] */
101 int c='?';
102 int i, j;
103 int no_options;
104 int optind = *my_optind_ptr;
105 char option[4];
106 int option_matched=0;
107
108 /* Get the number of options in the option string */
109 for(i=0, no_options=0; i < strlen(optstring) ; i++) {
110 if (optstring[i] != ':') {
111 no_options++;
112 }
113 }
114
115 /* Iterate through all the option until it matches the current opt_argv */
116 /* Ie. opt_argv[optind] */
117 for (i=0, j=0; i <= no_options; i++, j++) {
118 /* Construct one option from the optstring */
119 option[0] = '-';
120 if (optstring[j] == ':') {
121 j++;
122 }
123 option[1] = optstring[j];
124 if ( optstring[j+1] == ':' ) {
125 option[2] = ':';
126 }
127 else {
128 option[2] = '\0';
129 }
130 option[3] = '\0';
131
132 if (optind < opt_argc) {
133 if (strlen(opt_argv[optind]) > 0) {
134
135 /* printf("opt_argv[%d] == option <==> %s == %s\n",
136 optind, opt_argv[optind], option); */
137
138 if (strncmp(opt_argv[optind], option, 2) == 0) {
139 /* Does the option have arguments. */
140 if (option[2] == ':') {
141 /* If the option has arguments */
142 if (strlen(opt_argv[optind]) > 2) {
143 /* If the arguments are in this token */
144 *my_optarg_ptr = (opt_argv[optind])+2;
145 }
146 else {
147 /* If the arguments are in the next token */
148 *my_optarg_ptr = opt_argv[optind+1];
149 optind++;
150 }
151 }
152 else {
153 /* There are no arguments to this token */
154 *my_optarg_ptr = NULL;
155 }
156 /* Option matched - break out of the search */
157 option_matched = 1;
158 break;
159 }
160 }
161 }
162 } /* for() */
163
164 if ( option_matched == 1 ) {
165 /* This option was matched, return it. */
166 c = option[1];
167
168 /* Move to the next opt_argv */
169 optind++;
170 *my_optind_ptr = optind;
171 }
172 else {
173 /* Discontinue search */
174 c = EOF;
175 }
176
177 return c;
178
179 } /* my_getopt() */
180
181 /* QC_environ_to_string() */
182 /*++++++++++++++++++++++++++++++++++++++
183 Convert the query_environ to a string.
184
185 Query_environ *query_environ The query_environ to be converted.
186
187 More:
188 +html+ <PRE>
189 Authors:
190 ottrey
191 +html+ </PRE><DL COMPACT>
192 +html+ <DT>Online References:
193 +html+ <DD><UL>
194 +html+ </UL></DL>
195
196 ++++++++++++++++++++++++++++++++++++++*/
197 char *QC_environ_to_string(Query_environ qe) {
/* [<][>][^][v][top][bottom][index][help] */
198 char *result;
199 char *str1;
200 char str2[IP_ADDRSTR_MAX];
201 char result_buf[STR_XL];
202
203 str1 = CO_sources_list_to_string(qe.sources_list);
204
205 if( IP_addr_b2a( &(qe.pIP), str2, IP_ADDRSTR_MAX) != IP_OK ) {
206 *str2 = '\0';
207 }
208
209 sprintf(result_buf, "host=%s, keep_connection=%s, sources=%s, version=%s%s%s", qe.condat.ip,
210 qe.k?"on":"off",
211 str1,
212 (qe.version == NULL) ? "?" : qe.version,
213 *str2 == '\0' ? "" : ", passedIP=",
214 *str2 == '\0' ? "" : str2
215 );
216
217 wr_free(str1);
218
219 dieif( wr_malloc((void **)&result, strlen(result_buf)+1) != UT_OK);
220
221 strcpy(result, result_buf);
222
223 return result;
224
225 } /* QC_environ_to_string() */
226
227 /* QC_query_command_to_string() */
228 /*++++++++++++++++++++++++++++++++++++++
229 Convert the query_command to a string.
230
231 Query_command *query_command The query_command to be converted.
232
233 More:
234 +html+ <PRE>
235 Authors:
236 ottrey
237 +html+ </PRE><DL COMPACT>
238 +html+ <DT>Online References:
239 +html+ <DD><UL>
240 +html+ </UL></DL>
241
242 ++++++++++++++++++++++++++++++++++++++*/
243 char *QC_query_command_to_string(Query_command *query_command) {
/* [<][>][^][v][top][bottom][index][help] */
244 char *result;
245 char result_buf[STR_XL];
246 char *str1;
247 char *str2;
248 char *str3;
249
250 str1 = MA_to_string(query_command->inv_attrs_bitmap, DF_get_attribute_names());
251 str2 = MA_to_string(query_command->object_type_bitmap, DF_get_class_names());
252 str3 = WK_to_string(query_command->keytypes_bitmap);
253
254 sprintf(result_buf, "Query_command : inv_attrs=%s, recursive=%s, object_type=%s, (e=%d,g=%d,l=%d,m=%d,q=%d,t=%d,v=%d,x=%d,F=%d,K=%d,L=%d,M=%d,R=%d,S=%d), possible keytypes=%s, keys=[%s]",
255 str1,
256 query_command->recursive?"y":"n",
257 str2,
258 query_command->e,
259 query_command->g,
260 query_command->l,
261 query_command->m,
262 query_command->q,
263 query_command->t,
264 query_command->v,
265 query_command->x,
266 query_command->fast,
267 query_command->filtered,
268 query_command->L,
269 query_command->M,
270 query_command->R,
271 query_command->S,
272 str3,
273 query_command->keys);
274 wr_free(str1);
275 wr_free(str2);
276 wr_free(str3);
277
278 dieif( wr_malloc((void **)&result, strlen(result_buf)+1) != UT_OK);
279 strcpy(result, result_buf);
280
281 return result;
282
283 } /* QC_query_command_to_string() */
284
285 /* log_command() */
286 /*++++++++++++++++++++++++++++++++++++++
287 Log the command.
288 This is more to do with Tracing. And should/will get merged with a tracing
289 module (when it is finalized.)
290
291 char *query_str
292
293 Query_command *query_command
294
295 More:
296 +html+ <PRE>
297 Authors:
298 ottrey
299 +html+ </PRE><DL COMPACT>
300 +html+ <DT>Online References:
301 +html+ <DD><UL>
302 +html+ </UL></DL>
303
304 ++++++++++++++++++++++++++++++++++++++*/
305 static void log_command(char *query_str, Query_command *query_command) {
/* [<][>][^][v][top][bottom][index][help] */
306 char *str;
307
308 if( ER_is_traced(FAC_QC, ASP_QC_BUILD) ) {
309 str = QC_query_command_to_string(query_command);
310 ER_dbg_va(FAC_QC, ASP_QC_BUILD,
311 "query=[%s] %s", query_str, str);
312 wr_free(str);
313 }
314 } /* log_command() */
315
316 /* QC_environ_free() */
317 /*++++++++++++++++++++++++++++++++++++++
318 Free the query_environ.
319
320 Query_command *qc query_environ to be freed.
321
322 More:
323 +html+ <PRE>
324 Authors:
325 ottrey
326 +html+ </PRE><DL COMPACT>
327 +html+ <DT>Online References:
328 +html+ <DD><UL>
329 +html+ </UL></DL>
330
331 ++++++++++++++++++++++++++++++++++++++*/
332 void QC_environ_free(Query_environ *qe) {
/* [<][>][^][v][top][bottom][index][help] */
333 if (qe != NULL) {
334 if (qe->version != NULL) {
335 wr_free(qe->version);
336 }
337
338 if (qe->sources_list != NULL) {
339 g_list_free(qe->sources_list);
340 }
341 wr_free(qe);
342 }
343 } /* QC_environ_free() */
344
345 /* QC_free() */
346 /*++++++++++++++++++++++++++++++++++++++
347 Free the query_command.
348
349 Query_command *qc query_command to be freed.
350
351 XXX I'm not sure the bitmaps will get freed.
352 qc->inv_attrs_bitmap
353 qc->object_type_bitmap
354 qc->keytypes_bitmap
355
356 More:
357 +html+ <PRE>
358 Authors:
359 ottrey
360 +html+ </PRE><DL COMPACT>
361 +html+ <DT>Online References:
362 +html+ <DD><UL>
363 +html+ </UL></DL>
364
365 ++++++++++++++++++++++++++++++++++++++*/
366 void QC_free(Query_command *qc) {
/* [<][>][^][v][top][bottom][index][help] */
367 if (qc != NULL) {
368 if (qc->keys != NULL) {
369 wr_free(qc->keys);
370 }
371 wr_free(qc);
372 }
373 } /* QC_free() */
374
375
376
377 /* QC_fill() */
378 /*++++++++++++++++++++++++++++++++++++++
379 Create a new query_command.
380
381
382
383 char *query_str The garden variety whois query string.
384
385 Query_environ *qe the environment
386
387 Pre-condition:
388
389 Returns -1 when query incorrect, 0 otherwise
390
391 More:
392 +html+ <PRE>
393 Authors:
394 ottrey
395 +html+ </PRE><DL COMPACT>
396 +html+ <DT>Online References:
397 +html+ <DD><UL>
398 +html+ </UL></DL>
399
400 ++++++++++++++++++++++++++++++++++++++*/
401 static
402 int QC_fill(char *query_str,
/* [<][>][^][v][top][bottom][index][help] */
403 Query_command *query_command,
404 Query_environ *qe) {
405 char *my_optarg;
406 int my_optind = 0;
407 int c;
408 int errflg = 0;
409 char *inv_attrs_str = NULL;
410 char *object_types_str = NULL;
411 char *sources_str = NULL;
412 int opt_argc;
413 gchar **opt_argv;
414 char *value;
415 char *tmp_query_str;
416 int key_length;
417 int i;
418 int index;
419 int type;
420 int attr;
421
422 char str_buf[STR_XL];
423
424 GList *first_source;
425
426 query_command->e = 0;
427 query_command->g = 0;
428 query_command->inv_attrs_bitmap = MA_new(MA_END);
429 query_command->recursive = 1; /* Recursion is on by default. */
430 query_command->l = 0;
431 query_command->m = 0;
432 query_command->q = -1;
433 query_command->t = -1;
434 query_command->v = -1;
435 query_command->x = 0;
436 query_command->fast = 0;
437 query_command->filtered = 0;
438 query_command->L = 0;
439 query_command->M = 0;
440 query_command->R = 0;
441 query_command->S = 0;
442 query_command->object_type_bitmap = MA_new(MA_END);
443 /*
444 query_command->keytypes_bitmap = MA_new(MA_END);
445 */
446 query_command->keys = NULL;
447
448 /* This is so Marek can't crash me :-) */
449 /* Side Effect - query keys are subsequently cut short to STR_S size. */
450
451 dieif( wr_calloc((void **)&tmp_query_str, 1, STR_S+1) != UT_OK);
452 strncpy(tmp_query_str, query_str, STR_S);
453
454 /* Create the arguments. */
455 /* This allows only a maximum of MAX_OPT_ARG_C words in the query. */
456 opt_argv = g_strsplit(tmp_query_str, " ", MAX_OPT_ARG_C);
457
458 /* Determine the number of arguments. */
459 for (opt_argc=0; opt_argv[opt_argc] != NULL; opt_argc++);
460
461 while ((c = my_getopt(opt_argc, opt_argv, "aegi:klrmq:s:t:v:xFKLMRST:V:", &my_optind, &my_optarg)) != EOF) {
462 switch (c) {
463 case 'a':
464 /* Remove any user specified sources from the sources list. */
465 while ((first_source = g_list_first(qe->sources_list)) != NULL) {
466 qe->sources_list = g_list_remove(qe->sources_list, first_source->data);
467 }
468 #if 0
469 /* Add all the config sources to the sources list. */
470 for (i=0; CO_get_source(i) != NULL; i++) {
471 qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_source_database(i));
472 }
473 #else
474 qe->sources_list = g_list_append(qe->sources_list, CO_get_database() );
475 #endif
476
477 break;
478
479 case 'e':
480 query_command->e=1;
481 break;
482
483 case 'g':
484 query_command->g=1;
485 break;
486
487 case 'i':
488 if (my_optarg != NULL) {
489 inv_attrs_str = my_optarg;
490 /* Now a really stupid hard-coded hack to support "pn" being a synonym for "ac,tc,zc,ah" */
491 /* I particularly object to this because it references attributes that should only be
492 defined in XML - but I don't see a simplier more robust way of doing this hack.
493 :-( - ottrey 8/12/99 */
494 if (strcmp(inv_attrs_str, "pn") == 0) {
495 dieif( wr_malloc((void **)&inv_attrs_str, 12) != UT_OK);
496 strcpy(inv_attrs_str, "ac,tc,zc,ah");
497 }
498 else if (strcmp(inv_attrs_str, "ro") == 0) {
499 dieif( wr_malloc((void **)&inv_attrs_str, 12) != UT_OK);
500 strcpy(inv_attrs_str, "ac,tc,zc,ah");
501 }
502 while (*inv_attrs_str) {
503 index = getsubopt(&inv_attrs_str, DF_get_attribute_aliases(), &value);
504 if (index == -1) {
505 attr = -1;
506 strcpy(str_buf, "");
507 sprintf(str_buf, "Unknown attribute encountered.\n");
508 SK_cd_puts(&(qe->condat), str_buf);
509 errflg++;
510 }
511 else {
512 mask_t inv_attr_mask = MA_new(INV_ATTR_MASK);
513 attr = DF_get_attribute_index(index);
514 if ( MA_isset(inv_attr_mask, attr) == 1 ) {
515 /* Add the attr to the bitmap. */
516 MA_set(&(query_command->inv_attrs_bitmap), attr, 1);
517 }
518 else {
519 strcpy(str_buf, "");
520 sprintf(str_buf, "\"%s\" does not belong to inv_attr.\n", (DF_get_attribute_aliases())[index]);
521 SK_cd_puts(&(qe->condat), str_buf);
522 errflg++;
523 }
524 }
525 } /* while () */
526 } /* if () */
527 break;
528
529 case 'k':
530 /* This is a tricky XOR operation.... ;-)
531 State transition for k_flag:
532 0 -> 0 then k flag = 0, connected = 0
533 0 -> 1 then k flag = 1, connected = 1
534 1 -> 0 then k flag = 1, connected = 1
535 1 -> 1 then k flag = 0, connected = 0
536 */
537 qe->k ^= 1;
538 break;
539
540 case 'r':
541 query_command->recursive=0; /* Unset recursion */
542 break;
543
544 case 'l':
545 query_command->l=1;
546 break;
547
548 case 'm':
549 query_command->m=1;
550 break;
551
552 case 'q':
553 if (my_optarg != NULL) {
554 index = getsubopt(&my_optarg, DF_get_server_queries(), &value);
555 if (index == -1) {
556 errflg++;
557 }
558 else {
559 query_command->q = index;
560 }
561 } /* if () */
562 break;
563
564 case 's':
565 if (my_optarg != NULL) {
566 sources_str = my_optarg;
567 /* Remove any sources from the sources list. */
568 while ((first_source = g_list_first(qe->sources_list)) != NULL) {
569 qe->sources_list = g_list_remove(qe->sources_list, first_source->data);
570 }
571 while (*sources_str) {
572 index = getsubopt(&sources_str, CO_get_sources(), &value);
573 if (index == -1) {
574 strcpy(str_buf, "");
575 sprintf(str_buf, "Unknown source encountered.\nNot one of: %s\n", CO_sources_to_string());
576 SK_cd_puts(&(qe->condat), str_buf);
577
578 /* Put the default source back in. */
579 SK_cd_puts(&(qe->condat), "Reverting to default source - ");
580 SK_cd_puts(&(qe->condat), CO_get_database());
581 SK_cd_puts(&(qe->condat), "\n");
582 qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_database());
583 errflg++;
584 }
585 else {
586 qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_source_database(index));
587 }
588 } /* while () */
589 } /* if () */
590 break;
591
592 case 't':
593 if (my_optarg != NULL) {
594 object_types_str = my_optarg;
595 while (*object_types_str) {
596 index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
597 if (index == -1) {
598 strcpy(str_buf, "");
599 sprintf(str_buf, "Unknown object encountered.\n");
600 SK_cd_puts(&(qe->condat), str_buf);
601 errflg++;
602 }
603 else {
604 type = DF_get_class_index(index);
605 query_command->t=type;
606 }
607 }
608 }
609 break;
610
611 case 'v':
612 if (my_optarg != NULL) {
613 object_types_str = my_optarg;
614 if (*object_types_str) {
615 index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
616 if (index == -1) {
617 strcpy(str_buf, "");
618 sprintf(str_buf, "Unknown object encountered.\n");
619 SK_cd_puts(&(qe->condat), str_buf);
620 errflg++;
621 }
622 else {
623 type = DF_get_class_index(index);
624 query_command->v=type;
625 }
626 }
627 }
628 break;
629
630 case 'x':
631 query_command->x=1;
632 break;
633
634 case 'F':
635 query_command->fast=1;
636 query_command->recursive=0; /* implies no recursion */
637 break;
638
639 case 'K':
640 query_command->filtered=1;
641 query_command->recursive=0; /* implies no recursion */
642 break;
643
644 case 'L':
645 query_command->L=1;
646 break;
647
648 case 'M':
649 query_command->M=1;
650 break;
651
652 case 'R':
653 query_command->R=1;
654 break;
655
656 case 'S':
657 query_command->S=1;
658 break;
659
660 case 'T':
661 if (my_optarg != NULL) {
662 object_types_str = my_optarg;
663 while (*object_types_str) {
664 index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
665 if (index == -1) {
666 strcpy(str_buf, "");
667 sprintf(str_buf, "Unknown class encountered.\n");
668 SK_cd_puts(&(qe->condat), str_buf);
669 errflg++;
670 }
671 else {
672 type = DF_get_class_index(index);
673 /* Add the type to the bitmap. */
674 MA_set(&(query_command->object_type_bitmap), type, 1);
675 }
676 }
677 }
678 break;
679
680 case 'V':
681 if (qe->version != NULL) {
682 /* free up the old client info */
683 wr_free(qe->version);
684 }
685
686 {
687 char *token, *cursor = my_optarg;
688 while( (token = strsep( &cursor, "," )) != NULL ) {
689 if(IP_addr_e2b( & (qe->pIP), token)
690 != IP_OK ) {
691 /* means it was not an IP -> it was a version */
692 dieif( wr_malloc( (void **)&(qe->version),
693 strlen(token)+1) != UT_OK);
694 strcpy(qe->version, token);
695 }
696 }
697 }
698 break;
699
700 case '?':
701 errflg++;
702 break;
703
704 default:
705 errflg++;
706 }
707 }
708
709 /* XXX Report the error. This could be improved. */
710 /* if (opt_argv[my_optind] != NULL) { */
711
712 /* this needed improvement, MB */
713 if( my_optind < opt_argc && opt_argv[my_optind] != NULL) {
714 if ( (errflg) || (strncmp(opt_argv[my_optind], "-", 1) == 0) ) {
715 return -1;
716 }
717 }
718 else {
719 if (errflg) {
720 return -1;
721 }
722 }
723
724
725 /* Work out the length of space needed */
726 key_length = 0;
727 for (i=my_optind ; i < opt_argc; i++) {
728 /* length for the string + 1 for the '\0'+ 1 for the ' '
729 [MB removed: + 1 for good luck.] */
730 if (opt_argv[i] != NULL) {
731 key_length += strlen(opt_argv[i])+2;
732 }
733 }
734
735 dieif( wr_calloc((void **)&(query_command->keys), 1, key_length+1) != UT_OK);
736 strcpy(query_command->keys, "");
737 if (errflg == 0) {
738 for (i=my_optind; i < opt_argc; i++) {
739 strcat(query_command->keys, opt_argv[i]);
740 if ( (i + 1) < opt_argc) {
741 strcat(query_command->keys, " ");
742 }
743 }
744 } /* XXX - Be careful about where this brace goes. */
745
746 /* Now convert the key to uppercase. */
747 for (i=0; i <= key_length; i++) {
748 query_command->keys[i] = toupper(query_command->keys[i]);
749 }
750
751 /* Now make the keytypes_bitmap. */
752 query_command->keytypes_bitmap = WK_new(query_command->keys);
753
754 if ( CO_get_comnd_logging() == 1 ) {
755 log_command(tmp_query_str, query_command);
756 }
757
758 /* Now we don't need this anymore */
759 wr_free(tmp_query_str);
760
761 return 0;
762
763 } /* QC_fill() */
764
765 /* QC_environ_new() */
766 /*++++++++++++++++++++++++++++++++++++++
767 Create a new query environment.
768
769 More:
770 +html+ <PRE>
771 Authors:
772 ottrey
773 +html+ </PRE><DL COMPACT>
774 +html+ <DT>Online References:
775 +html+ <DD><UL>
776 +html+ </UL></DL>
777
778 ++++++++++++++++++++++++++++++++++++++*/
779 Query_environ *QC_environ_new(char *ip, unsigned sock) {
/* [<][>][^][v][top][bottom][index][help] */
780 Query_environ *qe;
781
782
783 dieif( wr_calloc((void **)&qe, 1, sizeof(Query_environ)+1 ) != UT_OK);
784 qe->condat.ip = ip;
785 qe->condat.sock = sock;
786
787 /* The source is initialized to be the one defined in the config by default. */
788 qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_database());
789
790 return qe;
791
792 } /* QC_environ_new() */
793
794 Query_command *QC_create(char *input, Query_environ *qe)
/* [<][>][^][v][top][bottom][index][help] */
795 {
796 Query_command *qc;
797
798
799 dieif( wr_calloc((void **)&qc, 1, sizeof(Query_command)+1) != UT_OK);
800
801 if ( strlen(input) == 0) {
802 /* An empty query (Ie return) was sent */
803 qc->query_type = QC_EMPTY;
804 }
805 else { /* else <==> input_length > 0 ) */
806 /* parse query */
807
808 if( QC_fill(input, qc, qe) < 0 ) {
809 qc->query_type = QC_ERROR;
810 }
811 else {
812 /* Update the query environment */
813 /* qe = QC_environ_update(qc, qe); */
814
815 /* Only do a query if there are keys. */
816 if (qc->keys == NULL || strlen(qc->keys) == 0 ) {
817 if( strlen(qc->keys) == 0
818 && ( qc->q != -1 || qc->t != -1 || qc->v != -1 ) ) {
819 qc->query_type = QC_TEMPLATE;
820 }
821 else {
822 qc->query_type = QC_NOKEY;
823 }
824 }
825 else {
826 if ( strcmp(qc->keys, "HELP") == 0 ) {
827 qc->query_type = QC_HELP;
828 }
829 /* So, a real query */
830 else if( qc->filtered ) {
831 qc->query_type = QC_FILTERED;
832 }
833 else {
834 qc->query_type = QC_REAL;
835 }
836 }
837 }
838 }
839 return qc;
840 }
841
842
843 char *QC_get_qrytype(qc_qtype_t qrytype) {
/* [<][>][^][v][top][bottom][index][help] */
844 dieif(qrytype >= QC_TYPE_MAX);
845
846 return qrytype_str[qrytype];
847 }