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.36 $
   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 errflg = 0;
 320   char *inv_attrs_str = NULL;
 321   char *object_types_str = NULL;
 322   char *sources_str = NULL;
 323   int opt_argc;
 324   gchar **opt_argv;
 325   char *value;
 326   char *tmp_query_str;
 327   int key_length;
 328   int i;
 329   int index;
 330   int type;
 331   int attr;
 332   char str_buf[STR_XL];
 333   getopt_state_t *gst = NULL;
 334   
 335   GList *first_source;
 336 
 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   query_command->object_type_bitmap = MA_new(MA_END);
 354   /*
 355   query_command->keytypes_bitmap = MA_new(MA_END);
 356   */
 357   query_command->keys = NULL;
 358 
 359   /* This is so Marek can't crash me :-) */
 360   /* Side Effect - query keys are subsequently cut short to STR_S size. */
 361 
 362   dieif( wr_calloc((void **)&tmp_query_str, 1, STR_S+1) != UT_OK);  
 363   strncpy(tmp_query_str, query_str, STR_S);
 364 
 365   /* Create the arguments. */
 366   /* This allows only a maximum of MAX_OPT_ARG_C words in the query. */
 367   opt_argv = g_strsplit(tmp_query_str, " ", MAX_OPT_ARG_C);
 368 
 369   /* Determine the number of arguments. */
 370   for (opt_argc=0; opt_argv[opt_argc] != NULL; opt_argc++);
 371 
 372   dieif( (gst = mg_new(0)) == NULL );
 373   
 374   while ((c = mg_getopt(opt_argc, opt_argv, "aegi:klrmq:s:t:v:xFKLMRST:V:", 
 375                         gst)) != EOF) {
 376     switch (c) {
 377       case 'a':
 378         /* Remove any user specified sources from the sources list. */
 379         /* free the list only, do not touch the elements */
 380         g_list_free(qe->sources_list); 
 381         qe->sources_list=NULL;
 382 
 383         /* Add all the config sources to the sources list. */
 384         {
 385           int i;
 386           ca_dbSource_t *hdl;
 387           
 388           for (i=0; (hdl = ca_get_SourceHandleByPosition(i)) != NULL; i++) {
 389             qe->sources_list = g_list_append(qe->sources_list, (void *)hdl);
 390           }
 391         }
 392 
 393 
 394       break;
 395 
 396       case 'e':
 397         query_command->e=1;
 398       break;
 399 
 400       case 'g':
 401         query_command->g=1;
 402       break;
 403 
 404       case 'i':
 405         if (gst->optarg != NULL) {
 406           char *hackstr = NULL;
 407 
 408           inv_attrs_str = gst->optarg;
 409           /* Now a really stupid hard-coded hack to support "pn" being a synonym for "ac,tc,zc,ah" */
 410           /* I particularly object to this because it references attributes that should only be 
 411              defined in XML - but I don't see a simplier more robust way of doing this hack.
 412              :-( - ottrey 8/12/99 
 413              ** removed a memory leak - MB, 1/08/00
 414              */
 415           if (   strcmp(inv_attrs_str, "pn") == 0 
 416               || strcmp(inv_attrs_str, "ro") == 0) {
 417             wr_malloc( (void **)& hackstr, 24);
 418             strcpy(hackstr, "ac,tc,zc,ah");
 419             inv_attrs_str = hackstr;
 420           }
 421           while (*inv_attrs_str) {
 422             index = getsubopt(&inv_attrs_str, DF_get_attribute_aliases(), &value);
 423             if (index == -1) {
 424               attr = -1;
 425               strcpy(str_buf, "");
 426               sprintf(str_buf, "Unknown attribute encountered.\n"); 
 427               SK_cd_puts(&(qe->condat), str_buf);
 428               errflg++;
 429             }
 430             else {
 431               mask_t inv_attr_mask = MA_new(INV_ATTR_MASK);
 432               attr = DF_get_attribute_index(index);
 433               if ( MA_isset(inv_attr_mask, attr) == 1 ) {
 434                 /* Add the attr to the bitmap. */
 435                 MA_set(&(query_command->inv_attrs_bitmap), attr, 1);
 436               }
 437               else {
 438                 strcpy(str_buf, "");
 439                 sprintf(str_buf, "\"%s\" does not belong to inv_attr.\n", (DF_get_attribute_aliases())[index]); 
 440                 SK_cd_puts(&(qe->condat), str_buf);
 441                 errflg++;
 442               }
 443             } 
 444           } /* while () */
 445 
 446           if( hackstr != NULL) {
 447             wr_free(hackstr);
 448           }
 449         } /* if () */
 450       break;
 451 
 452       case 'k':
 453         /* triggering flag == a XOR operation */
 454         qe->k ^= 1;
 455       break;
 456 
 457       case 'r':
 458         query_command->recursive=0;       /* Unset recursion */
 459       break;
 460 
 461       case 'l':
 462         query_command->l=1;
 463       break;
 464 
 465       case 'm':
 466         query_command->m=1;
 467       break;
 468 
 469       case 'q':
 470         if (gst->optarg != NULL) {
 471           index = getsubopt(&gst->optarg, DF_get_server_queries(), &value);
 472           if (index == -1) {
 473             errflg++;
 474           }
 475           else {
 476             query_command->q = index;
 477           } 
 478         } /* if () */
 479       break;
 480 
 481       case 's':
 482         if (gst->optarg != NULL) {
 483           char *token, *cursor = gst->optarg;
 484           ca_dbSource_t *handle;
 485           
 486           /* Remove any sources from the sources list. */
 487           g_list_free(qe->sources_list); 
 488           qe->sources_list=NULL;
 489           
 490           /* go through specified sources */
 491           while( (token = strsep( &cursor, "," )) != NULL ) {
 492             
 493             if( (handle = ca_get_SourceHandleByName(token)) != NULL ) {
 494               /* append */
 495               qe->sources_list 
 496                 = g_list_append(qe->sources_list, (void *) handle );
 497             }
 498             else {
 499               /* bail out */
 500               strcpy(str_buf, "");
 501               sprintf(str_buf, "Unknown source %s encountered.\n",token ); 
 502               SK_cd_puts(&(qe->condat), str_buf);
 503               
 504               /* XXX error */
 505               errflg++;
 506               
 507             } /* if handle not null */
 508           } /* while sources */
 509         } /* if argument present */
 510         break;
 511         
 512       case 't':
 513         if (gst->optarg != NULL) {
 514           object_types_str = gst->optarg;
 515           while (*object_types_str) {
 516             index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
 517             if (index == -1) {
 518               strcpy(str_buf, "");
 519               sprintf(str_buf, "Unknown object encountered.\n"); 
 520               SK_cd_puts(&(qe->condat), str_buf);
 521               errflg++;
 522             }
 523             else {
 524               type = DF_get_class_index(index);
 525               query_command->t=type;
 526             }
 527           }
 528         }
 529       break;
 530 
 531       case 'v':
 532         if (gst->optarg != NULL) {
 533           object_types_str = gst->optarg;
 534           if (*object_types_str) {
 535             index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
 536             if (index == -1) {
 537               strcpy(str_buf, "");
 538               sprintf(str_buf, "Unknown object encountered.\n"); 
 539               SK_cd_puts(&(qe->condat), str_buf);
 540               errflg++;
 541             }
 542             else {
 543               type = DF_get_class_index(index);
 544               query_command->v=type;
 545             }
 546           }
 547         }
 548       break;
 549 
 550       case 'x':
 551         query_command->x=1;
 552       break;
 553 
 554       case 'F':
 555         query_command->fast=1;
 556         query_command->recursive=0; /* implies no recursion */
 557       break;
 558 
 559       case 'K':
 560         query_command->filtered=1;
 561         query_command->recursive=0; /* implies no recursion */
 562       break;
 563 
 564       case 'L':
 565         query_command->L=1;
 566       break;
 567 
 568       case 'M':
 569         query_command->M=1;
 570       break;
 571 
 572       case 'R':
 573         query_command->R=1;
 574       break;
 575 
 576       case 'S':
 577         query_command->S=1;
 578       break;
 579 
 580       case 'T':
 581         if (gst->optarg != NULL) {
 582           object_types_str = gst->optarg;
 583           while (*object_types_str) {
 584             index = getsubopt(&object_types_str, DF_get_class_aliases(), &value);
 585             if (index == -1) {
 586               strcpy(str_buf, "");
 587               sprintf(str_buf, "Unknown class encountered.\n"); 
 588               SK_cd_puts(&(qe->condat), str_buf);
 589               errflg++;
 590             }
 591             else {
 592               type = DF_get_class_index(index);
 593               /* Add the type to the bitmap. */
 594               MA_set(&(query_command->object_type_bitmap), type, 1);
 595             }
 596           }
 597         }
 598       break;
 599 
 600       case 'V':
 601         if (qe->version != NULL) {
 602           /* free up the old client info */
 603           wr_free(qe->version);
 604         }
 605         
 606         {
 607           char *token, *cursor = gst->optarg;
 608           while( (token = strsep( &cursor, "," )) != NULL ) {
 609             if(IP_addr_e2b( & (qe->pIP), token) 
 610                != IP_OK ) {
 611               /* means it was not an IP -> it was a version */
 612               dieif( wr_malloc( (void **)&(qe->version), 
 613                                 strlen(token)+1) != UT_OK);  
 614               strcpy(qe->version, token);
 615             }
 616           }
 617         }
 618       break;
 619 
 620       /* any other flag, including '?' and ':' errors */
 621       default:
 622         errflg++;
 623     }
 624   }
 625 
 626   /* copy the key */
 627 
 628   /* Work out the length of space needed */
 629   key_length = 1; /* for terminal '\0' */
 630   for (i=gst->optind ; i < opt_argc; i++) {
 631     /* length for the string + 1 for the '\0'+ 1 for the ' ' */
 632     if (opt_argv[i] != NULL) {
 633       key_length += strlen(opt_argv[i])+1;
 634     }
 635   }
 636   /* allocate */
 637   dieif( wr_calloc((void **)&(query_command->keys), 1, key_length+1) != UT_OK);  
 638   /* copy */
 639   for (i=gst->optind; i < opt_argc; i++) {
 640     strcat(query_command->keys, opt_argv[i]);
 641     if ( (i + 1) < opt_argc) {
 642       strcat(query_command->keys, " ");
 643     }
 644   }
 645     
 646   /* if no error, process the key, otherwise don't bother */
 647   if ( ! errflg ) { 
 648     /* convert the key to uppercase. */
 649     for (i=0; i <= key_length; i++) {
 650       query_command->keys[i] = toupper(query_command->keys[i]);
 651     }
 652     
 653     /* make the keytypes_bitmap. */
 654     query_command->keytypes_bitmap = WK_new(query_command->keys);
 655     
 656     /* tracing */
 657     if ( CO_get_comnd_logging() == 1 ) {
 658       log_command(tmp_query_str, query_command);
 659     }
 660   } /* if no error */
 661 
 662   /* we don't need this anymore */
 663   wr_free(tmp_query_str);
 664   wr_free(gst);
 665 
 666   return (errflg) ? -1 : 0; /* return -1 on error */
 667 
 668 } /* QC_fill() */
 669 
 670 /* QC_environ_new() */
 671 /*++++++++++++++++++++++++++++++++++++++
 672   Create a new query environment.
 673 
 674   More:
 675   +html+ <PRE>
 676   Authors:
 677         ottrey
 678   +html+ </PRE><DL COMPACT>
 679   +html+ <DT>Online References:
 680   +html+ <DD><UL>
 681   +html+ </UL></DL>
 682 
 683   ++++++++++++++++++++++++++++++++++++++*/
 684 Query_environ *QC_environ_new(char *ip, unsigned sock) {
     /* [<][>][^][v][top][bottom][index][help] */
 685   Query_environ *qe;
 686 
 687 
 688   dieif( wr_calloc((void **)&qe, 1, sizeof(Query_environ)+1 ) != UT_OK);  
 689   qe->condat.ip = ip;
 690   qe->condat.sock = sock;
 691 
 692   /* The source is initialized to include only the deflook sources */
 693   {
 694     int i;
 695     ca_dbSource_t *hdl;
 696     
 697     for (i=0; (hdl = ca_get_SourceHandleByPosition(i)) != NULL; i++) {
 698       if( ca_get_srcdeflook(hdl) ) {
 699         qe->sources_list = g_list_append(qe->sources_list, (void *)hdl);
 700       }
 701     }
 702   }
 703   
 704   return qe;
 705 
 706 } /* QC_environ_new() */
 707 
 708 
 709 
 710 /*++ QC_create()
 711   
 712   try to parse the query and fill in the QC struct, setting 
 713   qc->query_type accordingly.
 714  
 715   by marek.
 716 ++++++++++++++++++++++++++++++++++++++*/
 717 Query_command *QC_create(char *input, Query_environ *qe)
     /* [<][>][^][v][top][bottom][index][help] */
 718 {
 719   Query_command *qc;
 720   /* allocate place for a copy of the input */
 721   char *copy = calloc(1,strlen(input)+1); 
 722   char *ci, *co;
 723   /* clean the string from junk - allow only known chars, something like
 724      tr/A-Za-z0-9\-\_\:\+\=\.\,\@\/ \n//cd; 
 725   */
 726 
 727   dieif(copy == NULL);
 728   
 729   for(ci = input, co = copy; *ci != 0; ci++) {
 730     if( strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ"     /* only those are allowed */
 731                "abcdefghijklmnopqrstuvwxyz"
 732                "0123456789-_:+=.,@/' \n", *ci) != NULL) {
 733       *(co++) = *ci;
 734     }
 735   }
 736 
 737   /* now delete whitespace chars at the end */
 738   co--;
 739   while( isspace(*co) ) {
 740     *co = '\0';
 741     co--;
 742   }
 743 
 744 
 745   dieif( wr_calloc((void **)&qc, 1, sizeof(Query_command)+1) != UT_OK);
 746   
 747   if ( strlen(copy) == 0) {
 748     /* An empty query (Ie return) was sent */
 749     qc->query_type = QC_EMPTY;
 750   } 
 751   else {        /* else <==> input_length > 0 ) */
 752     /* parse query */
 753     
 754     if( QC_fill(copy, qc, qe) < 0 ) {
 755       qc->query_type = QC_ERROR;
 756     }
 757     else {
 758       /* Update the query environment */
 759       /* qe = QC_environ_update(qc, qe); */
 760 
 761       /* Only do a query if there are keys. */
 762       if (qc->keys == NULL || strlen(qc->keys) == 0 ) {
 763         if( strlen(qc->keys) == 0 
 764             && ( qc->q != -1 || qc->t != -1 || qc->v != -1 ) ) {
 765           qc->query_type = QC_TEMPLATE;
 766         }
 767         else {
 768           qc->query_type = QC_NOKEY;
 769         }
 770       }
 771       else {
 772         if ( strcmp(qc->keys, "HELP") == 0 ) {
 773           qc->query_type = QC_HELP;
 774         }
 775         /* So, a real query */
 776         else if( qc->filtered ) {
 777           qc->query_type = QC_FILTERED;
 778         }
 779         else {
 780           qc->query_type = QC_REAL;
 781         }
 782       }
 783     }
 784   }
 785 
 786   free(copy);
 787 
 788   return qc;
 789 }
 790 
 791 
 792 char *QC_get_qrytype(qc_qtype_t qrytype) {
     /* [<][>][^][v][top][bottom][index][help] */
 793   dieif(qrytype >= QC_TYPE_MAX);
 794 
 795   return qrytype_str[qrytype];
 796 }

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