1 | /***************************************
2 | $Revision: 1.29 $
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)
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) {
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) {
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) {
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) {
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) {
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) {
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,
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 | break;
637 |
638 | case 'K':
639 | query_command->filtered=1;
640 | break;
641 |
642 | case 'L':
643 | query_command->L=1;
644 | break;
645 |
646 | case 'M':
647 | query_command->M=1;
648 | break;
649 |
650 | case 'R':
651 | query_command->R=1;
652 | break;
653 |
654 | case 'S':
655 | query_command->S=1;
656 | break;
657 |
658 | case 'T':
659 | if (my_optarg != NULL) {
660 | object_types_str = my_optarg;
661 | while (*object_types_str) {
662 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
663 | if (index == -1) {
664 | strcpy(str_buf, "");
665 | sprintf(str_buf, "Unknown class encountered.\n");
666 | SK_cd_puts(&(qe->condat), str_buf);
667 | errflg++;
668 | }
669 | else {
670 | type = DF_get_class_index(index);
671 | /* Add the type to the bitmap. */
672 | MA_set(&(query_command->object_type_bitmap), type, 1);
673 | }
674 | }
675 | }
676 | break;
677 |
678 | case 'V':
679 | if (qe->version != NULL) {
680 | /* free up the old client info */
681 | wr_free(qe->version);
682 | }
683 |
684 | {
685 | char *token, *cursor = my_optarg;
686 | while( (token = strsep( &cursor, "," )) != NULL ) {
687 | if(IP_addr_e2b( & (qe->pIP), token)
688 | != IP_OK ) {
689 | /* means it was not an IP -> it was a version */
690 | dieif( wr_malloc( (void **)&(qe->version),
691 | strlen(token)+1) != UT_OK);
692 | strcpy(qe->version, token);
693 | }
694 | }
695 | }
696 | break;
697 |
698 | case '?':
699 | errflg++;
700 | break;
701 |
702 | default:
703 | errflg++;
704 | }
705 | }
706 |
707 | /* XXX Report the error. This could be improved. */
708 | /* if (opt_argv[my_optind] != NULL) { */
709 |
710 | /* this needed improvement, MB */
711 | if( my_optind < opt_argc && opt_argv[my_optind] != NULL) {
712 | if ( (errflg) || (strncmp(opt_argv[my_optind], "-", 1) == 0) ) {
713 | return -1;
714 | }
715 | }
716 | else {
717 | if (errflg) {
718 | return -1;
719 | }
720 | }
721 |
722 |
723 | /* Work out the length of space needed */
724 | key_length = 0;
725 | for (i=my_optind ; i < opt_argc; i++) {
726 | /* length for the string + 1 for the '\0'+ 1 for the ' '
727 | [MB removed: + 1 for good luck.] */
728 | if (opt_argv[i] != NULL) {
729 | key_length += strlen(opt_argv[i])+2;
730 | }
731 | }
732 |
733 | dieif( wr_calloc((void **)&(query_command->keys), 1, key_length+1) != UT_OK);
734 | strcpy(query_command->keys, "");
735 | if (errflg == 0) {
736 | for (i=my_optind; i < opt_argc; i++) {
737 | strcat(query_command->keys, opt_argv[i]);
738 | if ( (i + 1) < opt_argc) {
739 | strcat(query_command->keys, " ");
740 | }
741 | }
742 | } /* XXX - Be careful about where this brace goes. */
743 |
744 | /* Now convert the key to uppercase. */
745 | for (i=0; i <= key_length; i++) {
746 | query_command->keys[i] = toupper(query_command->keys[i]);
747 | }
748 |
749 | /* Now make the keytypes_bitmap. */
750 | query_command->keytypes_bitmap = WK_new(query_command->keys);
751 |
752 | if ( CO_get_comnd_logging() == 1 ) {
753 | log_command(tmp_query_str, query_command);
754 | }
755 |
756 | /* Now we don't need this anymore */
757 | wr_free(tmp_query_str);
758 |
759 | return 0;
760 |
761 | } /* QC_fill() */
762 |
763 | /* QC_environ_new() */
764 | /*++++++++++++++++++++++++++++++++++++++
765 | Create a new query environment.
766 |
767 | More:
768 | +html+ <PRE>
769 | Authors:
770 | ottrey
771 | +html+ </PRE><DL COMPACT>
772 | +html+ <DT>Online References:
773 | +html+ <DD><UL>
774 | +html+ </UL></DL>
775 |
776 | ++++++++++++++++++++++++++++++++++++++*/
777 | Query_environ *QC_environ_new(char *ip, unsigned sock) {
778 | Query_environ *qe;
779 |
780 |
781 | dieif( wr_calloc((void **)&qe, 1, sizeof(Query_environ)+1 ) != UT_OK);
782 | qe->condat.ip = ip;
783 | qe->condat.sock = sock;
784 |
785 | /* The source is initialized to be the one defined in the config by default. */
786 | qe->sources_list = g_list_append(qe->sources_list, (void *)CO_get_database());
787 |
788 | return qe;
789 |
790 | } /* QC_environ_new() */
791 |
792 | Query_command *QC_create(char *input, Query_environ *qe)
793 | {
794 | Query_command *qc;
795 |
796 |
797 | dieif( wr_calloc((void **)&qc, 1, sizeof(Query_command)+1) != UT_OK);
798 |
799 | if ( strlen(input) == 0) {
800 | /* An empty query (Ie return) was sent */
801 | qc->query_type = QC_EMPTY;
802 | }
803 | else { /* else <==> input_length > 0 ) */
804 | /* parse query */
805 |
806 | if( QC_fill(input, qc, qe) < 0 ) {
807 | qc->query_type = QC_ERROR;
808 | }
809 | else {
810 | /* Update the query environment */
811 | /* qe = QC_environ_update(qc, qe); */
812 |
813 | /* Only do a query if there are keys. */
814 | if (qc->keys == NULL || strlen(qc->keys) == 0 ) {
815 | if( strlen(qc->keys) == 0
816 | && ( qc->q != -1 || qc->t != -1 || qc->v != -1 ) ) {
817 | qc->query_type = QC_TEMPLATE;
818 | }
819 | else {
820 | qc->query_type = QC_NOKEY;
821 | }
822 | }
823 | else {
824 | if ( strcmp(qc->keys, "HELP") == 0 ) {
825 | qc->query_type = QC_HELP;
826 | }
827 | /* So, a real query */
828 | else if( qc->filtered ) {
829 | qc->query_type = QC_FILTERED;
830 | }
831 | else {
832 | qc->query_type = QC_REAL;
833 | }
834 | }
835 | }
836 | }
837 | return qc;
838 | }
839 |
840 |
841 | char *QC_get_qrytype(qc_qtype_t qrytype) {
842 | dieif(qrytype >= QC_TYPE_MAX);
843 |
844 | return qrytype_str[qrytype];
845 | }