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