modules/up/UP_util.cc

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

FUNCTIONS

This source file includes following functions.
  1. authorise
  2. error_msg_cat
  3. interpret_ripdb_result
  4. get_assigned_nic
  5. send_object_db
  6. get_type
  7. get_search_key
  8. send_and_get
  9. count_objects
  10. strip_lines
  11. take_objects
  12. take_object
  13. get_as_block
  14. get_aut_num_object
  15. get_less_specific_domain
  16. get_less_specific_set
  17. get_less_specific
  18. get_less_spec_inetnum
  19. get_exact_match_inetnum
  20. get_exact_match_routes
  21. get_less_spec_routes
  22. get_mntners
  23. get_attributes
  24. get_attribute
  25. strstr_in_list
  26. get_auths
  27. get_attr_list
  28. get_mnt_lowers
  29. get_mnt_routes
  30. get_mnt_routes_from_list
  31. get_mnt_lowers_from_list
  32. get_override
  33. check_override
  34. add_to_auth_vector
  35. get_auth_vector
  36. get_mntnfy_vector
  37. get_updto_vector
  38. filter_out_diff_origins
  39. check_auth
  40. get_old_version
  41. process_mail_header
  42. stringPack
  43. delete_delete_attrib
  44. identical
  45. find_initials
  46. get_combination_from_autonic
  47. replace_AUTO_NIC_hdl
  48. replace_AUTO_NIC_hdl
  49. replace_refs_to_AUTO_NIC_hdl
  50. has_AUTO_NIC_hdl
  51. has_ref_to_AUTO_nic_hdl
  52. process_object
  53. find_to_address

   1 /***************************************
   2   $Revision: 1.29 $
   3 
   4   UP module utilities
   5 
   6   Status: NOT REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (17/01/2000) Created.
  13   ******************/ /******************
  14   Copyright (c) 2000                              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 #include "dbupdate.h" 
  35 
  36 int error = 0; // a global variable to store the errors
  37 char * error_msg = NULL; // a global variable to store the error messages
  38 extern int tracing;
  39 extern char * overridecryptedpw;
  40 extern int test_mode;
  41 
  42 /* authorise function takes the auth_vector, credentials struct, and 'overriden'
  43    variable. If overriden == 1, then it immediately returns UP_AUTH_OK 
  44    (because this means that the update contained a valid override attribute).
  45    Else, it goes through the auth_vector and when it finds a an "auth:"
  46    attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
  47    UP_AUF (authorisation failed) */
  48    
  49 int authorise(GSList * auth_vector, credentials_struct credentials, int overriden){
     /* [<][>][^][v][top][bottom][index][help] */
  50 
  51   int result = 0;
  52 
  53   if(tracing){
  54     printf("TRACING: authorise started with override: %i\n", overriden);
  55   }
  56     
  57   /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
  58   if(overriden == 1){
  59     return UP_AUTH_OK;
  60   }
  61   else{
  62     result = AU_authorise(auth_vector, credentials);
  63     if(tracing){
  64       printf("TRACING: authorise: AU_authorise returned %i\n", result);
  65     }
  66     if(result > 0){
  67       return UP_AUTH_OK;
  68     }
  69     else{
  70       return UP_AUF; /* authorisation failed */
  71     }
  72   }
  73 }
  74 
  75 /* concatanates the string at the end of error_msg */
  76 void error_msg_cat(const char * string){
     /* [<][>][^][v][top][bottom][index][help] */
  77 
  78   if(string == NULL){
  79     return;
  80   }
  81   if(error_msg == NULL){
  82     error_msg = strdup(string);
  83   }else{
  84     error_msg = (char *)realloc(error_msg, strlen(error_msg) + strlen(string) + 2);
  85     error_msg = strcat(error_msg, "\n");
  86     error_msg = strcat(error_msg, string); 
  87   }
  88 }
  89 
  90 
  91 /* interprets the result string coming from RIPupd
  92    It is called by send_object_db.
  93    It returns the error no returned from RIPupd.  */
  94    
  95 int interpret_ripdb_result(const char * string){
     /* [<][>][^][v][top][bottom][index][help] */
  96    char * error_no = NULL;
  97    char ** temp = NULL, ** temp2 = NULL;
  98    int i;
  99    int err = 0;
 100      
 101   /* if the string is NULL or empty, then return error */
 102   if(string == NULL || strlen(string) == 0){
 103     error = UP_INT; /* internal error, RIPupd should return something */
 104     error_msg_cat("Internal error. RIPupd didn't return anything.");
 105     return 0; 
 106   }
 107 
 108   /* split the string into lines */
 109   temp = g_strsplit(string , "\n", 0);
 110   for(i = 0; temp[i] != NULL; i++){
 111     if(i == 0){/* this line must contain "%ERROR " string in the beginning */
 112       temp2 = g_strsplit(temp[0], " ", 0);
 113       error_no = strdup(temp2[1]);
 114       g_strfreev(temp2);
 115       err = atoi(error_no);
 116       if(tracing){
 117         printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
 118       }
 119     }else if(error_no != NULL && strcmp(error_no, "0") != 0){
 120       error_msg_cat(temp[i]);
 121     }
 122   }
 123   g_strfreev(temp);
 124   //if(error_no != NULL && error_msg != NULL){
 125   //  printf("TRACING: interpret_ripdb_result: Error: [%s][%s]\n", error_no, error_msg);  
 126   //}
 127   if(error_no != NULL){
 128     free(error_no);
 129   }
 130   return err; /* 0 means no error in this context */
 131 }
 132 
 133 
 134 
 135 /* Gets assigned NIC hdl from the string that is returned from 
 136    RIPupdate */
 137 void get_assigned_nic(char * nic_hdl, const char * string){
     /* [<][>][^][v][top][bottom][index][help] */
 138    char * error_no = NULL;
 139    char ** temp = NULL, ** temp2 = NULL;
 140    int i;
 141    //char * to_be_returned = NULL;
 142      
 143   /* if the string is NULL or empty, then return error */
 144   if(string == NULL || strlen(string) == 0){
 145     error = UP_INT; /* internal error, RIPupd should return something */
 146     error_msg_cat("Internal error. RIPupd didn't return anything.");
 147     return; 
 148   }
 149 
 150   /* split the string into lines */
 151   temp = g_strsplit(string , "\n", 0);
 152   for(i = 0; temp[i] != NULL; i++){
 153     if(i == 0){/* this line must contain "%ERROR " string in the beginning */
 154       temp2 = g_strsplit(temp[0], " ", 0);
 155       error_no = strdup(temp2[1]);
 156       g_strfreev(temp2);
 157       printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
 158     }else if(error_no != NULL && strcmp(error_no, "0") != 0){
 159       error_msg_cat(temp[i]);
 160     }else if(error_no != NULL && strcmp(error_no, "0") == 0 && i == 1){/* look for assigned NIC hdl */
 161       printf("error_no != NULL && strcmp(error_no, \"0\") == 0 && i == 1\n");
 162       /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
 163          need to extract EK3-RIPE part */
 164       //to_be_returned = (char *)malloc(128); /* 128 should be enough for a NIC hdl */
 165       nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,  
 166                                  rindex(temp[i],']') - rindex(temp[i],'[') - 1);
 167       nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
 168       if(nic_hdl != NULL){
 169         printf("DEBUG: get_assigned_nic will return [%s]\n", nic_hdl);
 170       }
 171       g_strfreev(temp);
 172       //return to_be_returned;
 173       return;
 174     }
 175   }
 176   g_strfreev(temp);
 177   if(error_no != NULL && error_msg != NULL){
 178     printf("TRACING: interpret_ripdb_result: Error: [%s][%s]\n", error_no, error_msg);  
 179   }
 180   return;
 181 }
 182 
 183 
 184 
 185 /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
 186    assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl 
 187    assigned_NIC must be allocated enough memory before send_object_db is called 
 188    
 189    If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
 190    */
 191 int send_object_db(char * arg, char * assigned_NIC, char * operation){
     /* [<][>][^][v][top][bottom][index][help] */
 192 
 193         int sockfd, numbytes;  
 194         char buf[MAXDATASIZE];
 195         struct hostent *he;
 196         struct sockaddr_in their_addr; /* connector's address information */
 197         char *result_string = NULL;
 198         char *to_be_returned = NULL;
 199         int err = 0;
 200 
 201 
 202         if ((he=gethostbyname(UPDATE_HOST)) == NULL) {  /* get the host info */
 203             perror("gethostbyname");
 204             exit(1);
 205         }
 206 
 207         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 208             perror("socket");
 209             exit(1);
 210         }
 211 
 212         their_addr.sin_family = AF_INET;      /* host byte order */
 213         their_addr.sin_port = htons(UPDATE_PORT);    /* short, network byte order */
 214         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 215         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 216 
 217 
 218         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 219                                               sizeof(struct sockaddr)) == -1) {
 220             perror("connect");
 221             exit(1);
 222         }
 223 
 224         if (send(sockfd, operation , strlen(operation), 0) == -1)
 225             perror("send");
 226         if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
 227             perror("send");
 228         if (send(sockfd, arg , strlen(arg), 0) == -1)
 229             perror("send");
 230         if (send(sockfd, "\n\n",2,0)  == -1)
 231             perror("send");
 232 
 233 
 234         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
 235             buf[numbytes] = '\0';
 236             printf("%s",buf);
 237             if(result_string == NULL){
 238               result_string = strdup(buf);
 239             }else{
 240               result_string = (char *)realloc(result_string, 
 241                                  strlen(result_string) + strlen(buf) + 1);
 242               result_string = strcat(result_string, buf);
 243             }
 244         }
 245 
 246         err = interpret_ripdb_result(result_string);
 247         if(assigned_NIC != NULL){ /* if the caller of the function expected to get a NIC handle */
 248           get_assigned_nic(assigned_NIC, result_string);
 249         }
 250         close(sockfd);
 251         return err; /* 0 means no error in this context */ 
 252 }
 253 
 254 
 255 
 256 
 257 
 258 
 259 /* takes a pre-parsed object, and returns its type */
 260 char * get_type(Object *arg){
     /* [<][>][^][v][top][bottom][index][help] */
 261     
 262     char * be_returned = NULL;
 263     if(arg == NULL) return NULL;
 264     be_returned = strdup(arg->type->getName());  
 265     return g_strstrip(be_returned);
 266 }
 267 
 268 
 269 
 270 
 271 
 272 
 273 /* takes an object (pre-parsed) and returns its first attrib if it is not
 274    a person, and returns the nic-hdl if it is a person object */
 275 char * get_search_key(Object *arg, char * type, const char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 276 
 277     
 278     Attr *attr;    
 279     char *primary_key = NULL, *value = NULL;
 280 
 281     if(arg == NULL) return NULL;
 282 
 283     for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
 284        value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 285        strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 286            attr->len - strlen(attr->type->name()) -2 );
 287            value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 288        //cout << "value: #" << value << "#" << endl;
 289        if(strcmp(attr->type->name(),type) == 0 &&
 290               strcmp(type,"person") != 0 && strcmp(type,"role") != 0  ){
 291          primary_key = strdup(value);
 292        }
 293        if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
 294             (strcmp(type,"person") == 0 || strcmp(type,"role") == 0 )){
 295          primary_key = strdup(value);
 296        }
 297     }
 298     if(primary_key != NULL){ 
 299       return g_strstrip(primary_key);
 300     }else{
 301       return NULL;
 302     }
 303 }
 304 
 305 
 306 
 307 
 308 /* sends char * arg to the specified host's specified port, and
 309    returns the reply as a string. This is used to query the
 310    whois host. Probably we must use WC (whois client) module here,
 311    but it must be extented */
 312 char * send_and_get(char * host, int port, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 313 
 314         int sockfd, numbytes; 
 315         char * result = NULL; 
 316         char buf[MAXDATASIZE];
 317         struct hostent *he;
 318         struct sockaddr_in their_addr; /* connector's address information */
 319   
 320         if(tracing) { 
 321           printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
 322         }
 323 
 324         if ((he=gethostbyname(host)) == NULL) {  /* get the host info */
 325             perror("gethostbyname");
 326             exit(1);
 327         }
 328 
 329         if(tracing) { 
 330           printf("TRACING: send_and_get: called gethostbyname\n");
 331         }
 332 
 333         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 334             perror("socket");
 335             exit(1);
 336         }
 337 
 338         if(tracing) { 
 339           printf("TRACING: send_and_get: called socket\n");
 340         }
 341 
 342 
 343         their_addr.sin_family = AF_INET;      /* host byte order */
 344         their_addr.sin_port = htons(port);    /* short, network byte order */
 345         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 346         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 347 
 348         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 349                                               sizeof(struct sockaddr)) == -1) {
 350             perror("connect");
 351             exit(1);
 352         }
 353         if (send(sockfd, arg , strlen(arg), 0) == -1)
 354                perror("send");
 355         if (send(sockfd, "\n",1,0)  == -1)
 356                perror("send");
 357 
 358 
 359         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
 360             buf[numbytes] = '\0';
 361             if(result == NULL){
 362               result = strdup(buf);
 363             }else{
 364               result = (char *)realloc(result, strlen(result) + strlen(buf));
 365               result = strcat(result, buf);
 366             }
 367         }
 368 
 369         close(sockfd);
 370         return result;
 371 
 372 
 373 }
 374 
 375 /* counts the number of objects in a string */
 376 int count_objects(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 377     int count = 0;
 378     char *pos = NULL;
 379     char *temp = NULL;
 380 
 381     if(tracing) {
 382       printf("TRACING: count_objects running\n");
 383     }
 384     
 385     if(arg != NULL){
 386       temp = strdup(arg);
 387     }else{
 388       return 0;
 389     }
 390     
 391     if(isalpha(arg[0])){
 392       count++;
 393     }else if(arg[0] == '\n' && isalpha(arg[1])){
 394       count++;
 395     }
 396     while(pos = strstr(temp,"\n\n")){
 397       pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
 398       if(isalpha(pos[2])){
 399         count++;
 400       }
 401     }
 402     if(tracing) {
 403       cout << "TRACING: count_objects returning " << count << endl;
 404     }
 405     return count;
 406 }
 407 
 408 
 409 /* strips lines beginning with '%' off  */
 410 char * strip_lines(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 411 
 412     char ** temp = NULL;
 413     char * string = NULL;
 414     int i;
 415 
 416     if(arg == NULL){
 417        return NULL;
 418     }
 419 
 420     /* split the string into lines */
 421     temp = g_strsplit (arg, "\n", 0);
 422 
 423     for(i=0; temp[i] != NULL; i++){
 424       if(temp[i][0] != '%'){
 425         if(string == NULL){
 426           string = strdup(temp[i]);
 427         }else{
 428           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 1);
 429           string = strcat(string, "\n");
 430           string = strcat(string, temp[i]);
 431         }
 432       }
 433     }
 434     return string;
 435 }
 436 
 437 /* Separates the objects in the given char * arg using "\n\n" as
 438    separator. Returns a linked list whose data consist of separated
 439    objects as  char *  */
 440 
 441 GSList * take_objects(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 442     char ** objects=NULL;
 443     char ** temp = NULL;
 444     GSList * tobereturned = NULL;
 445     int i;
 446 
 447     arg = strip_lines(arg);
 448 
 449     objects =  g_strsplit(arg, "\n\n", 1000);
 450     temp = objects;
 451     for(i=0; temp[i] != NULL; i++){
 452       /* stripe off the trailing and leading white spaces-eols*/
 453       g_strstrip(temp[i]);
 454       if(strlen(temp[i]) > 0){/* if not an empty string */
 455         tobereturned = g_slist_append(tobereturned, temp[i]);
 456       }
 457     }
 458     return tobereturned;
 459 }
 460 
 461 
 462 
 463 
 464 
 465 /* takes the first object in the given char *, using empty lines as
 466    separator */
 467 char * take_object(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 468     char * object = NULL, * pos = NULL;
 469     char * temp = strdup(arg);
 470     
 471     if(isalpha(temp[0])){
 472       if(strstr(temp,"\n\n") == NULL){
 473         return temp;
 474       }else{
 475         pos = strstr(temp,"\n\n");
 476         pos[0] = '\0';
 477         return temp;
 478       }
 479     }else if(temp[0] == '\n' && isalpha(temp[1])){
 480       if(strstr(temp,"\n\n") == NULL){
 481         return (char *)temp[1];
 482       }else{
 483         pos = strstr(temp,"\n\n");
 484         pos[0] = '\0';
 485         return (char *)temp[1];
 486       }
 487     }else{
 488       temp = strstr(temp,"\n\n");
 489       temp = temp + 2;
 490       if(strstr(temp,"\n\n") == NULL){
 491         return temp;
 492       }else{
 493         pos = strstr(temp,"\n\n");
 494         pos[0] = '\0';
 495         return temp;
 496       }
 497     }
 498 }
 499 
 500 
 501 
 502 
 503 
 504 /* Takes an autnum_object, and returns the as-block containing this aut-num */
 505 char * get_as_block(char *autnum_object){
     /* [<][>][^][v][top][bottom][index][help] */
 506   bool code;
 507   char * search_key = NULL, * query_string = NULL;
 508   char * result = NULL;
 509   Object * o = new Object();
 510   
 511   code = o->scan(autnum_object, strlen(autnum_object));
 512   search_key = get_search_key(o,"aut-num",autnum_object);
 513   
 514   query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
 515   sprintf(query_string, "-Tas-block -r %s",search_key);
 516   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 517   if(count_objects(result) == 0){
 518     cout << "No such as-block" << endl;
 519     return NULL;
 520   }else if(count_objects(result) > 1){
 521     cout << "More than one as-block returned" << endl;
 522     return NULL;
 523   }else{ /* count_objects(result) == 1 */
 524     return take_object(result);
 525   }
 526   
 527 }
 528 
 529 
 530 /* Takes a route_object, and returns the aut-num mentioned in origin
 531    attribute of this route */
 532 char * get_aut_num_object(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 533   bool code;
 534   char * search_key = NULL, * query_string = NULL;
 535   char * result = NULL;
 536   Object * o = new Object();
 537   
 538   code = o->scan(route_object, strlen(route_object));
 539   search_key = get_search_key(o,"origin",route_object);
 540   
 541   query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
 542   sprintf(query_string, "-Taut-num -r %s",search_key);
 543   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 544   if(count_objects(result) == 0){
 545     cout << "No such aut-num" << endl;
 546     return NULL;
 547   }else if(count_objects(result) > 1){
 548     cout << "More than one aut-num returned" << endl;
 549     return NULL;
 550   }else{ /* count_objects(result) == 1 */
 551     return take_object(result);
 552   }
 553   
 554 }
 555 
 556 
 557 
 558 
 559 /* Takes a domain_object, and returns the less specific domain of it */
 560 char * get_less_specific_domain(char *domain_object){
     /* [<][>][^][v][top][bottom][index][help] */
 561   bool code;
 562   char * search_key = NULL, * query_string = NULL;
 563   char * result = NULL, * domain = NULL;
 564   Object * o = new Object();
 565   int i,j, length;
 566   char * temp = NULL;
 567   char ** splitted;
 568 
 569   code = o->scan(domain_object, strlen(domain_object));
 570   domain = get_search_key(o,"domain",domain_object);
 571 
 572   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
 573   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
 574 
 575   for(i=1; splitted[i] != NULL; i++){
 576     /* in the following for loop, we will construct the 'less spec' domains
 577        to be looked up in the DB */ 
 578     for(j=i; splitted[j] !=NULL; j++){
 579       length = 0;
 580       if(temp!=NULL){
 581         length = strlen(temp); 
 582       }
 583       temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2); 
 584       if(j==i){
 585         temp = (char *)strdup(splitted[j]);
 586       }else{
 587         sprintf(temp, "%s.%s", temp, splitted[j]);
 588       }
 589     }
 590     query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
 591     sprintf(query_string, "-Tdomain -r -R %s", temp);
 592     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 593     if(count_objects(result) == 0){
 594     }else if(count_objects(result) > 1){
 595       if(tracing){
 596         cout << "TRACING: get_less_specific_domain: More than one domains returned" << endl;
 597       }
 598       return NULL; /* error condition */
 599     }else{ /* count_objects(result) == 1 */
 600       return take_object(result);
 601     }
 602     
 603   }
 604   /* release the memory allocated to **splitted */
 605   for(i=0; splitted[i] != NULL; i++){ 
 606     free(splitted[i]);
 607   }  
 608   /* so, we couldn't  find any 'less specific' domain */
 609   return NULL;
 610 }
 611 
 612 
 613 
 614 
 615 
 616 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
 617    by striping down the object's name ( eg, for as35:rs-trial:rs-myset, 
 618    as35:rs-trial is tried ) */
 619 char * get_less_specific_set(char *set_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 620   bool code;
 621   char * search_key = NULL, * query_string = NULL;
 622   char * result = NULL;
 623   Object * o = new Object();
 624   int i;
 625   
 626   code = o->scan(set_object, strlen(set_object));
 627   search_key = get_search_key(o, type, set_object);
 628   delete(o);
 629 
 630   for(i = strlen(search_key) -1; i > -1; i--){
 631     if(search_key[i] == ':'){
 632       search_key[i] = '\0'; /* truncate the string */
 633       break;
 634     }
 635     if(i == 0){/* if we've reached the beginning of the string 
 636                 (this means there wasn't any ';' in the string) */
 637       free(search_key);
 638       search_key = NULL;
 639     }
 640   }
 641   if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since 
 642                                                         we make sure that the name of the 
 643                                                         set_object contains a ':' in a proper place */
 644     return NULL;
 645   }
 646 
 647    
 648   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
 649   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r  %s", search_key);
 650   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 651   if(count_objects(result) == 0){
 652     cout << "No such object"  << endl;
 653     return NULL;
 654   }else if(count_objects(result) > 1){
 655     cout << "More than one objects returned" << endl;
 656     return NULL;
 657   }else{ // count_objects(result) == 1
 658     return take_object(result);
 659   }
 660   
 661 }
 662 
 663 
 664 
 665 
 666 
 667 
 668 
 669 /* Takes an inetnum or inet6num object and returns one less specific of it */
 670 char * get_less_specific(char *inetnum_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 671   bool code;
 672   char * search_key = NULL, * query_string = NULL;
 673   char * result = NULL;
 674   Object * o = new Object();
 675   
 676   code = o->scan(inetnum_object, strlen(inetnum_object));
 677   search_key = get_search_key(o, type, inetnum_object);
 678   
 679   query_string = (char *)malloc(strlen("-Tinet6num -r -l ") + strlen(search_key) + 1);
 680   sprintf(query_string, "-T%s -r -l %s",type, search_key);
 681   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 682   if(count_objects(result) == 0){
 683     cout << "No such " << type << endl;
 684     return NULL;
 685   }else if(count_objects(result) > 1){
 686     cout << "More than one " << type << " returned" << endl;
 687     return NULL;
 688   }else{ /* count_objects(result) == 1 */
 689     return take_object(result);
 690   }
 691   
 692 }
 693 
 694 
 695 
 696 /* Takes a route object and returns one less specific inetnum */
 697 char * get_less_spec_inetnum(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 698   bool code;
 699   char * search_key = NULL, * query_string = NULL;
 700   char * result = NULL;
 701   Object * o = new Object();
 702   
 703   code = o->scan(route_object, strlen(route_object));
 704   search_key = get_search_key(o, "route", route_object);
 705   
 706   query_string = (char *)malloc(strlen("-Tinetnum -r -l ") + strlen(search_key) + 1);
 707   sprintf(query_string, "-Tinetnum -r -l %s", search_key);
 708   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 709   if(count_objects(result) == 0){
 710     cout << "No such inetnum" << endl;
 711     return NULL;
 712   }else if(count_objects(result) > 1){
 713     cout << "More than one inetnums returned" << endl;
 714     return NULL;
 715   }else{ /* count_objects(result) == 1 */
 716     return take_object(result);
 717   }
 718   
 719 }
 720 
 721 
 722 /* Takes a route object and returns exact match inetnum */
 723 char * get_exact_match_inetnum(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 724   bool code;
 725   char * search_key = NULL, * query_string = NULL;
 726   char * result = NULL;
 727   Object * o = new Object();
 728   
 729   code = o->scan(route_object, strlen(route_object));
 730   search_key = get_search_key(o, "route", route_object);
 731   
 732   query_string = (char *)malloc(strlen("-Tinetnum -r -x ") + strlen(search_key) + 1);
 733   sprintf(query_string, "-Tinetnum -r -x %s", search_key);
 734   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 735   if(count_objects(result) == 0){
 736     cout << "No such inetnum" << endl;
 737     return NULL;
 738   }else if(count_objects(result) > 1){
 739     cout << "More than one inetnums returned" << endl;
 740     return NULL;
 741   }else{ /* count_objects(result) == 1 */
 742     return take_object(result);
 743   }
 744   
 745 }
 746 
 747 
 748 
 749 /* Takes a route object and returns exact matches of this route */
 750 GSList * get_exact_match_routes(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 751   bool code;
 752   char * search_key = NULL, * query_string = NULL;
 753   char * result = NULL;
 754   Object * o = new Object();
 755   
 756   code = o->scan(route_object, strlen(route_object));
 757   search_key = get_search_key(o, "route", route_object);
 758   
 759   query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(search_key) + 1);
 760   sprintf(query_string, "-Troute -r -x %s", search_key);
 761   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 762   if(count_objects(result) == 0){
 763     cout << "get_exact_match_routes: No such route" << endl;
 764     return NULL;
 765   }else{ /* count_objects(result) == 1 */
 766     return take_objects(result);
 767   }
 768   
 769 }
 770 
 771 
 772 
 773 /* Takes a route object and returns (immediate) less specifics of this route */
 774 GSList * get_less_spec_routes(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 775   bool code;
 776   char * search_key = NULL, * query_string = NULL;
 777   char * result = NULL;
 778   Object * o = new Object();
 779   
 780   code = o->scan(route_object, strlen(route_object));
 781   search_key = get_search_key(o, "route", route_object);
 782   
 783   query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(search_key) + 1);
 784   sprintf(query_string, "-Troute -r -l %s", search_key);
 785   result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
 786   if(count_objects(result) == 0){
 787     cout << "get_less_spec_routes: No such route" << endl;
 788     return NULL;
 789   }else{ /* count_objects(result) == 1 */
 790     return take_objects(result);
 791   }
 792   
 793 }
 794 
 795 
 796 
 797 /* Gets an object as a string and returns its 'mnt-by' attributes as a 
 798    GSList (linked list)   */
 799 /* No need for this function any more in fact. 'get_attr_list' can be used instead.
 800    All calls to get_mntners(object) must be converted into get_attr_list(object, "mnt-by") */
 801 
 802 GSList *get_mntners(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 803   bool code;
 804   Object * o;
 805   Attr *attr;
 806   char *value  = NULL;
 807   GSList *list_of_mntners = NULL;
 808   char * object; 
 809 
 810   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
 811    (no harm in having more than one) */
 812   object = (char *)malloc(strlen(arg) + 2);
 813   sprintf(object, "%s\n", arg);
 814 
 815   if(tracing) {
 816     printf("TRACING: get_mntners is running\n");
 817   }
 818   o = new Object;
 819   code = o->scan(object,strlen(object));
 820   
 821   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 822     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 823     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 824         attr->len - strlen(attr->type->name()) -2 );
 825     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 826     //cout << "DEBUG: get_mntners: type: #" << attr->type->name() << "#, value: #" << value << "#" << endl;
 827     if(strcmp(attr->type->name(),"mnt-by") == 0){
 828       if(tracing) {
 829         cout << "TRACING: get_mntners: adding " << g_strstrip(value) << endl;
 830       }
 831       list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
 832     }
 833     free(value);
 834   }
 835 
 836 
 837   return list_of_mntners; 
 838 }
 839 
 840 
 841 /* Gets a preparsed object, its text and an attribute name. Returns a list of
 842    attribute values */
 843 GSList *get_attributes(Object * o, const char * attrib, const char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 844 
 845   char * value = NULL;
 846   Attr *attr;
 847   GSList *list_of_attributes = NULL;
 848 
 849   //if(tracing) {
 850   //  printf("TRACING: get_attributes is running\n");
 851   //}
 852   
 853   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 854     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 855     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 856         attr->len - strlen(attr->type->name()) -2 );
 857     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 858     if(strcmp(attr->type->name(), attrib) == 0){
 859       if(tracing) {
 860         cout << "TRACING: get_attributes: adding " << g_strstrip(value) << endl;
 861       }
 862       list_of_attributes = g_slist_append(list_of_attributes, strdup(g_strstrip(value)));
 863     }
 864     //free(value);
 865   }
 866 
 867   //if(tracing) {
 868   //  printf("TRACING: get_attributes is returning\n");
 869   //}
 870   
 871   return list_of_attributes; 
 872 }
 873 
 874 
 875 /* Gets a preparsed object, an attribute name. Returns the value of first occurence
 876    of this attribute */
 877 char *get_attribute(Object * o, const char * attrib, char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 878 
 879   char * value = NULL;
 880   Attr *attr;
 881 
 882   if(tracing) {
 883     printf("TRACING: get_attributes is running\n");
 884   }
 885   
 886   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 887     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 888     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 889         attr->len - strlen(attr->type->name()) -2 );
 890     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 891     if(strcmp(attr->type->name(), attrib) == 0){
 892       if(tracing) {
 893         cout << "TRACING: get_attribute: will return " << value << endl;
 894       }
 895       return value;
 896     }else{
 897       free(value);
 898     }
 899   }
 900 
 901   if(tracing) {
 902     printf("TRACING: get_attribute is returning\n");
 903   }
 904   
 905   return NULL; 
 906 }
 907 
 908 
 909 
 910 /* Gets a GSList of strings and returns 1 if one of them starts with substr, 0 otherwise */
 911 int strstr_in_list(GSList * list, const char * substr){
     /* [<][>][^][v][top][bottom][index][help] */
 912 
 913  GSList * next = NULL;
 914  char * word; 
 915 
 916   if(tracing) {
 917     printf("TRACING: strstr_in_list is running\n");
 918   }
 919  
 920  for( next = list; next != NULL ; next = g_slist_next(next) ){
 921    word = strdup((char *)next->data);
 922    g_strup(word);
 923    if(strstr(word, substr) == word){
 924      free(word);
 925      return 1;
 926    }
 927    free(word);
 928  }
 929  /* none of them matched, so return 0 */
 930  return 0; 
 931 }
 932 
 933 
 934 
 935 
 936 
 937 /* Gets a (maintainer) object as a string and returns its 'auth' attributes 
 938    as a GSList (linked list) */
 939 
 940 GSList *get_auths(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
 941   bool code;
 942   Object * o;
 943   Attr *attr;
 944   char *value  = NULL;
 945   GSList *list_of_auths = NULL;
 946 
 947   if(tracing){
 948     printf("TRACING: get_auths is running\n");
 949   }
 950   o = new Object;
 951   code = o->scan(object,strlen(object));
 952   
 953   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 954     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 955     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 956         attr->len - strlen(attr->type->name()) -2 );
 957     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 958     //cout << "value: #" << value << "#" << endl;
 959     if(strcmp(attr->type->name(),"auth") == 0){
 960       if(tracing) {
 961         cout << "TRACING: get_auths: adding " << g_strstrip(value) << endl;
 962       }
 963       list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
 964       if(tracing) {
 965         cout << "TRACING: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
 966       }
 967     }
 968   }
 969 
 970   if(tracing) {
 971     cout << "TRACING: get_auths: returning (with " << g_slist_length(list_of_auths) << " nodes)" << endl;
 972   }
 973   return list_of_auths; 
 974 }
 975 
 976 
 977 
 978 
 979 /* Gets an object as a string an returns its 'attr_type' attributes as a 
 980    GSList (linked list) */
 981 
 982 GSList *get_attr_list(char * arg, char * attr_type){
     /* [<][>][^][v][top][bottom][index][help] */
 983   bool code;
 984   Object * o;
 985   Attr *attr;
 986   char *value  = NULL;
 987   GSList *list_of_attrs = NULL;
 988   char * object;
 989 
 990   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
 991    (no harm in having more than one) */
 992   object = (char *)malloc(strlen(arg) + 2);
 993   sprintf(object, "%s\n", arg);
 994 
 995   if(tracing) {
 996     printf("TRACING: get_attr_list is running, object is \n#%s#\n", object);
 997   }
 998   o = new Object;
 999   code = o->scan(object,strlen(object));
1000   
1001   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1002     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1003     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1004         attr->len - strlen(attr->type->name()) -2 );
1005     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1006     //cout << "DEBUG: get_attr_list: (looking for '" << attr_type << "') type: #" << attr->type->name() << "#, value: #" << value << "#" << endl;
1007     if(strcmp(attr->type->name(), attr_type) == 0){
1008       if(tracing) {
1009         cout << "TRACING: get_attr_list: adding " << g_strstrip(value) << endl;
1010       }
1011       list_of_attrs = g_slist_append(list_of_attrs, strdup(g_strstrip(value)));
1012     }
1013   }
1014 
1015 
1016   return list_of_attrs; 
1017 }
1018 
1019 
1020 
1021 
1022 
1023 
1024 /* Gets an object as a string an returns its mnt_lower attributes as a 
1025    GSList (linked list) */
1026 
1027 GSList *get_mnt_lowers(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1028   bool code;
1029   Object * o;
1030   Attr *attr;
1031   char *value  = NULL;
1032   GSList *list_of_mnt_lowers = NULL;
1033 
1034 
1035   if(tracing) {
1036     printf("TRACING: get_mnt_lowers is running\n");
1037   }
1038   o = new Object;
1039   code = o->scan(object,strlen(object));
1040   
1041   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1042     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1043     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1044         attr->len - strlen(attr->type->name()) -2 );
1045     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1046     //cout << "value: #" << value << "#" << endl;
1047     if(strcmp(attr->type->name(),"mnt-lower") == 0){
1048       if(tracing) {
1049         cout << "TRACING: get_mnt_lowers: adding " << g_strstrip(value) << endl;
1050       }
1051       list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
1052     }
1053   }
1054 
1055 
1056   return list_of_mnt_lowers; 
1057 }
1058 
1059 
1060 /* Gets an object as a string an returns its mnt_routes attributes as a 
1061    GSList (linked list) */
1062 
1063 GSList *get_mnt_routes(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1064   bool code;
1065   Object * o;
1066   Attr *attr;
1067   char *value  = NULL;
1068   GSList *list_of_mnt_routes = NULL;
1069 
1070   if(tracing) {
1071   cout << "TRACING: get_mnt_routes is running" << endl;
1072   }
1073   o = new Object;
1074   code = o->scan(object,strlen(object));
1075   
1076   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1077     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1078     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1079         attr->len - strlen(attr->type->name()) -2 );
1080     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1081     //cout << "value: #" << value << "#" << endl;
1082     if(strcmp(attr->type->name(),"mnt-routes") == 0){
1083       if(tracing) {
1084         cout << "TRACING: get_mnt_routes: adding " << g_strstrip(value) << endl;
1085       }
1086       list_of_mnt_routes = g_slist_append(list_of_mnt_routes, strdup(g_strstrip(value)));
1087     }
1088   }
1089 
1090   return list_of_mnt_routes; 
1091 }
1092 
1093 
1094 /* Gets a linked list of objects and returns the mnt_routes attribs of
1095    them in a linked list */
1096 GSList *get_mnt_routes_from_list(GSList * objects){
     /* [<][>][^][v][top][bottom][index][help] */
1097   GSList *next = NULL;
1098   GSList *list_of_mnt_routes = NULL;
1099   
1100   for( next = objects; next != NULL ; next = g_slist_next(next) ){
1101     list_of_mnt_routes = g_slist_concat(list_of_mnt_routes, get_mnt_routes((char *)next->data));
1102   }
1103 
1104   return list_of_mnt_routes;
1105 }
1106 
1107 
1108 
1109 /* Gets a linked list of objects and returns the mnt_routes attribs of
1110    them in a linked list */
1111 GSList *get_mnt_lowers_from_list(GSList * objects){
     /* [<][>][^][v][top][bottom][index][help] */
1112   GSList *next = NULL;
1113   GSList *list_of_mnt_lowers = NULL;
1114   
1115   for( next = objects; next != NULL ; next = g_slist_next(next) ){
1116     list_of_mnt_lowers = g_slist_concat(list_of_mnt_lowers, get_mnt_lowers((char *)next->data));
1117   }
1118 
1119   return list_of_mnt_lowers;
1120 }
1121 
1122 
1123 
1124 /* retrieves the override password from the 'override' attribute  
1125    of the object. If none, it returns NULL   */
1126 char *get_override(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1127   bool code;
1128   Object * o;
1129   Attr *attr;
1130   char *value  = NULL;
1131 
1132   if(tracing){
1133     printf("TRACING: get_override is running\n");
1134   }
1135   o = new Object;
1136   code = o->scan(object,strlen(object));
1137   
1138   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1139     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1140     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1141         attr->len - strlen(attr->type->name()) -2 );
1142     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1143     //cout << "value: #" << value << "#" << endl;
1144     if(strcmp(attr->type->name(),"override") == 0){
1145       if(tracing) {
1146         cout << "TRACING: get_override: returning " << g_strstrip(value) << endl;
1147       }
1148       return  strdup(g_strstrip(value));
1149     }
1150   }
1151   /* there was no 'override' attrib, so return NULL */
1152   return NULL; 
1153 }
1154 
1155 
1156 
1157 
1158 
1159 
1160 /* checks override string (password) 
1161    returns OVR_OK if it is correct password */
1162 int check_override(char * string){
     /* [<][>][^][v][top][bottom][index][help] */
1163    char ** temp;
1164    int i;
1165    char * crypted_password = strdup(overridecryptedpw);
1166    if(string == NULL) {
1167      if(tracing) {
1168        printf("TRACING: check_override is returning FAILED\n");
1169      }
1170      return UP_OVF; /* override attempt failed */ 
1171    }else{
1172     /* split the string */
1173      temp = g_strsplit (string, " ", 0);
1174 
1175      for(i=0; temp[i] != NULL; i++){
1176        if(strlen(temp[i]) != 0){
1177          printf("%s\n", temp[i]);
1178          if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0){
1179            g_strfreev(temp);
1180            if(tracing) {
1181              printf("TRACING: check_override is returning OK\n", string);
1182            }
1183            return OVR_OK; 
1184          }
1185        }
1186      }
1187 
1188      g_strfreev(temp);         
1189      /* we couldn't find a word matching the override password */ 
1190           return UP_OVF; /* override attempt failed */
1191    }
1192 }
1193 
1194 
1195 
1196 
1197 
1198 
1199 
1200 
1201 
1202 
1203 
1204 
1205 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
1206    add new elements to GSList of struct auth_struct and  returns the new
1207    GSList of struct auth_struct  */
1208 
1209 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
     /* [<][>][^][v][top][bottom][index][help] */
1210    //GSList * to_be_returned = NULL;
1211    GSList * next;
1212    char * auth_attrib = NULL;
1213    char * auth_attrib_uppercase = NULL, * argument = NULL;
1214    //struct auth_struct * temp = NULL;
1215    auth_struct * temp = NULL;
1216    int index = 1;
1217       
1218    for(next = auths; next != NULL; next = g_slist_next(next)){
1219      auth_attrib = strdup((char *)next->data);
1220      auth_attrib = g_strstrip(auth_attrib);
1221      if(tracing) {
1222        cout << "TRACING: add_to_auth_vector: " << auth_attrib << endl;
1223      }
1224      /* Take the auth attribute and convert it into uppercase for comparisons */
1225      auth_attrib_uppercase = strdup(auth_attrib);
1226      g_strup(auth_attrib_uppercase);
1227      
1228      if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
1229        /* take the argument of the auth attribute */
1230        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1231        g_strstrip(argument);
1232        if(tracing) {
1233          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1234        }
1235        //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1236        temp = (auth_struct *)malloc(sizeof(auth_struct));
1237        temp->type = AU_CRYPT_PW;
1238        temp->auth = argument;
1239        temp->mntner_name = mntner_name;
1240        temp->index = index++;
1241        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1242      }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
1243        /* take the argument of the auth attribute */
1244        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1245        g_strstrip(argument);
1246        if(tracing) {
1247          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1248        }
1249        //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1250        temp = (auth_struct *)malloc(sizeof(auth_struct));
1251        temp->type = AU_MAIL_FROM;
1252        temp->auth = argument;
1253        temp->mntner_name = mntner_name;
1254        temp->index = index++;
1255        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1256      }else if(strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase){
1257        /* take the argument of the auth attribute */
1258        //argument = strdup(auth_attrib + strlen("NONE"));
1259        //g_strstrip(argument);
1260        //cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
1261        //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1262        temp = (auth_struct *)malloc(sizeof(auth_struct));
1263        temp->type = AU_NONE;
1264        temp->auth = NULL;
1265        temp->mntner_name = mntner_name;
1266        temp->index = index++;
1267        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1268     }else if(strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase){
1269        argument = strdup(auth_attrib + strlen("PGPKEY-"));
1270        g_strstrip(argument);
1271        if(tracing) {
1272          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1273        }
1274        //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1275        temp = (auth_struct *)malloc(sizeof(auth_struct));
1276        temp->type = AU_PGP;
1277        temp->mntner_name = mntner_name;
1278        temp->index = index++;
1279        /* temp->pgp_struct must be assigned, not yet implemented */
1280        temp->auth = argument;
1281        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1282        cout << "Not implemented totally (PGP)" << endl;
1283      }else{
1284        cout << "DEBUG: Error: invalid auth attrib: " << auth_attrib << endl;
1285        return NULL;
1286      }
1287    }
1288    free(auth_attrib_uppercase);
1289    free(auth_attrib); 
1290    return list_of_auth_struct;
1291 
1292 }
1293 
1294 
1295 
1296 
1297 
1298 
1299 
1300 
1301 
1302 /* Gets a list of mntner names, retrieves those mntners from
1303    the database and extracts the 'auth' attributes, and
1304    constructs the authorisation vector, which is a GSList of
1305    struct auth_struct */
1306 
1307 GSList * get_auth_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1308   GSList * list_of_auths = NULL;
1309   GSList * next = NULL;
1310   GSList * to_be_returned = NULL;
1311   char * query_string = NULL, * result = NULL, * object = NULL;
1312   GSList * temp;
1313 
1314   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1315     if(tracing) {
1316       cout << "=====" << endl << "Got a mntner" << endl;
1317       cout << (char *)next->data << endl;
1318     }
1319     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1320     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1321     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1322     if(count_objects(result) == 0){
1323       //if(tracing) {
1324       //  cout << "No such maintainer, exiting" << endl;
1325       //}
1326       //exit(1);
1327       /* no such maintainer */
1328       return NULL;
1329     }else if(count_objects(result) > 1){
1330       if(tracing) {
1331         cout << "More than one objects returned" << endl;
1332       }
1333     }else{ /* count_objects(result) == 1 */
1334       object = take_object(result);
1335       if(tracing) {
1336         printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1337       }
1338       temp = get_auths(object);
1339       if(tracing) {
1340         cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1341       }
1342       list_of_auths = g_slist_concat(list_of_auths, temp);
1343       if(tracing) {
1344         cout << "TRACING: get_auth_vector: list_of_auths has now " <<  g_slist_length(list_of_auths) << " nodes" << endl;
1345       }
1346       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1347       if(tracing) {
1348        cout << "TRACING: get_auth_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1349       }
1350       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1351     }
1352   }
1353   
1354   if(tracing) {  
1355     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1356   }
1357   return to_be_returned; 
1358 }
1359 
1360 
1361 
1362 
1363 
1364 
1365 
1366 /* Gets a list of mntner names, retrieves those mntners from
1367    the database and extracts the 'mnt-by' attributes, and
1368    returns them as a GSList */
1369 
1370 GSList * get_mntnfy_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1371   GSList * list_of_mntnfy = NULL;
1372   GSList * next = NULL;
1373   //GSList * to_be_returned = NULL;
1374   char * query_string = NULL, * result = NULL, * object = NULL;
1375   GSList * temp;
1376   
1377   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1378     if(tracing) {
1379       cout << "=====" << endl << "Got a mntner" << endl;
1380       cout << (char *)next->data << endl;
1381     }
1382     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1383     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1384     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1385     if(count_objects(result) == 0){
1386       /* no such maintainer */
1387     }else if(count_objects(result) > 1){
1388       if(tracing) {
1389         cout << "More than one objects returned" << endl;
1390       }
1391     }else{ /* count_objects(result) == 1 */
1392       object = take_object(result);
1393       if(tracing) {
1394         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1395       }
1396       temp = get_attr_list(object, "mnt-nfy");
1397       if(tracing) {
1398         cout << "TRACING: get_mntnfy_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1399       }
1400       list_of_mntnfy = g_slist_concat(list_of_mntnfy, temp);
1401       if(tracing) {
1402         cout << "TRACING: get_mntnfy_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_mntnfy) << " nodes" << endl;
1403       }
1404       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1405       //if(tracing) {
1406       // cout << "TRACING: get_mntnfy_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1407       //}
1408       //to_be_returned = add_to_auth_vector(to_be_returned, list_of_mntnfy, (char *)next->data);
1409     }
1410   }
1411   
1412   if(tracing) {  
1413     printf("TRACING: get_auth_vector: list_of_mntnfy has %i nodes\n", g_slist_length(list_of_mntnfy)); 
1414   }
1415   return list_of_mntnfy; 
1416 }
1417 
1418 
1419 
1420 
1421 
1422 
1423 /* Gets a list of mntner names, retrieves those mntners from
1424    the database and extracts the 'upd-to' attributes, and
1425    returns them as a GSList */
1426 
1427 GSList * get_updto_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1428   GSList * list_of_updto = NULL;
1429   GSList * next = NULL;
1430   //GSList * to_be_returned = NULL;
1431   char * query_string = NULL, * result = NULL, * object = NULL;
1432   GSList * temp;
1433   
1434   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1435     if(tracing) {
1436       cout << "=====" << endl << "Got a mntner" << endl;
1437       cout << (char *)next->data << endl;
1438     }
1439     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1440     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1441     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1442     if(count_objects(result) == 0){
1443       /* no such maintainer */
1444     }else if(count_objects(result) > 1){
1445       if(tracing) {
1446         cout << "More than one objects returned" << endl;
1447       }
1448     }else{ /* count_objects(result) == 1 */
1449       object = take_object(result);
1450       if(tracing) {
1451         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1452       }
1453       temp = get_attr_list(object, "upd-to");
1454       if(tracing) {
1455         cout << "TRACING: get_updto_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1456       }
1457       list_of_updto = g_slist_concat(list_of_updto, temp);
1458       if(tracing) {
1459         cout << "TRACING: get_updto_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_updto) << " nodes" << endl;
1460       }
1461       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1462       //if(tracing) {
1463       // cout << "TRACING: get_mntnfy_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1464       //}
1465       //to_be_returned = add_to_auth_vector(to_be_returned, list_of_mntnfy, (char *)next->data);
1466     }
1467   }
1468   
1469   if(tracing) {  
1470     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_slist_length(list_of_updto)); 
1471   }
1472   return list_of_updto; 
1473 }
1474 
1475 
1476 
1477 
1478 
1479 
1480 
1481 
1482 
1483 
1484 /* gets one or more route objects filters out the ones which don't have the same
1485    origin as 'char * origin' argument */
1486 char * filter_out_diff_origins(char * objects, char * origin){
     /* [<][>][^][v][top][bottom][index][help] */
1487   GSList * object_list = NULL, * next =NULL;
1488   char * objects_to_be_returned = NULL;
1489   bool code;
1490   char * key = NULL;
1491   Object * o = new Object();
1492   
1493   
1494   if(tracing) {
1495     printf("TRACING: filter_out_diff_origins\n");
1496   }
1497 
1498   /* strip the lines beginning with '%' off */
1499   objects = strip_lines(objects);
1500   
1501   /* separate the objects, store them in a linked list */
1502   object_list = take_objects(objects);
1503 
1504   for(next = object_list; next != NULL; next = g_slist_next(next)){
1505     code = o->scan((char *)next->data, strlen((char *)next->data));
1506     key = get_search_key(o, "origin", (char *)next->data);
1507     if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1508       if(objects_to_be_returned == NULL){
1509         objects_to_be_returned = strdup((char *)next->data);
1510       }else{
1511         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
1512                       strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1513         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1514         objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1515       }
1516     }
1517   }
1518 
1519   delete(o);
1520   if(tracing) {
1521     if(objects_to_be_returned != NULL){
1522       printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1523     }else {
1524       printf("TRACING: filter_out_diff_origins: returning NULL\n");
1525       
1526     }
1527   }
1528   return objects_to_be_returned; 
1529   
1530 }
1531 
1532 
1533 
1534 
1535 /* Check authorisation
1536    Applies authorisation rules according to the object type 
1537    
1538    Arguments:
1539       char *new_object: the new object,
1540       char *old_object: the old object, as found in the database,
1541       char *type: type of the object
1542       credentials_struct credentials: a struct which
1543         contains credentials of the update, such as 'From:' field of
1544         the e-mail header and passwords in the update   */
1545 
1546 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
     /* [<][>][^][v][top][bottom][index][help] */
1547    
1548    GSList *old_mntners = NULL, *new_mntners = NULL;
1549    GSList *old_auths = NULL, *new_auths = NULL;
1550    GSList *as_block_mnt_lowers = NULL;
1551    GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1552    GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1553    GSList *less_specific_mntners = NULL;
1554    GSList *aut_num_maintainers = NULL;
1555    GSList *aut_num_auth_vector = NULL;
1556    GSList *exact_match_routes = NULL;  
1557    GSList *exact_match_routes_maintainers = NULL;
1558    GSList *exact_match_routes_auth_vector = NULL;
1559    GSList *less_spec_routes = NULL;
1560    GSList *less_spec_routes_mntners = NULL;
1561    GSList *less_spec_routes_auth_vector = NULL;
1562    GSList *exact_match_inetnum_mnt_routes = NULL;
1563    GSList *exact_match_inetnum_auth_vector = NULL;
1564    GSList *less_spec_inetnum_mntners = NULL;
1565    GSList *less_spec_inetnum_auth_vector = NULL;
1566    GSList *exact_match_intenum_auth_vector = NULL;
1567    GSList *exact_match_auth_vector = NULL;
1568     
1569    char *as_block_object = NULL, *less_specific_object = NULL;
1570    char *less_specific_domain = NULL;
1571    char *less_spec_inetnum = NULL;
1572    char *exact_match_inetnum = NULL;
1573    char *less_specific_object_type = NULL;
1574    char *override_string = NULL;
1575    char *set_name = NULL;
1576    char * aut_num_object = NULL;
1577    Object *set_object = new Object();
1578    Object *temp_obj;
1579    bool code;
1580    bool aut_num_auth_OK = false;
1581 
1582    int overriden = 0;
1583    
1584    /* first check if it is overriden or not. if overriden, check the override
1585       password. If it is correct, continue, setting "overriden" to 1. If not,   
1586       immediately exit returning ERR_UP_OVF                                   */
1587    override_string = get_override((new_object == NULL) ? old_object : new_object );
1588    if(override_string == NULL){ 
1589      overriden = 0;
1590    }else if(check_override(override_string) == OVR_OK){
1591      overriden = 1; /* authorisation is overriden */
1592    }else if(check_override(override_string) == UP_OVS){
1593      return UP_OVS; /* override syntax error --it must have at least two words */
1594    }else{
1595      return UP_OVF; /* override failed! */
1596    }
1597 
1598 
1599    /*  
1600     *  Handle the "person", "role", "limerick", "inet-rtr" types 
1601     */
1602    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
1603       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ){
1604      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1605        old_mntners = get_mntners(old_object);
1606        old_auth_vector = get_auth_vector(old_mntners);
1607        return authorise(old_auth_vector, credentials, overriden);
1608      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1609        new_mntners = get_mntners(new_object);
1610        new_auth_vector = get_auth_vector(new_mntners);
1611        if(new_mntners != NULL && new_auth_vector == NULL){
1612          /* then, the mntners in 'new_mntners' do not exist. Problem. */
1613          return UP_AUF; /* auth failed */
1614        }
1615        /*printf("DEBUG: check_auth: new_auth_vector has %i, new_mntners has %i nodes\n",
1616               g_slist_length(new_auth_vector) ,g_slist_length(new_mntners));*/
1617        return authorise(new_auth_vector, credentials, overriden);
1618      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1619        old_mntners = get_mntners(old_object);
1620        old_auth_vector = get_auth_vector(old_mntners);
1621        if(old_mntners != NULL && old_auth_vector == NULL){
1622          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1623          return UP_AUF; /* auth failed */
1624        }
1625        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1626          return authorise(old_auth_vector, credentials, overriden);
1627        }else{
1628          new_mntners = get_mntners(new_object);
1629          new_auth_vector = get_auth_vector(new_mntners);
1630          if(new_mntners != NULL && new_auth_vector == NULL){
1631            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1632            return UP_AUF; /* auth failed */
1633          }
1634          return authorise(new_auth_vector, credentials, overriden);
1635        }
1636      }else{ // both are NULL, mustn't happen
1637          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1638          return UP_INT; /* internal error */
1639      }
1640    }
1641 
1642    /*  
1643     *  Handle the "auth-num" type 
1644     */
1645    else if(strcmp(type,"aut-num")  == 0 ){
1646      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1647        old_mntners = get_mntners(old_object);
1648        old_auth_vector = get_auth_vector(old_mntners);
1649        if(old_mntners != NULL && old_auth_vector == NULL){
1650          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1651          return UP_AUF; /* auth failed */
1652        }
1653        return authorise(old_auth_vector, credentials, overriden);
1654      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1655        as_block_object = get_as_block(new_object);
1656        if(as_block_object == NULL ){
1657          return UP_ABN; /* As-block does not exist */
1658          }else{
1659            as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1660            as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1661            if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1662              /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1663              return UP_AUF; /* auth failed */
1664            }
1665          if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1666            new_mntners = get_mntners(new_object);
1667            new_auth_vector = get_auth_vector(new_mntners);
1668            if(new_mntners != NULL && new_auth_vector == NULL){
1669              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1670              return UP_AUF; /* auth failed */
1671            }
1672            return authorise(new_auth_vector, credentials, overriden);
1673          }else{
1674            return UP_HOF; /* hierarchical auth failed */
1675          }
1676        }
1677      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1678        old_mntners = get_mntners(old_object);
1679        old_auth_vector = get_auth_vector(old_mntners);
1680        if(old_mntners != NULL && old_auth_vector == NULL){
1681          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1682          return UP_AUF; /* auth failed */
1683        }
1684        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1685          return authorise(old_auth_vector, credentials, overriden);
1686        }else{
1687          new_mntners = get_mntners(new_object);
1688          new_auth_vector = get_auth_vector(new_mntners);
1689          if(new_mntners != NULL && new_auth_vector == NULL){
1690            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1691            return UP_AUF; /* auth failed */
1692          }
1693          return authorise(new_auth_vector, credentials, overriden);
1694        }
1695      }else{ /* both are NULL, mustn't happen */
1696          if(tracing) {
1697            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1698          } 
1699          return UP_INT; /* internal error */
1700      }
1701    } 
1702 
1703    /*  
1704     *  Handle the "mntner/as-block" types 
1705     */
1706    else if(strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 ){
1707      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1708        old_mntners = get_mntners(old_object);
1709        old_auth_vector = get_auth_vector(old_mntners);
1710        if(old_mntners != NULL && old_auth_vector == NULL){
1711          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1712          return UP_AUF; /* auth failed */
1713        }
1714        return authorise(old_auth_vector, credentials, overriden);
1715      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1716        if(overriden || test_mode){
1717          return UP_AUTH_OK; 
1718        }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
1719          if(tracing) {
1720            cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
1721          }
1722          return UP_AUF; /* authorisation failed */
1723        }
1724      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1725        old_mntners = get_mntners(old_object);
1726        old_auth_vector = get_auth_vector(old_mntners);
1727        if(old_mntners != NULL && old_auth_vector == NULL){
1728          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1729          return UP_AUF; /* auth failed */
1730        }
1731        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1732          return authorise(old_auth_vector, credentials, overriden);
1733        }else{
1734          new_mntners = get_mntners(new_object);
1735          new_auth_vector = get_auth_vector(new_mntners);
1736          if(new_mntners != NULL && new_auth_vector == NULL){
1737            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1738            return UP_AUF; /* auth failed */
1739          }
1740          return authorise(new_auth_vector, credentials, overriden);
1741        }
1742      }else{ // both are NULL, mustn't happen
1743          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1744          return UP_INT; /* internal error */
1745      }
1746    }
1747 
1748    /*  
1749     *  Handle the "inetnum/inet6num" types 
1750     */
1751    else if(strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 ){
1752      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1753        old_mntners = get_mntners(old_object);
1754        old_auth_vector = get_auth_vector(old_mntners);
1755        if(old_mntners != NULL && old_auth_vector == NULL){
1756          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1757          return UP_AUF; /* auth failed */
1758        }
1759        return authorise(old_auth_vector, credentials, overriden);
1760      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1761        less_specific_object = get_less_specific(new_object, type);
1762        if(less_specific_object == NULL){
1763          if(overriden){
1764            return UP_AUTH_OK; 
1765          }else{
1766            return UP_HOF; /* hierarchical authorisation failed */
1767          }
1768        }else{ /* if we got an inet(6)num object */
1769          less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1770          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1771          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1772            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1773            return UP_AUF; /* auth failed */
1774          }
1775          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1776            new_mntners = get_mntners(new_object);
1777            new_auth_vector = get_auth_vector(new_mntners);
1778            if(new_mntners != NULL && new_auth_vector == NULL){
1779              /* then, the mntners in 'new_mntners' do not exist. Problem. */
1780              return UP_AUF; /* auth failed */
1781            }
1782            return authorise(new_auth_vector, credentials, overriden);
1783          }else{
1784            return UP_HOF; /* hierarchical authorisation failed */
1785          }
1786        }
1787      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1788        old_mntners = get_mntners(old_object);
1789        old_auth_vector = get_auth_vector(old_mntners);
1790        if(old_mntners != NULL && old_auth_vector == NULL){
1791          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1792          return UP_AUF; /* auth failed */
1793        }
1794        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1795          return authorise(old_auth_vector, credentials, overriden);
1796        }else{
1797          new_mntners = get_mntners(new_object);
1798          new_auth_vector = get_auth_vector(new_mntners);
1799          if(new_mntners != NULL && new_auth_vector == NULL){
1800            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1801            return UP_AUF; /* auth failed */
1802          }
1803          return authorise(new_auth_vector, credentials, overriden);
1804        }
1805      }else{ /* both are NULL, mustn't happen */
1806          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1807          return UP_INT; /* internal error */
1808      }
1809    }
1810 
1811 
1812    
1813    /*  
1814     *  Handle the "domain" type 
1815     */
1816    else if(strcmp(type,"domain")  == 0){
1817      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1818        old_mntners = get_mntners(old_object);
1819        old_auth_vector = get_auth_vector(old_mntners);
1820        if(old_mntners != NULL && old_auth_vector == NULL){
1821          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1822          return UP_AUF; /* auth failed */
1823        }
1824        return authorise(old_auth_vector, credentials, overriden);
1825      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1826        /* now, we have to find a 'less specific domain object' for this. 
1827           If there is no less specific object, then creation is possible
1828           only with overriding. */
1829       less_specific_domain = get_less_specific_domain(new_object);
1830       if(less_specific_domain == NULL){
1831         if(overriden){/* we didn't get a 'less specific' domain object */
1832            return UP_AUTH_OK; 
1833          }else{
1834            return UP_HOF; /* hierarchical authorisation failed */
1835          }
1836       }else{ /* we get a 'less specific' domain object */
1837          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
1838          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1839          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1840            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1841            return UP_AUF; /* auth failed */
1842          }
1843          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1844            new_mntners = get_mntners(new_object);
1845            new_auth_vector = get_auth_vector(new_mntners);
1846            if(new_mntners != NULL && new_auth_vector == NULL){
1847              /* then, the mntners in 'new_mntners' do not exist. Problem. */
1848              return UP_AUF; /* auth failed */
1849            }
1850            return authorise(new_auth_vector, credentials, overriden);
1851          }else{
1852            return UP_HOF; /* hierarchical authorisation failed */
1853          }
1854         
1855       }
1856      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1857        old_mntners = get_mntners(old_object);
1858        old_auth_vector = get_auth_vector(old_mntners);
1859        if(old_mntners != NULL && old_auth_vector == NULL){
1860          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1861          return UP_AUF; /* auth failed */
1862        }
1863        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1864          return authorise(old_auth_vector, credentials, overriden);
1865        }else{
1866          new_mntners = get_mntners(new_object);
1867          new_auth_vector = get_auth_vector(new_mntners);
1868          if(new_mntners != NULL && new_auth_vector == NULL){
1869            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1870            return UP_AUF; /* auth failed */
1871          }
1872          return authorise(new_auth_vector, credentials, overriden);
1873        }
1874      }else{ /* both are NULL, mustn't happen */
1875          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1876          return UP_INT; /* internal error */
1877      }
1878    }
1879    
1880 
1881    /*  
1882     *  Handle the "route" type 
1883     */
1884    else if(strcmp(type,"route")  == 0){
1885      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1886        old_mntners = get_mntners(old_object);
1887        old_auth_vector = get_auth_vector(old_mntners);
1888        if(old_mntners != NULL && old_auth_vector == NULL){
1889          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1890          return UP_AUF; /* auth failed */
1891        }
1892        return authorise(old_auth_vector, credentials, overriden);
1893      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1894        /* first we have to find the aut-num object mentioned in the 
1895           origin attribute */
1896 
1897        aut_num_object = get_aut_num_object(new_object); 
1898        if(aut_num_object == NULL){
1899          if(overriden){
1900            return UP_AUTH_OK; 
1901          }else{
1902            return UP_HOF; /* hierarchical authorisation failed */
1903          }
1904        }else{/* there is a corresponding aut-num in the db */
1905          printf("DEBUG: check_auth: will try to authorise the route using aut-num\n");
1906          aut_num_maintainers = get_mnt_routes(aut_num_object);
1907          if(aut_num_maintainers != NULL){
1908            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1909            if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1910              aut_num_auth_OK = true;
1911            }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1912              return UP_HOF;
1913            }
1914          }else{/* aut_num_maintainers is NULL */
1915             aut_num_maintainers = get_mnt_lowers(aut_num_object);
1916             if(aut_num_maintainers != NULL){
1917               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1918               if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1919                 aut_num_auth_OK = TRUE;
1920               }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1921                 return UP_HOF; /* hierarchical authorisation failed */
1922               }
1923             }else{/* aut_num_maintainers is NULL */
1924               aut_num_maintainers = get_mntners(aut_num_object);
1925               if(aut_num_maintainers != NULL){
1926                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1927                 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1928                   aut_num_auth_OK = TRUE;
1929                 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1930                   return UP_HOF; /* hierarchical authorisation failed */
1931                 }
1932               }else{/* aut_num_maintainers is NULL */
1933                 aut_num_auth_OK = TRUE;
1934               }
1935               
1936             }
1937          }
1938          if(aut_num_auth_OK){
1939            /* now, we have to find an exact match for this route object. 
1940               If there is no exact match object, then we will go on to find
1941               less specific. */
1942            exact_match_routes = get_exact_match_routes(new_object);
1943            if(exact_match_routes != NULL){
1944              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
1945              exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
1946              if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
1947                /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
1948                return UP_AUF; /* auth failed */
1949               }
1950              if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1951                /* then, check mnt_bys of the route itself */
1952                new_mntners = get_mntners(new_object);
1953                new_auth_vector = get_auth_vector(new_mntners);
1954                if(new_mntners != NULL && new_auth_vector == NULL){
1955                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
1956                  return UP_AUF; /* auth failed */
1957                }
1958                return authorise(new_auth_vector, credentials, overriden);
1959              }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1960                return UP_HOF; /* hierarchical authorisation failed */
1961              }
1962            }else{ /* exact_match_routes == NULL */
1963              /* then we have to look for less specific route objs */
1964              less_spec_routes = get_less_spec_routes(new_object);
1965              if(less_spec_routes != NULL){
1966                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
1967                less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners, 
1968                                              get_mnt_lowers_from_list(less_spec_routes));
1969                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
1970                if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
1971                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
1972                  return UP_AUF; /* auth failed */
1973                }
1974                if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1975                  /* then, check mnt_bys of the route itself */
1976                  new_mntners = get_mntners(new_object);
1977                  new_auth_vector = get_auth_vector(new_mntners);
1978                  if(new_mntners != NULL && new_auth_vector == NULL){
1979                    /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1980                    return UP_AUF; /* auth failed */
1981                  }
1982                  return authorise(new_auth_vector, credentials, overriden);
1983                }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1984                  return UP_HOF; /* hierarchical authorisation failed */
1985                }
1986             }else{/* less_spec_routes == NULL */
1987                /* so, we have to get the exact match inetnum */
1988                exact_match_inetnum = get_exact_match_inetnum(new_object);
1989                if(exact_match_inetnum != NULL){
1990                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
1991                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
1992                  if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
1993                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
1994                    return UP_AUF; /* auth failed */
1995                  }
1996                  if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
1997                    /* then, check mnt_bys of the route itself */
1998                    new_mntners = get_mntners(new_object);
1999                    new_auth_vector = get_auth_vector(new_mntners);
2000                    if(new_mntners != NULL && new_auth_vector == NULL){
2001                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2002                      return UP_AUF; /* auth failed */
2003                    }
2004                    return authorise(new_auth_vector, credentials, overriden);
2005                  }else{
2006                    return UP_HOF; /* hierarchical authorisation failed */
2007                  }
2008                }else{/* exact_match_inetnum == NULL */
2009                  /* then, we will try to find less spec inetnums */
2010                  less_spec_inetnum = get_less_spec_inetnum(new_object);
2011                  if(less_spec_inetnum != NULL){
2012                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
2013                    less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners, 
2014                                   get_mnt_lowers(less_spec_inetnum));
2015                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
2016                    if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
2017                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
2018                      return UP_AUF; /* auth failed */
2019                    }
2020                    if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
2021                      /* then, check mnt_bys of the route itself */
2022                      new_mntners = get_mntners(new_object);
2023                      new_auth_vector = get_auth_vector(new_mntners);
2024                      if(new_mntners != NULL && new_auth_vector == NULL){
2025                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2026                        return UP_AUF; /* auth failed */
2027                      }
2028                      return authorise(new_auth_vector, credentials, overriden);
2029                    }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
2030                      return UP_HOF; /* hierarchical authorisation failed */
2031                    }
2032                  }else{/* less_spec_inetnum == NULL */
2033                    /* now that we couldn't find any route or inetnum object
2034                       to be used in authentication. So, only if the auth is
2035                       overriden the object will be created. */
2036                    if(overriden){
2037                      return UP_AUTH_OK; 
2038                    }else{
2039                      return UP_HOF; /* hierarchical authorisation failed */
2040                    }
2041                  }
2042                }
2043              }
2044            }
2045          }else{/* ! aut_num_auth_OK */
2046            return UP_HOF; /* hierarchical auth failed */
2047          }
2048 
2049        }
2050           
2051      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2052        old_mntners = get_mntners(old_object);
2053        old_auth_vector = get_auth_vector(old_mntners);
2054        if(old_mntners != NULL && old_auth_vector == NULL){
2055          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2056          return UP_AUF; /* auth failed */
2057        }
2058        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2059          return authorise(old_auth_vector, credentials, overriden);
2060        }else{
2061          new_mntners = get_mntners(new_object);
2062          new_auth_vector = get_auth_vector(new_mntners);
2063          if(new_mntners != NULL && new_auth_vector == NULL){
2064            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2065            return UP_AUF; /* auth failed */
2066          }
2067          return authorise(new_auth_vector, credentials, overriden);
2068        }
2069      }else{ /* both are NULL, mustn't happen */
2070          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
2071          return UP_INT; /* internal error */
2072      }
2073    }
2074 
2075 
2076    /*  
2077     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types 
2078     */
2079    else if(strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
2080            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
2081            strcmp(type,"route-set")    == 0 ){
2082      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2083        old_mntners = get_mntners(old_object);
2084        old_auth_vector = get_auth_vector(old_mntners);
2085        if(old_mntners != NULL && old_auth_vector == NULL){
2086          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2087          return UP_AUF; /* auth failed */
2088        }
2089        return authorise(old_auth_vector, credentials, overriden);
2090      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2091         code = set_object->scan(new_object, strlen(new_object));
2092         set_name = get_search_key(set_object, type, new_object);
2093        if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
2094          new_mntners = get_mntners(new_object);
2095          new_auth_vector = get_auth_vector(new_mntners);
2096          if(new_mntners != NULL && new_auth_vector == NULL){
2097            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2098            return UP_AUF; /* auth failed */
2099          }
2100          return authorise(new_auth_vector, credentials, overriden);
2101        }else{/* the name is hierarchical */
2102          less_specific_object = get_less_specific_set(new_object, type);
2103          if(less_specific_object != NULL){/* such an object exists */
2104            temp_obj = new Object();
2105            code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
2106            less_specific_object_type = get_type(temp_obj);
2107            delete(temp_obj);
2108            if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
2109              less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2110              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2111              if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2112                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
2113               return UP_AUF; /* auth failed */
2114              }
2115              if(less_specific_auth_vector != NULL){
2116                return authorise(less_specific_auth_vector, credentials, overriden);
2117              }else{/* the less specific object doesn't contain any mnt-lower */
2118                less_specific_mntners = get_mntners(less_specific_object);
2119                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2120                if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2121                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2122                  return UP_AUF; /* auth failed */
2123                }
2124                if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs, 
2125                                                         use them  */
2126                    return authorise(less_specific_auth_vector, credentials, overriden);
2127                }else{/* the less specific object doesn't contain any mnt-by either */
2128                  if(overriden){
2129                    return UP_AUTH_OK; 
2130                  }else{
2131                    return UP_HOF; /* hierarchical authorisation failed */
2132                  }
2133                }
2134              }
2135            }else{ /* this is _not_ an aut-num object*/
2136              less_specific_mntners = get_mntners(less_specific_object);
2137              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2138              if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2139                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2140                return UP_AUF; /* auth failed */
2141              }
2142              if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
2143                return authorise(less_specific_auth_vector, credentials, overriden);
2144              }else{
2145                if(overriden){
2146                  return UP_AUTH_OK; 
2147                }else{
2148                  return UP_HOF; /* hierarchical authorisation failed */
2149                }
2150              }
2151            }
2152 
2153          }else{/* we don't have a less specific of this set object in the DB  */
2154            return UP_HOF; /* hierarchical authorisation failed */
2155          }
2156        }
2157      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2158        old_mntners = get_mntners(old_object);
2159        old_auth_vector = get_auth_vector(old_mntners);
2160        if(old_mntners != NULL && old_auth_vector == NULL){
2161          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2162          return UP_AUF; /* auth failed */
2163        }
2164        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2165          return authorise(old_auth_vector, credentials, overriden);
2166        }else{
2167          new_mntners = get_mntners(new_object);
2168          new_auth_vector = get_auth_vector(new_mntners);
2169          if(new_mntners != NULL && new_auth_vector == NULL){
2170            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2171            return UP_AUF; /* auth failed */
2172          }
2173          return authorise(new_auth_vector, credentials, overriden);
2174        }
2175      }else{ /* both are NULL, mustn't happen */
2176          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
2177          return UP_INT; /* internal error */
2178      }
2179    
2180 
2181 
2182 
2183 
2184    }else{ /* We exhausted all object classes. If we are here, then there is a problem */
2185      cout << "check_auth: This type '" << type << "' is unknown" << endl;
2186      return UP_NIY; /* not implemented yet */
2187    }
2188    return UP_AUF; /* if we come to this point, then auth failed */ 
2189 }
2190 
2191 
2192 
2193 
2194 
2195 
2196 /* Gets the old version of the given "arg" object, which is in char * format
2197    and returns the old version again in char * format */
2198 
2199 char * get_old_version(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2200 
2201     bool code = true;
2202     char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2203     Object *o;
2204     o = new Object;
2205     char *result = NULL, *origin = NULL;
2206     
2207     error = 0; 
2208     code = o->scan(arg,strlen(arg));
2209     type = get_type(o);
2210     primary_search_key = get_search_key(o, type, arg);
2211     if(tracing) {
2212       cout << "type=" << type << endl;
2213       cout << "primary_search_key=" << primary_search_key << endl;
2214     }
2215     /* prepare the search string */
2216     //search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2217     //                                      + strlen(type) + 1);
2218     /* if the object is a pn ro a ro object, then get all pn/ro's with the
2219        same NIC hdl */
2220     if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2221       /* prepare the search string */
2222       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2223                                           + strlen("person,role") + 1);
2224       sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2225     }else{
2226       /* prepare the search string */
2227       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2228                                           + strlen(type) + 1);
2229       sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2230     }
2231     result = send_and_get(QUERY_HOST, QUERY_PORT, search_string);
2232     if(tracing) {
2233       cout << "TRACING: send_and_get has returned" << endl;
2234       cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl 
2235            << result << endl;
2236     }
2237     /* Attention: here we must also check these:
2238          for ro/pn objects: The name must also the same. When the NIC hdl is the
2239                same but names are different, we must somehow return an error.
2240                Also, when we search for a person, we must also look for role objects
2241                (and vice versa) since the RIPupdate does not distinguish between
2242                role & person objects. We have to check it here.
2243          for rt objects: We also have to check the identicalness of origin
2244                attributes.                
2245                
2246           These are not yet implemented.     
2247                */
2248 
2249     if(strcmp(type,"route") == 0){
2250       if(tracing) {
2251         printf("TRACING: This is a route\n");
2252       }
2253       /* if this is a route, then we must filter out the routes with different
2254          origin attributes */
2255       origin = get_search_key(o, "origin", arg);
2256       if(tracing) {
2257         printf("TRACING: Got origin of route: %s\n", origin);
2258       }
2259       result = filter_out_diff_origins(result, origin);  
2260       if(tracing) {
2261         printf("TRACING: Filtered routes\n");
2262       }
2263     }
2264     // count the objects
2265     if(count_objects(result) == 0){
2266       result = NULL; /* we don't have such an object */
2267     }else if(count_objects(result) == 1){
2268       result = take_object(result);
2269       if(tracing) {
2270       cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2271       }
2272     }else{ /* we have more than one objects, error! */
2273       error = UP_MOR;
2274       return NULL;
2275     }
2276     return result;
2277 }
2278 
2279 
2280 
2281 
2282 /* Gets a credentials_struct whose 'from' field will be filled in and
2283    the mail header. Finds the 'From:' line in the header and sets
2284    the 'from' field to this line (all line, including the 'From:' string,
2285    since some users have put regexps which match the whole line in their
2286    'auth' attributes.) */
2287 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2288   char * header = strdup(arg);
2289   char * temp = (char *)malloc(strlen(header));
2290   while(index(header, '\n') != NULL){
2291     temp = strdup(header);
2292     temp[index(temp, '\n') - temp] = '\0';
2293     if(strstr(temp, "From:") == temp){
2294       if(tracing) {
2295         printf("TRACING: process_mail_header: Assigning %s\n", temp);
2296       }
2297       credentials_ptr->from = strdup(temp);
2298       free(temp);
2299       return;
2300     }
2301     header = header + (index(header, '\n') - header + 1);
2302   }
2303   free(temp);
2304 }
2305 
2306 
2307 
2308 
2309 
2310 
2311 void stringPack(char *dest, const char *source)
     /* [<][>][^][v][top][bottom][index][help] */
2312 {
2313 
2314   if(tracing) {
2315     printf("TRACING: stringPack running\n");
2316   }
2317         
2318 
2319 
2320 /*----------------------------------------------------------------------*\
2321 
2322 *  Function to rewrite a line of text with only one blankspace between  *
2323 *  each word.
2324 *
2325 
2326 \*----------------------------------------------------------------------*/
2327 
2328 
2329 /*
2330  * This while loop continues until the NULL character is copied into
2331  * the destination string.  If a tab character is copied into the
2332  * destination string, it is replaced with a blank-space character.
2333  *
2334  * Multiple blank-space and/or tab characters are skipped in the source
2335  * string until any other character is found.
2336  */
2337 
2338         while (1)
2339                 {
2340                 *dest = *source;
2341 
2342                 if (*dest == '\t')
2343                         (*dest = ' ');
2344 
2345                 /* Exit if have copied the end of the string. */
2346                 if (*dest == '\0')
2347                         return;
2348 
2349 /*
2350  * If the source character was a blank-space or a tab, move to the next
2351  * source character.  While the source character is a blank-space or a
2352  * tab, move to the next character (i.e. ignore these characters).  When
2353  * any other character is found in the source string, move to the next
2354  * element of the destination string.
2355  *
2356  * Otherwise, simultaneously, move to the next elements of the destination
2357  * and the source strings.
2358  */
2359 
2360 
2361 
2362                 if ( (*source == ' ') || (*source == '\t') )
2363                         {
2364                         ++source;
2365                         while ( (*source == ' ') || (*source == '\t') )
2366                                 {
2367                                 ++source;
2368                                 }
2369 
2370                         ++dest;
2371                         }
2372                 else
2373                         {
2374                         ++dest;
2375                         ++source;
2376                         }
2377                 }
2378 }
2379 
2380 /* strips lines beginning with "delete:" off  */
2381 char * delete_delete_attrib(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2382 
2383     char ** temp = NULL;
2384     char * string = NULL;
2385     int i;
2386 
2387     if(arg == NULL){
2388        return NULL;
2389     }
2390 
2391     /* split the string into lines */
2392     temp = g_strsplit (arg, "\n", 0);
2393 
2394     for(i=0; temp[i] != NULL; i++){
2395       /* if the line begins with "delete:", then do not copy it */
2396       if(strstr(temp[i], "delete:") != temp[i]){
2397         //printf("DEBUG: delete_delete_attrib: temp[i] = %s\n", temp[i]);
2398         if(string == NULL){
2399           string = strdup(temp[i]);
2400         }else{
2401           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 1);
2402           string = strcat(string, "\n");
2403           string = strcat(string, temp[i]);
2404         }
2405       }
2406     }
2407     g_strfreev(temp);
2408     return string;
2409 }
2410 
2411 
2412 
2413 int identical(const char * old_version, const char * new_version){
     /* [<][>][^][v][top][bottom][index][help] */
2414   char * arg1 = strdup(old_version);
2415   char * arg2 = strdup(new_version);
2416   int result = 0;
2417   char *temp1, *temp2; 
2418 
2419 
2420   arg1 = g_strstrip(arg1);
2421   arg2 = g_strstrip(arg2);
2422 
2423   /* delete the 'delete:' attrib */
2424   arg2 = delete_delete_attrib(arg2);
2425   /* convert tabs to white spaces */
2426   arg1 = g_strdelimit(arg1, "\t", ' ');
2427   arg2 = g_strdelimit(arg2, "\t", ' ');
2428   
2429   temp1 = (char *)malloc(strlen(arg1)); 
2430   temp2 = (char *)malloc(strlen(arg2));
2431   stringPack(temp1, arg1);
2432   stringPack(temp2, arg2);
2433 
2434   result = strcmp(temp1, temp2);
2435   //printf("DEBUG: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2436   free(arg1);
2437   free(arg2);
2438   free(temp1);
2439   free(temp2);
2440   if(result  == 0){
2441     if(tracing) {
2442       printf("TRACING: identical returning 1\n");
2443     }
2444     return 1;
2445   }else{
2446     if(tracing) {
2447       printf("TRACING: identical returning 0\n");
2448     }
2449     return 0;
2450   }
2451 }
2452 
2453 
2454 
2455 
2456 
2457 
2458 /* constructs an initials string from a given name (for NIC hdl generation) */
2459 char * find_initials(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2460 
2461    char * temp, * temp2;
2462    char * initials = NULL;
2463    int len, i;
2464    char ** vector;
2465 
2466    temp = strdup(arg);
2467    g_strstrip(temp);
2468    temp2 = (char *)malloc(strlen(temp) + 1);
2469    stringPack(temp2, temp);
2470    vector = g_strsplit(temp2, " ", 0);
2471    for(i = 0; vector[i] != NULL && i < 4; i++){
2472      //printf("%i\n",i);
2473      if(strlen(vector[i]) > 0){
2474        if(initials == NULL){
2475          initials = (char *)malloc(2);
2476          initials[0] = vector[i][0]; initials[1] = '\0';
2477        }else{
2478          len = strlen(initials);
2479          initials = (char *)realloc(initials, len + 2 );
2480          initials[len] = vector[i][0];
2481          initials[len + 1] = '\0';
2482        }
2483      }
2484    }
2485    free(temp);free(temp2);g_strfreev(vector);
2486    return initials;
2487 }
2488 
2489 
2490 
2491 
2492 
2493 /*  Gets the letter combination to be used in the automatically
2494     generated NIc handle. It the letter combination is specified
2495     in the AUTO NIC handle, return that. If not, return NULL
2496     (in which case the initials of the name must be used) */
2497 char * get_combination_from_autonic(const char * autonic){
     /* [<][>][^][v][top][bottom][index][help] */
2498 
2499   GString * temp;
2500   char * str = NULL;
2501 
2502   temp = g_string_new(autonic);
2503   temp = g_string_up(temp);
2504   temp = g_string_erase(temp, 0, strlen("AUTO-"));
2505   /* delete all digits from the beginning of the string */
2506   while(temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9')){
2507     temp = g_string_erase(temp, 0, 1);
2508   }
2509   if(temp->len == 0){
2510     g_string_free(temp, TRUE);
2511     return NULL;
2512   }else{
2513     str = temp->str;
2514     g_string_free(temp, FALSE);
2515     return str;
2516   }
2517 
2518 }
2519 
2520 
2521 
2522 
2523 
2524 
2525 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2526    and  modifies the nic-hdl: attribute, returns the new object.
2527    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2528    auto_nic is set to "AUTO-1"
2529    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2530 #if 0
2531 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
     /* [<][>][^][v][top][bottom][index][help] */
2532 
2533   GString* temp_string; 
2534   char * to_be_returned = NULL;
2535   char * person_role_name= NULL;
2536   char * initials = NULL;
2537   char ** temp = NULL;
2538   int i, pos;
2539   Object * o = new Object;
2540 
2541   temp = g_strsplit(arg, "\n", 0);
2542 
2543   for(i = 0; temp[i] != NULL; i++){
2544     //printf("Line: %s\n", temp[i]);
2545     if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2546       temp_string = g_string_new(temp[i]);
2547       if(strstr(temp_string->str, "AUTO-") != NULL){
2548         auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "AUTO-"), 
2549             temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-") );
2550         auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-")] = '\0';
2551         g_strstrip(auto_nic_hdl);
2552         printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2553         pos = strstr(temp_string->str, "AUTO-") - temp_string->str;
2554         temp_string = g_string_erase(temp_string,
2555             strstr(temp_string->str, "AUTO-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2556         
2557         temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2558         temp_string = g_string_insert(temp_string, pos, "*-");
2559         o->scan(arg, strlen(arg));
2560         person_role_name = get_attribute(o, get_type(o), arg);
2561         delete(o);
2562         initials = find_initials(person_role_name);
2563         free(person_role_name);
2564         temp_string = g_string_insert(temp_string, pos, initials);
2565         free(initials);
2566         
2567         if(to_be_returned == NULL){
2568           to_be_returned = strdup(temp_string->str);
2569           g_string_free(temp_string, TRUE);
2570         }else{
2571           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2572           to_be_returned = strcat(to_be_returned, "\n");
2573           to_be_returned = strcat(to_be_returned, temp_string->str);
2574           g_string_free(temp_string, TRUE);
2575         }
2576       }else{
2577         if(to_be_returned == NULL){
2578           to_be_returned = strdup(temp[i]);
2579         }else{
2580           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2581           to_be_returned = strcat(to_be_returned, "\n");
2582           to_be_returned = strcat(to_be_returned, temp[i]);
2583         }
2584       }
2585     }else{/* if it doesn't begin with nic-hdl */
2586         if(to_be_returned == NULL){
2587           to_be_returned = strdup(temp[i]);
2588         }else{
2589           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2590           strcat(to_be_returned, "\n");
2591           strcat(to_be_returned, temp[i]);
2592         }
2593 
2594     }
2595 
2596   }
2597   g_strfreev (temp);
2598   return to_be_returned;
2599 }
2600 #endif
2601 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
     /* [<][>][^][v][top][bottom][index][help] */
2602 
2603   GString* temp_string; 
2604   char * to_be_returned = NULL;
2605   char * person_role_name= NULL;
2606   char * initials = NULL;
2607   char ** temp = NULL;
2608   int i, pos;
2609   Object * o = new Object;
2610 
2611   temp = g_strsplit(arg, "\n", 0);
2612 
2613   for(i = 0; temp[i] != NULL; i++){
2614     //printf("Line: %s\n", temp[i]);
2615     if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2616       temp_string = g_string_new(temp[i]);
2617       temp_string = g_string_down(temp_string);
2618       if(strstr(temp_string->str, "auto-") != NULL){
2619         auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "auto-"), 
2620             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2621         auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")] = '\0';
2622         g_strstrip(auto_nic_hdl);
2623         printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2624         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2625         temp_string = g_string_erase(temp_string,
2626             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2627         
2628         temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2629         temp_string = g_string_insert(temp_string, pos, "*-");
2630         o->scan(arg, strlen(arg));
2631         person_role_name = get_attribute(o, get_type(o), arg);
2632         delete(o);
2633         /* if the letter combination is already specified, get it */
2634         initials = get_combination_from_autonic(auto_nic_hdl);
2635         /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
2636         if(initials == NULL){
2637           initials = find_initials(person_role_name);
2638         }
2639         free(person_role_name);
2640         temp_string = g_string_insert(temp_string, pos, initials);
2641         free(initials);
2642         
2643         if(to_be_returned == NULL){
2644           to_be_returned = strdup(temp_string->str);
2645           g_string_free(temp_string, TRUE);
2646         }else{
2647           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2648           to_be_returned = strcat(to_be_returned, "\n");
2649           to_be_returned = strcat(to_be_returned, temp_string->str);
2650           g_string_free(temp_string, TRUE);
2651         }
2652       }else{
2653         if(to_be_returned == NULL){
2654           to_be_returned = strdup(temp[i]);
2655         }else{
2656           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2657           to_be_returned = strcat(to_be_returned, "\n");
2658           to_be_returned = strcat(to_be_returned, temp[i]);
2659         }
2660       }
2661     }else{/* if it doesn't begin with nic-hdl */
2662         if(to_be_returned == NULL){
2663           to_be_returned = strdup(temp[i]);
2664         }else{
2665           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2666           strcat(to_be_returned, "\n");
2667           strcat(to_be_returned, temp[i]);
2668         }
2669 
2670     }
2671 
2672   }
2673   g_strfreev (temp);
2674   return to_be_returned;
2675 }
2676 
2677 
2678 
2679 /* replaces the refs to AUTO NIC hdls with the assigned one */
2680 
2681 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
     /* [<][>][^][v][top][bottom][index][help] */
2682 
2683   char * auto_nic = NULL;
2684   GString* temp_string; 
2685   char * to_be_returned = NULL;
2686   char ** temp = NULL;
2687   int i, pos;
2688 
2689   //printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is running\n");
2690 
2691   temp = g_strsplit(arg, "\n", 0);
2692 
2693   for(i = 0; temp[i] != NULL; i++){
2694     //printf("Line: %s\n", temp[i]);
2695     if(   strstr(temp[i], "admin-c:") == temp[i]    /*    if it starts with admin-c */
2696        || strstr(temp[i], "tech-c:" ) == temp[i]    /* or if it starts with tech-c */
2697        || strstr(temp[i], "zone-c:" ) == temp[i]    /* or if it starts with zone-c */
2698        || strstr(temp[i], "author:" ) == temp[i]){  /* or if it starts with author */
2699       temp_string = g_string_new(temp[i]);
2700       temp_string = g_string_down(temp_string);
2701       if(strstr(temp_string->str, "auto-") != NULL){
2702         auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")  + 1);
2703         auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"), 
2704             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2705         auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0'; 
2706         g_strstrip(auto_nic);
2707         printf("DEBUG: auto_nic is [%s]\n", auto_nic);
2708         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2709         temp_string = g_string_erase(temp_string,
2710             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
2711         
2712         //temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2713         //temp_string = g_string_insert(temp_string, pos, "*-");
2714         /* if we have this AUTO NIC hdl in the hash, put it. */
2715         if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
2716           temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
2717         }else{/* else, return 0 immediately */
2718           g_strfreev (temp);
2719           return NULL;
2720         }
2721         
2722         if(to_be_returned == NULL){
2723           to_be_returned = strdup(temp_string->str);
2724           g_string_free(temp_string, TRUE);
2725         }else{
2726           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2727           to_be_returned = strcat(to_be_returned, "\n");
2728           to_be_returned = strcat(to_be_returned, temp_string->str);
2729           g_string_free(temp_string, TRUE);
2730         }
2731       }else{
2732         if(to_be_returned == NULL){
2733           to_be_returned = strdup(temp[i]);
2734         }else{
2735           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2736           to_be_returned = strcat(to_be_returned, "\n");
2737           to_be_returned = strcat(to_be_returned, temp[i]);
2738         }
2739       }
2740     }else{/* if it doesn't begin with ac,tc,ac or author */
2741         if(to_be_returned == NULL){
2742           to_be_returned = strdup(temp[i]);
2743         }else{
2744           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2745           strcat(to_be_returned, "\n");
2746           strcat(to_be_returned, temp[i]);
2747         }
2748 
2749     }
2750 
2751   }
2752   g_strfreev (temp);
2753   //free(arg);
2754   //changed_obj = strdup(to_be_returned);
2755   //free(to_be_returned);
2756   printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
2757   return to_be_returned;
2758 }
2759 
2760 
2761 
2762 
2763 
2764 
2765 
2766 
2767 /* Takes an object in a char * , and returns 1 if this object has 
2768    an AUTO NIC handle. Otherwise, returns 0 */
2769 int has_AUTO_NIC_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
2770 
2771   Object * o = new Object();
2772   GSList * attributes = NULL;
2773   bool code;
2774 
2775   code = o->scan(object, strlen(object));
2776 
2777   if(code && !(o->isDeleted)){
2778     attributes = get_attributes(o, "nic-hdl", object);
2779     if(attributes != NULL){
2780       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2781         g_slist_free(attributes);
2782         delete(o);
2783         return 1;
2784       }
2785     }
2786     /* if control reaches here, then we will return 0 */
2787     g_slist_free(attributes);
2788     delete(o);
2789     return 0; 
2790   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
2791            it contains refs to AUTO NIC hdls. */
2792     delete(o); 
2793     return 0;        
2794   }
2795     
2796 }
2797 
2798 
2799 /* Takes an object in a char * , and returns 1 if this object contains
2800    a reference to an AUTO NIC handle. Otherwise, returns 0 */
2801 int has_ref_to_AUTO_nic_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
2802 
2803   Object * o = new Object();
2804   GSList * attributes = NULL;
2805   bool code;
2806 
2807   code = o->scan(object, strlen(object));
2808 
2809   if(code && !(o->isDeleted)){
2810     attributes = get_attributes(o, "admin-c", object);
2811     if(attributes != NULL){
2812       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2813         g_slist_free(attributes);
2814         delete(o);
2815         return 1;
2816       }
2817     }
2818     g_slist_free(attributes);
2819     attributes = get_attributes(o, "tech-c", object);
2820     if(attributes != NULL){
2821       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2822         g_slist_free(attributes);
2823         delete(o);
2824         return 1;
2825       }
2826     }
2827 
2828     g_slist_free(attributes);
2829     attributes = get_attributes(o, "zone-c", object);
2830     if(attributes != NULL){
2831       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2832         g_slist_free(attributes);
2833         delete(o);
2834         return 1;
2835       }
2836     }
2837     g_slist_free(attributes);
2838     attributes = get_attributes(o, "author", object);
2839     if(attributes != NULL){
2840       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2841         g_slist_free(attributes);
2842         delete(o);
2843         return 1;
2844       }
2845     }
2846     /* if control reaches here, then we will return 0 */
2847     delete(o);
2848     return 0; 
2849   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
2850            it contains refs to AUTO NIC hdls. */
2851     delete(o); 
2852     return 0;        
2853   }
2854     
2855 }
2856 
2857 
2858 #if 0
2859 /* Checks the object's syntax, retrives the old version of it from the db, 
2860    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
2861    integrity is checked, and the object is really committed to the db.
2862    
2863      Arguments:
2864         char * arg: The object,
2865         credentials_struct credentials: The struct containing the credentials, such as 
2866           'From:' field of the e-mail update,
2867         GHashTable * NIC_hdl_hash: A hash containing 
2868         char * ack_file_name:  The file name, to be used to store ACK message 
2869 */
2870 
2871 
2872 
2873 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name){
     /* [<][>][^][v][top][bottom][index][help] */
2874     bool code = true;
2875     Object *o;
2876     char * old_version = NULL;
2877     o = new Object;
2878     int result = 0;
2879     int result_from_RIPupd = 0;
2880     char * auto_nic = NULL;
2881     char * changed_obj = NULL;
2882     char * obj_with_AUTO_NIC_hdl;
2883     char * assigned_NIC;
2884 
2885     char * value = NULL;/* these two are for */
2886     Attr * attr;        /* ack messages only */ 
2887     
2888     if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
2889        /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
2890        if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
2891          return UP_ANE; /* AUTO NIC hdl error */
2892        };
2893     }
2894     
2895     code = o->scan(arg,strlen(arg));
2896     if(code){
2897       /* is the object to be deleted? */
2898       if(o->isDeleted){
2899         //printf("DEBUG: This object is to be deleted\n"); 
2900         old_version = get_old_version(arg);
2901         if(old_version == NULL){ // the object doesn't exist in the db!
2902           //add_to_ack("\nDeletion Failed: Object doesn't exist", ack_file_name);
2903           //add_to_ack(o->type->getName(), ack_file_name);
2904           //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2905           AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s] %s\nObject doesn't exist\n", 
2906                         o->type->getName(), get_search_key(o, o->type->getName(), arg));
2907           return UP_NSO; /* no such object */
2908         }else {/* the object is in the db */
2909           if(identical(old_version, arg)){/* if the old & new versions are identical */
2910             result = check_auth(NULL, old_version, o->type->getName(), credentials);
2911             if(result == UP_AUTH_OK){ 
2912               if(tracing) {
2913                 printf("TRACING: Will send the obj to be deleted\n");
2914               }
2915               result_from_RIPupd = send_object_db(arg, NULL, "DEL");
2916               if(result_from_RIPupd == 0){
2917                 //add_to_ack("\nDeletion succeeded", ack_file_name);
2918                 //add_to_ack(o->type->getName(), ack_file_name);
2919                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2920                  AK_add_to_ack(ack_file_name, "\nDel OK: [%s] %s\n", 
2921                                o->type->getName(), get_search_key(o, o->type->getName(), arg));
2922               }else{
2923                 //add_to_ack("\nDeletion failed: Referential intergrity failure", ack_file_name);
2924                 //add_to_ack(o->type->getName(), ack_file_name);
2925                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2926                 AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s] %s\nReferential intergrity failure\n",
2927                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
2928               }
2929               result_from_RIPupd = 0;
2930             }else{ /* auth failed */
2931               if(tracing) {
2932                 printf("TRACING: Auth failed\n");
2933               }
2934               if(error_msg != NULL){
2935                   cout << error_msg << endl;
2936               }
2937               //add_to_ack("\nDeletion failed: Auth failed", ack_file_name);
2938               //add_to_ack(o->type->getName(), ack_file_name);
2939               //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2940               AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s]\n%s\nAuth failed\n",
2941                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
2942               return UP_AUF; /* Auth failed */
2943             } 
2944           }else{/* the new & old versions do not match */
2945             //add_to_ack("Deletion failed: new & old versions do not match", ack_file_name);
2946             AK_add_to_ack(ack_file_name, "\nDel FAILED: new & old versions do not match\n");
2947             return UP_NOM; /* new & old versions do not match */
2948           }
2949         }
2950       }else {/* the object is _not_ to be deleted */
2951         if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
2952           /* then its nic-hdl attribute must be modified so that RIPupdate
2953              would understand that it must assign a NIC handle to it */
2954           /* but first check the auth */
2955           result = check_auth(arg, NULL, o->type->getName(), credentials);
2956           if(result == UP_AUTH_OK){
2957             if(tracing) {                                
2958                 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
2959             }
2960             auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
2961             obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
2962             if(tracing) {  
2963               printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
2964               printf("TRACING: Will send the obj to be added\n");
2965             }
2966             assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
2967             result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
2968             if(result_from_RIPupd == 0){
2969               //add_to_ack("\nCreation succeeded", ack_file_name);
2970               //add_to_ack(o->type->getName(), ack_file_name);
2971               //add_to_ack(assigned_NIC, ack_file_name);
2972               AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", 
2973                             o->type->getName(), assigned_NIC);
2974             }else{
2975               //add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name);
2976               //add_to_ack(o->type->getName(), ack_file_name);
2977               //add_to_ack(arg, ack_file_name);
2978               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
2979                             o->type->getName(), arg);
2980             }
2981             result_from_RIPupd = 0;
2982             if(tracing && assigned_NIC != NULL) {  
2983               printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
2984             }
2985             if(assigned_NIC != NULL){
2986               printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
2987               g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
2988               printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
2989             }
2990             
2991           }else{
2992             // auth failed !
2993             if(tracing) {
2994               printf("TRACING: Auth failed\n");
2995             }
2996             if(error_msg != NULL){
2997               cout << error_msg << endl;
2998             }
2999             ER_perror(0, result, "");
3000             //add_to_ack("\nCreation failed: Auth failed", ack_file_name);
3001             //add_to_ack(o->type->getName(), ack_file_name);
3002             //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3003             AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
3004                           o->type->getName(), get_search_key(o, o->type->getName(), arg));
3005             return UP_AUF; /* Auth failed */
3006           }
3007         }
3008         else{ 
3009           old_version = get_old_version(arg);
3010           if(old_version != NULL){/* so, this is an update operation */
3011             result = check_auth(arg, old_version, o->type->getName(), credentials);    
3012             if(result == UP_AUTH_OK){
3013               if(tracing) {                                
3014                 printf("TRACING: Will send the obj to be updated\n");
3015               }
3016               result_from_RIPupd = send_object_db(arg, NULL, "UPD");
3017               if(result_from_RIPupd == 0){
3018                 //add_to_ack("\nUpdate succeeded", ack_file_name);
3019                 //add_to_ack(o->type->getName(), ack_file_name);
3020                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3021                 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
3022                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3023               }else{
3024                 //add_to_ack("\nUpdate failed: Referential integrity failure", ack_file_name);
3025                 //add_to_ack(o->type->getName(), ack_file_name);
3026                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3027                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
3028                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3029               }
3030               result_from_RIPupd = 0;
3031             }else{
3032               // auth failed !
3033               if(tracing) {
3034                 printf("TRACING: Auth failed\n");
3035               }
3036               if(error_msg != NULL){
3037                 cout << error_msg << endl;
3038               }
3039               //add_to_ack("\nUpdate failed: Auth failed", ack_file_name);
3040               //add_to_ack(o->type->getName(), ack_file_name);
3041               //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3042               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
3043                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
3044               return UP_AUF; /* Auth failed */
3045             }
3046           }else { /* old_version  == NULL, so, creation */
3047             result = check_auth(arg, NULL, o->type->getName(), credentials);
3048             if(result == UP_AUTH_OK){ 
3049               if(tracing) {                                
3050                 printf("TRACING: Will send the obj to be added\n");
3051               }
3052               result_from_RIPupd = send_object_db(arg, NULL, "ADD");
3053               if(result_from_RIPupd == 0){
3054                 //add_to_ack("\nCreation succeeded", ack_file_name); 
3055                 //add_to_ack(o->type->getName(), ack_file_name);
3056                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3057                 AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
3058                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3059               }else{
3060                 //add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name); 
3061                 //add_to_ack(o->type->getName(), ack_file_name);
3062                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3063                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
3064                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3065               }
3066               result_from_RIPupd = 0;
3067             }else{
3068               // auth failed !
3069               if(tracing) {
3070                 printf("TRACING: Auth failed\n");
3071               }
3072               if(error_msg != NULL){
3073                 cout << error_msg << endl;
3074               }
3075               ER_perror(0, result, "");
3076               //add_to_ack("\nCreation failed: Auth failed", ack_file_name);
3077               //add_to_ack(o->type->getName(), ack_file_name);
3078               //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3079               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
3080                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
3081               return UP_AUF; /* Auth failed */
3082             }
3083           } 
3084         }
3085       }
3086     }else{// even if obj doesn't parse properly, it may be a legacy object
3087           // which the user wants to delete...
3088        if(tracing){   
3089          printf("TRACING: Object didn't parse\n");   
3090        }
3091        //add_to_ack("\nFailed: Syntax error in object", ack_file_name);
3092        //add_to_ack(arg, ack_file_name);   
3093        AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
3094        //////////////////////////////////
3095        if(o->attrs.head() != NULL){
3096          for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
3097            value = (char*)malloc((*attr).len );
3098            strncpy(value, (char *)(arg+attr->offset) ,
3099              attr->len - 1);
3100            value[attr->len - 1] = '\0';
3101            //add_to_ack(value, ack_file_name);
3102            AK_add_to_ack(ack_file_name, "%s\n", value);
3103            if(!attr->errors.empty()){
3104              //add_to_ack_string(attr->errors, ack_file_name);
3105              //cout << "Error: " << attr->errors << endl;
3106              AK_add_to_ack_string(ack_file_name, attr->errors);
3107            }
3108            free(value);
3109           }
3110         }
3111         if(o->has_error){
3112           //add_to_ack_string(o->errors, ack_file_name);
3113           //cout << "Object Error: " << o->errors << endl;
3114           AK_add_to_ack_string(ack_file_name, o->errors);
3115         }
3116        //////////////////////////////////
3117        return UP_NIY; /* Not implemented yet */
3118     }
3119 }
3120 
3121 
3122 #endif
3123 
3124 /* Gets the "From" line of the incoming mail message and finds out an 
3125    address to send the acknowledgement */
3126 char * find_to_address(const char * from_line){
     /* [<][>][^][v][top][bottom][index][help] */
3127   char * pos1 = NULL, * pos2 = NULL;
3128   char * temp = NULL;
3129   
3130   if(from_line == NULL){
3131     return NULL;
3132   }
3133   if(strstr(from_line, "From:") != from_line){/* there is a problem, the line must start with 
3134                                                  "From:" */
3135     fprintf(stderr, "The line doesn't start with 'From:'\n");
3136     return NULL;
3137   }
3138   temp = strdup(from_line + strlen("From:"));
3139   g_strstrip(temp);
3140   if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
3141     pos1 = index(temp, '<');
3142     pos2 = index(temp, '>');
3143     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
3144     temp[pos2 - pos1 - 1] = '\0';
3145     printf("DEBUG: find_to_address\n");
3146     printf("DEBUG: find_to_address temp=[%s]\n", temp);
3147     return temp;
3148   }else{/* the line contains only the address, then */
3149    return temp; 
3150   }
3151 }  
3152 

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