modules/qc/query_command.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. qc_sources_list_to_string
  2. QC_environ_to_string
  3. QC_query_command_to_string
  4. log_command
  5. QC_environ_free
  6. QC_free
  7. QC_fill
  8. QC_environ_new
  9. QC_create
  10. QC_get_qrytype

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

/* [<][>][^][v][top][bottom][index][help] */