1 | /***************************************
2 | $Revision: 1.56 $
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 | Author : ottrey@ripe.net
12 | Modifications by : marek@ripe.net
13 | ******************/ /******************
14 | Copyright (c) 1999,2000,2001,2002 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 |
34 | #define QC_IMPL
35 | #include "rip.h"
36 |
37 | #include <stdlib.h>
38 | #include <stdio.h>
39 | #include <string.h>
40 | #include <ctype.h>
41 |
42 |
43 | #define MAX_OPT_ARG_C 20
44 |
45 | extern char *suboptarg;
46 | extern int getsubopt(char **optionp, char * const *tokens, char **valuep);
47 |
48 | /*++++++++++++++++++++++++++++++++++++++
49 | make a list of sources. expects list to hold source handles
50 |
51 | char *
52 | qc_sources_list_to_string returns an allocated string, must be freed
53 |
54 | GList *list list of source handles (as defined by CA)
55 |
56 | ++++++++++++++++++++++++++++++++++++++*/
57 | char *
58 | qc_sources_list_to_string(GList *list)
59 | {
60 | GString *tmp;
61 | GList *qitem;
62 | char *result;
63 |
64 | /* use GString for the result, because it resizes magically */
65 | tmp = g_string_sized_new(STR_L);
66 |
67 | /* loop through the list, creating a string with the names of the
68 | sources separated by commas */
69 | qitem = g_list_first(list);
70 | if (qitem != NULL) {
71 | for (;;) {
72 | ca_dbSource_t *source_hdl = (ca_dbSource_t *) ( qitem->data );
73 | char *srcname = ca_get_srcname( source_hdl );
74 | g_string_append(tmp, srcname);
75 |
76 | qitem = g_list_next(qitem);
77 | if (qitem == NULL) {
78 | break;
79 | }
80 |
81 | g_string_append_c(tmp, ',');
82 | }
83 | }
84 |
85 | /* move to a new buffer for the return */
86 | result = UT_strdup(tmp->str);
87 | g_string_free(tmp, TRUE);
88 | return result;
89 | }
90 |
91 | /* QC_environ_to_string() */
92 | /*++++++++++++++++++++++++++++++++++++++
93 | Convert the query_environ to a string.
94 |
95 | Query_environ *query_environ The query_environ to be converted.
96 |
97 | More:
98 | +html+ <PRE>
99 | Authors:
100 | ottrey
101 | +html+ </PRE><DL COMPACT>
102 | +html+ <DT>Online References:
103 | +html+ <DD><UL>
104 | +html+ </UL></DL>
105 |
106 | ++++++++++++++++++++++++++++++++++++++*/
107 | char *
108 | QC_environ_to_string(Query_environ qe)
109 | {
110 | char *sources;
111 | char passed_addr[IP_ADDRSTR_MAX];
112 | GString *tmp;
113 | char *result;
114 |
115 | /* convert the sources and the passed address (if any) to printable strings */
116 | sources = qc_sources_list_to_string(qe.sources_list);
117 | if( IP_addr_b2a( &(qe.pIP), passed_addr, IP_ADDRSTR_MAX) != IP_OK ) {
118 | passed_addr[0] = '\0';
119 | }
120 |
121 | /* format the environment info */
122 | tmp = g_string_sized_new(STR_L);
123 | g_string_sprintf(tmp,
124 | "host=%s, keep_connection=%s, sources=%s, version=%s%s%s",
125 | qe.condat.ip,
126 | qe.k ? "on" : "off",
127 | sources,
128 | (qe.version == NULL) ? "?" : qe.version,
129 | passed_addr[0] == '\0' ? "" : ", passedIP=",
130 | passed_addr);
131 |
132 | /* move result to return buffer, and free up memory */
133 | result = UT_strdup(tmp->str);
134 | g_string_free(tmp, TRUE);
135 | UT_free(sources);
136 |
137 | return result;
138 |
139 | } /* QC_environ_to_string() */
140 |
141 | /* QC_query_command_to_string() */
142 | /*++++++++++++++++++++++++++++++++++++++
143 | Convert the query_command to a string.
144 |
145 | Query_command *query_command The query_command to be converted.
146 |
147 | More:
148 | +html+ <PRE>
149 | Authors:
150 | ottrey
151 | +html+ </PRE><DL COMPACT>
152 | +html+ <DT>Online References:
153 | +html+ <DD><UL>
154 | +html+ </UL></DL>
155 |
156 | ++++++++++++++++++++++++++++++++++++++*/
157 | char *QC_query_command_to_string(Query_command *query_command) {
158 | char result_buf[STR_XL];
159 | char *str1;
160 | char *str2;
161 | char *str3;
162 |
163 | str1 = MA_to_string(query_command->inv_attrs_bitmap, DF_get_attribute_names());
164 | str2 = MA_to_string(query_command->object_type_bitmap, DF_get_class_names());
165 | str3 = WK_to_string(query_command->keytypes_bitmap);
166 |
167 | sprintf(result_buf, "Query_command : inv_attrs=%s, recursive=%s, object_type=%s, (c=%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]",
168 | str1,
169 | query_command->recursive?"y":"n",
170 | str2,
171 | query_command->c_irt_search ? "TRUE" : "FALSE",
172 | query_command->e,
173 | query_command->g,
174 | query_command->l,
175 | query_command->m,
176 | query_command->q,
177 | query_command->t,
178 | query_command->v,
179 | query_command->x,
180 | query_command->fast,
181 | query_command->filtered,
182 | query_command->L,
183 | query_command->M,
184 | query_command->R,
185 | query_command->S,
186 | str3,
187 | query_command->keys);
188 | UT_free(str1);
189 | UT_free(str2);
190 | UT_free(str3);
191 |
192 | return UT_strdup(result_buf);
193 |
194 | } /* QC_query_command_to_string() */
195 |
196 | /* log_command() */
197 | /*++++++++++++++++++++++++++++++++++++++
198 | Log the command.
199 | This is more to do with Tracing. And should/will get merged with a tracing
200 | module (when it is finalized.)
201 |
202 | char *query_str
203 |
204 | Query_command *query_command
205 |
206 | More:
207 | +html+ <PRE>
208 | Authors:
209 | ottrey
210 | +html+ </PRE><DL COMPACT>
211 | +html+ <DT>Online References:
212 | +html+ <DD><UL>
213 | +html+ </UL></DL>
214 |
215 | ++++++++++++++++++++++++++++++++++++++*/
216 | static void log_command(char *query_str, Query_command *query_command) {
217 | char *str;
218 |
219 | if( ER_is_traced(FAC_QC, ASP_QC_BUILD) ) {
220 | str = QC_query_command_to_string(query_command);
221 | ER_dbg_va(FAC_QC, ASP_QC_BUILD,
222 | "query=[%s] %s", query_str, str);
223 | UT_free(str);
224 | }
225 | } /* log_command() */
226 |
227 | /* QC_environ_free() */
228 | /*++++++++++++++++++++++++++++++++++++++
229 | Free the query_environ.
230 |
231 | Query_command *qc query_environ to be freed.
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 | void QC_environ_free(Query_environ *qe) {
244 | if (qe != NULL) {
245 | if (qe->version != NULL) {
246 | UT_free(qe->version);
247 | }
248 |
249 | if (qe->sources_list != NULL) {
250 | g_list_free(qe->sources_list);
251 | qe->sources_list=NULL;
252 | }
253 | UT_free(qe);
254 | }
255 | } /* QC_environ_free() */
256 |
257 | /* QC_free() */
258 | /*++++++++++++++++++++++++++++++++++++++
259 | Free the query_command.
260 |
261 | Query_command *qc query_command to be freed.
262 |
263 | XXX I'm not sure the bitmaps will get freed.
264 | qc->inv_attrs_bitmap
265 | qc->object_type_bitmap
266 | qc->keytypes_bitmap
267 |
268 | More:
269 | +html+ <PRE>
270 | Authors:
271 | ottrey
272 | +html+ </PRE><DL COMPACT>
273 | +html+ <DT>Online References:
274 | +html+ <DD><UL>
275 | +html+ </UL></DL>
276 |
277 | ++++++++++++++++++++++++++++++++++++++*/
278 | void QC_free(Query_command *qc) {
279 | if (qc != NULL) {
280 | if (qc->keys != NULL) {
281 | UT_free(qc->keys);
282 | }
283 | UT_free(qc);
284 | }
285 | } /* QC_free() */
286 |
287 |
288 |
289 | /* QC_fill() */
290 | /*++++++++++++++++++++++++++++++++++++++
291 | Create a new query_command.
292 | Returns 0 when OK, -1 when query incorrect.
293 |
294 | char *query_str The garden variety whois query string.
295 |
296 | Query_environ *qe the environment
297 |
298 | More:
299 | +html+ <PRE>
300 | Authors:
301 | ottrey - original code
302 | marek - modified for my getopts, multiple sources;
303 | and generally cleaned.
304 | +html+ </PRE><DL COMPACT>
305 | +html+ <DT>Online References:
306 | +html+ <DD><UL>
307 | +html+ </UL></DL>
308 |
309 | ++++++++++++++++++++++++++++++++++++++*/
310 | static
311 | int QC_fill(char *query_str,
312 | Query_command *query_command,
313 | Query_environ *qe) {
314 |
315 | int c;
316 | int synerrflg = 0;
317 | int badparerr = 0;
318 | int minusk = 0;
319 | char *inv_attrs_str = NULL;
320 | char *object_types_str = NULL;
321 | int opt_argc;
322 | gchar **opt_argv;
323 | char *value;
324 | /* char *tmp_query_str;*/
325 | unsigned key_length;
326 | int i;
327 | int index;
328 | C_Type_t type;
329 | A_Type_t attr;
330 | getopt_state_t *gst = NULL;
331 |
332 | query_command->c_irt_search = FALSE;
333 | query_command->d = 0;
334 | query_command->e = 0;
335 | query_command->g = 0;
336 | query_command->inv_attrs_bitmap = MA_new(MA_END);
337 | query_command->recursive = 1; /* Recursion is on by default. */
338 | query_command->l = 0;
339 | query_command->m = 0;
340 | query_command->q = -1;
341 | query_command->t = -1;
342 | query_command->v = -1;
343 | query_command->x = 0;
344 | query_command->fast = 0;
345 | query_command->filtered = 0;
346 | query_command->L = 0;
347 | query_command->M = 0;
348 | query_command->R = 0;
349 | query_command->S = 0;
350 |
351 | /* XXX UGLY - "all zeros" in object_type_bitmap means the same as
352 | "all ones". To limit the inconsistency, this is changed at the end
353 | of this function, so outside "all zeros" is an illegal value. */
354 | query_command->object_type_bitmap = MA_new(MA_END);
355 | /*
356 | query_command->keytypes_bitmap = MA_new(MA_END);
357 | */
358 | query_command->keys = NULL;
359 |
360 | /* This is so Marek can't crash me :-) */
361 | /* Side Effect - query keys are subsequently cut short to STR_S size. */
362 |
363 | /* tmp_query_str = (char *)UT_calloc(1, STR_S+1);
364 | strncpy(tmp_query_str, query_str, STR_S);*/
365 |
366 | /* Create the arguments. */
367 | /* This allows only a maximum of MAX_OPT_ARG_C words in the query. */
368 | /* opt_argv = g_strsplit(tmp_query_str, " ", MAX_OPT_ARG_C);*/
369 | opt_argv = g_strsplit(query_str, " ", MAX_OPT_ARG_C);
370 |
371 | /* Determine the number of arguments. */
372 | for (opt_argc=0; opt_argv[opt_argc] != NULL; opt_argc++);
373 |
374 | dieif( (gst = mg_new(0)) == NULL );
375 |
376 | while ((c = mg_getopt(opt_argc, opt_argv, "acdegi:klrmq:s:t:v:xFKLMRST:V:",
377 | gst)) != EOF) {
378 | switch (c) {
379 | case 'a':
380 | /* Remove any user specified sources from the sources list. */
381 | /* free the list only, do not touch the elements */
382 | g_list_free(qe->sources_list);
383 | qe->sources_list=NULL;
384 |
385 | /* Add all the config sources to the sources list. */
386 | {
387 | int i;
388 | ca_dbSource_t *hdl;
389 |
390 | for (i=0; (hdl = ca_get_SourceHandleByPosition(i)) != NULL; i++) {
391 | qe->sources_list = g_list_append(qe->sources_list, (void *)hdl);
392 | }
393 | }
394 |
395 |
396 | break;
397 |
398 | case 'c':
399 | query_command->c_irt_search = TRUE;
400 | break;
401 |
402 | case 'e':
403 | query_command->e=1;
404 | break;
405 |
406 | case 'd':
407 | query_command->d=1;
408 | break;
409 |
410 | case 'g':
411 | query_command->g=1;
412 | break;
413 |
414 | case 'i':
415 | if (gst->optarg != NULL) {
416 | char *hackstr = NULL;
417 |
418 | inv_attrs_str = gst->optarg;
419 | /*
420 | Now a really stupid hard-coded hack to support "pn" being a
421 | synonym for "ac,tc,zc,ah". I particularly object to this because
422 | it references attributes that should only be defined in XML - but
423 | I don't see a simplier more robust way of doing this hack.
424 | :-( - ottrey 8/12/99
425 |
426 | ** removed a memory leak - MB, 1/08/00
427 |
428 | ** removed the use of "ro", added "person" - shane, 2002-01-23
429 |
430 | */
431 | if ( strcmp(inv_attrs_str, "pn") == 0
432 | || strcmp(inv_attrs_str, "person") == 0) {
433 | hackstr = UT_strdup("ac,tc,zc,ah,cn");
434 | inv_attrs_str = hackstr;
435 | }
436 | while (*inv_attrs_str) {
437 | index = getsubopt(&inv_attrs_str, DF_get_attribute_aliases(), &value);
438 | if (index == -1) {
439 | /* Unknown attribute encountered. */
440 | char *rep = ca_get_qc_badattr ;
441 | SK_cd_puts(&(qe->condat), rep);
442 | UT_free(rep);
443 |
444 | attr = -1;
445 | badparerr++;
446 | }
447 | else {
448 | mask_t inv_attr_mask = MA_new(INV_ATTR_MASK);
449 | attr = DF_get_attribute_index(index);
450 | if ( MA_isset(inv_attr_mask, attr) == 1 ) {
451 | /* Add the attr to the bitmap. */
452 | MA_set(&(query_command->inv_attrs_bitmap), attr, 1);
453 | }
454 | else {
455 | /* "%s" is not an inverse searchable attribute. */
456 | char *rep = ca_get_qc_fmt_attrnotinv ;
457 | SK_cd_printf(&(qe->condat), rep,
458 | (DF_get_attribute_aliases())[index]);
459 | UT_free(rep);
460 | badparerr++;
461 | }
462 | }
463 | } /* while () */
464 |
465 | if( hackstr != NULL) {
466 | UT_free(hackstr);
467 | }
468 | } /* if () */
469 | break;
470 |
471 | case 'k':
472 | minusk = 1;
473 | break;
474 |
475 | case 'r':
476 | query_command->recursive=0; /* Unset recursion */
477 | break;
478 |
479 | case 'l':
480 | query_command->l=1;
481 | break;
482 |
483 | case 'm':
484 | query_command->m=1;
485 | break;
486 |
487 | case 'q':
488 | if (gst->optarg != NULL) {
489 | index = getsubopt(&gst->optarg, DF_get_server_queries(), &value);
490 | if (index == -1) {
491 | synerrflg++;
492 | }
493 | else {
494 | query_command->q = index;
495 | }
496 | } /* if () */
497 | break;
498 |
499 | case 's':
500 | if (gst->optarg != NULL) {
501 | char *token, *cursor = gst->optarg;
502 | ca_dbSource_t *handle;
503 |
504 | /* Remove any sources from the sources list. */
505 | g_list_free(qe->sources_list);
506 | qe->sources_list=NULL;
507 |
508 | /* go through specified sources */
509 | while( (token = strsep( &cursor, "," )) != NULL ) {
510 |
511 | if( (handle = ca_get_SourceHandleByName(token)) != NULL ) {
512 | /* append */
513 | qe->sources_list
514 | = g_list_append(qe->sources_list, (void *) handle );
515 | }
516 | else {
517 | /* bail out */
518 |
519 | /* Unknown source %s requested. */
520 | char *rep = ca_get_qc_fmt_badsource ;
521 | SK_cd_printf(&(qe->condat), rep, token );
522 | UT_free(rep);
523 |
524 | /* XXX error */
525 | badparerr++;
526 |
527 | } /* if handle not null */
528 | } /* while sources */
529 | } /* if argument present */
530 | break;
531 |
532 | case 't':
533 | if (gst->optarg != NULL) {
534 | object_types_str = gst->optarg;
535 | while (*object_types_str) {
536 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
537 | if (index == -1) {
538 | /* Unknown object type encountered */
539 | char *rep = ca_get_qc_badobjtype ;
540 | SK_cd_puts(&(qe->condat), rep);
541 | UT_free(rep);
542 | badparerr++;
543 | }
544 | else {
545 | type = DF_get_class_index(index);
546 | query_command->t=type;
547 | }
548 | }
549 | }
550 | break;
551 |
552 | case 'v':
553 | if (gst->optarg != NULL) {
554 | object_types_str = gst->optarg;
555 | if (*object_types_str) {
556 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
557 | if (index == -1) {
558 | /* Unknown object type encountered */
559 | char *rep = ca_get_qc_badobjtype ;
560 | SK_cd_puts(&(qe->condat), rep);
561 | UT_free(rep);
562 | badparerr++;
563 | }
564 | else {
565 | type = DF_get_class_index(index);
566 | query_command->v=type;
567 | }
568 | }
569 | }
570 | break;
571 |
572 | case 'x':
573 | query_command->x=1;
574 | break;
575 |
576 | case 'F':
577 | query_command->fast=1;
578 | query_command->recursive=0; /* implies no recursion */
579 | break;
580 |
581 | case 'K':
582 | query_command->filtered=1;
583 | query_command->recursive=0; /* implies no recursion */
584 | break;
585 |
586 | case 'L':
587 | query_command->L=1;
588 | break;
589 |
590 | case 'M':
591 | query_command->M=1;
592 | break;
593 |
594 | case 'R':
595 | query_command->R=1;
596 | break;
597 |
598 | case 'S':
599 | query_command->S=1;
600 | break;
601 |
602 | case 'T':
603 | if (gst->optarg != NULL) {
604 | /* parse the specification */
605 | object_types_str = gst->optarg;
606 | while (*object_types_str) {
607 | index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
608 | if (index == -1) {
609 | /* Unknown object type encountered */
610 | char *rep = ca_get_qc_badobjtype ;
611 | SK_cd_puts(&(qe->condat), rep);
612 | UT_free(rep);
613 | badparerr++;
614 | }
615 | else {
616 | type = DF_get_class_index(index);
617 | /* Add the type to the bitmap. */
618 | MA_set(&(query_command->object_type_bitmap), (unsigned) type, 1);
619 | }
620 | }
621 | }
622 | break;
623 |
624 | case 'V':
625 | if (qe->version != NULL) {
626 | /* free up the old client info */
627 | UT_free(qe->version);
628 | }
629 |
630 | {
631 | char *token, *cursor = gst->optarg;
632 | while( (token = strsep( &cursor, "," )) != NULL ) {
633 | if(IP_addr_e2b( & (qe->pIP), token)
634 | != IP_OK ) {
635 | /* means it was not an IP -> it was a version */
636 | qe->version = UT_strdup(token);
637 | }
638 | }
639 | }
640 | break;
641 |
642 | /* any other flag, including '?' and ':' errors */
643 | default:
644 | synerrflg++;
645 | }
646 | }
647 |
648 | /* copy the key */
649 |
650 | /* Work out the length of space needed */
651 | key_length = 1; /* for terminal '\0' */
652 | for (i=gst->optind ; i < opt_argc; i++) {
653 | /* length for the string + 1 for the '\0'+ 1 for the ' ' */
654 | if (opt_argv[i] != NULL) {
655 | key_length += strlen(opt_argv[i])+1;
656 | }
657 | }
658 | /* allocate */
659 | query_command->keys = (char *)UT_calloc(1, key_length+1);
660 |
661 | /* copy */
662 | for (i=gst->optind; i < opt_argc; i++) {
663 | strcat(query_command->keys, opt_argv[i]);
664 | if ( (i + 1) < opt_argc) {
665 | strcat(query_command->keys, " ");
666 | }
667 | }
668 |
669 | /* if no error, process the key, otherwise don't bother */
670 | if ( ! synerrflg && ! badparerr ) {
671 | /* convert the key to uppercase. */
672 | for (i=0; i <= key_length; i++) {
673 | query_command->keys[i] = toupper(query_command->keys[i]);
674 | }
675 |
676 | /* make the keytypes_bitmap. */
677 | query_command->keytypes_bitmap = WK_new(query_command->keys);
678 |
679 | /* fix the object type bitmap - turn "all zeros" into "all ones" */
680 | if( MA_bitcount(query_command->object_type_bitmap) == 0 ) {
681 | query_command->object_type_bitmap = MA_not(query_command->object_type_bitmap);
682 | }
683 |
684 | /* -d handling: if the keytype is IPv4/v6 address/prefix/range, then
685 | exclude the domains unless -d is set
686 | XXX this must be kept in sync with new types */
687 | if( query_command->d == 0
688 | && ( MA_isset(query_command->keytypes_bitmap, WK_IPADDRESS)
689 | || MA_isset(query_command->keytypes_bitmap, WK_IPRANGE )
690 | || MA_isset(query_command->keytypes_bitmap, WK_IPPREFIX )
691 | || MA_isset(query_command->keytypes_bitmap, WK_IP6PREFIX )
692 | ) ) {
693 |
694 | MA_set(&(query_command->object_type_bitmap), C_DN , 0);
695 | }
696 |
697 | /* tracing */
698 | /* log_command(tmp_query_str, query_command);*/
699 | log_command(query_str, query_command);
700 |
701 | /* "keep connection" processing:
702 | when opening connection, -k may be alone or with a query
703 | later -k must appear alone (or there must be an empty line,
704 | or an error) for the connection to close.
705 | */
706 | if( minusk ) {
707 | if( qe->k == 0 ) { /* opening */
708 | qe->k = 1;
709 | }
710 | else { /* closing, if no key; otherwise keep open */
711 | if( key_length <= 1 ) {
712 | qe->k = 0;
713 | }
714 | }
715 | }
716 |
717 | } /* if no error */
718 |
719 | /* we don't need this anymore */
720 | /* UT_free(tmp_query_str);*/
721 | UT_free(gst);
722 | g_strfreev(opt_argv);
723 |
724 | if(synerrflg > 0) { /* severe syntax error. Usage must be printed */
725 | return QC_SYNERR;
726 | }
727 | else if(badparerr > 0) { /* the requester has a clue. No Usage info */
728 | return QC_PARERR;
729 | }
730 | else {
731 | return 0;
732 | }
733 | } /* QC_fill() */
734 |
735 | /* QC_environ_new() */
736 | /*++++++++++++++++++++++++++++++++++++++
737 | Create a new query environment.
738 |
739 | More:
740 | +html+ <PRE>
741 | Authors:
742 | ottrey
743 | +html+ </PRE><DL COMPACT>
744 | +html+ <DT>Online References:
745 | +html+ <DD><UL>
746 | +html+ </UL></DL>
747 |
748 | ++++++++++++++++++++++++++++++++++++++*/
749 | Query_environ *QC_environ_new(char *ip, int sock) {
750 | Query_environ *qe;
751 |
752 | qe = (Query_environ *)UT_calloc(1, sizeof(Query_environ));
753 | qe->condat.ip = ip;
754 | qe->condat.sock = sock;
755 |
756 | /* The source is initialized to include only the deflook sources */
757 | {
758 | int i;
759 | ca_dbSource_t *hdl;
760 |
761 | for (i=0; (hdl = ca_get_SourceHandleByPosition(i)) != NULL; i++) {
762 | char *amrmrulez = ca_get_srcdeflook(hdl);
763 | if( strcmp(amrmrulez, "y")==0 ) {
764 | qe->sources_list = g_list_append(qe->sources_list, (void *)hdl);
765 | }
766 | UT_free(amrmrulez);
767 | }
768 | }
769 |
770 | return qe;
771 |
772 | } /* QC_environ_new() */
773 |
774 |
775 |
776 |
777 | /* QC_create() */
778 | /*++++++++++++++++++++++++++++++++++++++
779 | try to parse the query and fill in the QC struct, setting
780 | qc->query_type accordingly.
781 |
782 | Query_command *QC_create returns allocated structure
783 |
784 | char *input user query
785 |
786 | Query_environ *qe query environment structure
787 |
788 | Author:
789 | marek.
790 |
791 | ++++++++++++++++++++++++++++++++++++++*/
792 |
793 | Query_command *QC_create(char *input, Query_environ *qe)
794 | {
795 | Query_command *qc;
796 | /* allocate place for a copy of the input */
797 | char *copy = UT_calloc(1,strlen(input)+1);
798 | unsigned char *ci, *co;
799 | int qt;
800 | /* clean the string from junk - allow only known chars, something like
801 | tr/A-Za-z0-9\-\_\:\+\=\.\,\@\/ \n//cd;
802 |
803 | strip leading spaces too
804 | */
805 |
806 | for(ci = (unsigned char *)input; *ci != 0 && isspace(*ci); ci++) {
807 | /* EMPTY */
808 | }
809 |
810 | for(co = (unsigned char *) copy; *ci != 0; ci++) {
811 | if( strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* only those are allowed */
812 | "abcdefghijklmnopqrstuvwxyz"
813 | "0123456789-_:+=.,@/?' \n", *ci) != NULL) {
814 | *(co++) = *ci;
815 | }
816 | }
817 |
818 | /* now delete whitespace chars at the end */
819 | while( co != (unsigned char *)copy /* don't read past the beginning */
820 | && isspace(*co) ) {
821 | *co = '\0';
822 | co--;
823 | }
824 |
825 |
826 | qc = (Query_command *)UT_calloc(1, sizeof(Query_command));
827 |
828 | if ( strlen(copy) == 0) {
829 | /* An empty query (Ie return) was sent */
830 | qc->query_type = QC_EMPTY;
831 | }
832 | else { /* else <==> input_length > 0 ) */
833 | /* parse query */
834 | qt = QC_fill(copy, qc, qe);
835 |
836 | if( qt == QC_SYNERR || qt == QC_PARERR ) {
837 | qc->query_type = qt;
838 | }
839 | else {
840 | /* Update the query environment */
841 | /* qe = QC_environ_update(qc, qe); */
842 |
843 | /* Only do a query if there are keys. */
844 | if (qc->keys == NULL || strlen(qc->keys) == 0 ) {
845 | if( strlen(qc->keys) == 0
846 | && ( qc->q != -1 || qc->t != -1 || qc->v != -1 ) ) {
847 | qc->query_type = QC_TEMPLATE;
848 | }
849 | else {
850 | qc->query_type = QC_NOKEY;
851 | }
852 | }
853 | else {
854 | if ( strcmp(qc->keys, "HELP") == 0 ) {
855 | qc->query_type = QC_HELP;
856 | }
857 | /* So, a real query */
858 | else if( qc->filtered ) {
859 | qc->query_type = QC_FILTERED;
860 | }
861 | else {
862 | qc->query_type = QC_REAL;
863 | }
864 | }
865 | }
866 | }
867 |
868 | UT_free(copy);
869 |
870 | return qc;
871 | }
872 |
873 |
874 | /*++++++++++++++++++++++++++++++++++++++
875 |
876 | Get the name of the given query type code.
877 |
878 | char *QC_get_qrytype returns a pointer to an element of array of static strings
879 |
880 | qc_qtype_t qrytype query type code
881 |
882 | ++++++++++++++++++++++++++++++++++++++*/
883 |
884 | char *QC_get_qrytype(qc_qtype_t qrytype) {
885 | dieif(qrytype >= QC_TYPE_MAX);
886 |
887 | return qrytype_str[qrytype];
888 | }