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.30 $
   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->auth = argument;
1280        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1281      }else{
1282        cout << "DEBUG: Error: invalid auth attrib: " << auth_attrib << endl;
1283        return NULL;
1284      }
1285    }
1286    free(auth_attrib_uppercase);
1287    free(auth_attrib); 
1288    return list_of_auth_struct;
1289 
1290 }
1291 
1292 
1293 
1294 
1295 
1296 
1297 
1298 
1299 
1300 /* Gets a list of mntner names, retrieves those mntners from
1301    the database and extracts the 'auth' attributes, and
1302    constructs the authorisation vector, which is a GSList of
1303    struct auth_struct */
1304 
1305 GSList * get_auth_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1306   GSList * list_of_auths = NULL;
1307   GSList * next = NULL;
1308   GSList * to_be_returned = NULL;
1309   char * query_string = NULL, * result = NULL, * object = NULL;
1310   GSList * temp;
1311 
1312   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1313     if(tracing) {
1314       cout << "=====" << endl << "Got a mntner" << endl;
1315       cout << (char *)next->data << endl;
1316     }
1317     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1318     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1319     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1320     if(count_objects(result) == 0){
1321       //if(tracing) {
1322       //  cout << "No such maintainer, exiting" << endl;
1323       //}
1324       //exit(1);
1325       /* no such maintainer */
1326       return NULL;
1327     }else if(count_objects(result) > 1){
1328       if(tracing) {
1329         cout << "More than one objects returned" << endl;
1330       }
1331     }else{ /* count_objects(result) == 1 */
1332       object = take_object(result);
1333       if(tracing) {
1334         printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1335       }
1336       temp = get_auths(object);
1337       if(tracing) {
1338         cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1339       }
1340       list_of_auths = g_slist_concat(list_of_auths, temp);
1341       if(tracing) {
1342         cout << "TRACING: get_auth_vector: list_of_auths has now " <<  g_slist_length(list_of_auths) << " nodes" << endl;
1343       }
1344       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1345       if(tracing) {
1346        cout << "TRACING: get_auth_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1347       }
1348       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1349     }
1350   }
1351   
1352   if(tracing) {  
1353     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1354   }
1355   return to_be_returned; 
1356 }
1357 
1358 
1359 
1360 
1361 
1362 
1363 
1364 /* Gets a list of mntner names, retrieves those mntners from
1365    the database and extracts the 'mnt-by' attributes, and
1366    returns them as a GSList */
1367 
1368 GSList * get_mntnfy_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1369   GSList * list_of_mntnfy = NULL;
1370   GSList * next = NULL;
1371   //GSList * to_be_returned = NULL;
1372   char * query_string = NULL, * result = NULL, * object = NULL;
1373   GSList * temp;
1374   
1375   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1376     if(tracing) {
1377       cout << "=====" << endl << "Got a mntner" << endl;
1378       cout << (char *)next->data << endl;
1379     }
1380     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1381     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1382     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1383     if(count_objects(result) == 0){
1384       /* no such maintainer */
1385     }else if(count_objects(result) > 1){
1386       if(tracing) {
1387         cout << "More than one objects returned" << endl;
1388       }
1389     }else{ /* count_objects(result) == 1 */
1390       object = take_object(result);
1391       if(tracing) {
1392         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1393       }
1394       temp = get_attr_list(object, "mnt-nfy");
1395       if(tracing) {
1396         cout << "TRACING: get_mntnfy_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1397       }
1398       list_of_mntnfy = g_slist_concat(list_of_mntnfy, temp);
1399       if(tracing) {
1400         cout << "TRACING: get_mntnfy_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_mntnfy) << " nodes" << endl;
1401       }
1402       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1403       //if(tracing) {
1404       // cout << "TRACING: get_mntnfy_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1405       //}
1406       //to_be_returned = add_to_auth_vector(to_be_returned, list_of_mntnfy, (char *)next->data);
1407     }
1408   }
1409   
1410   if(tracing) {  
1411     printf("TRACING: get_auth_vector: list_of_mntnfy has %i nodes\n", g_slist_length(list_of_mntnfy)); 
1412   }
1413   return list_of_mntnfy; 
1414 }
1415 
1416 
1417 
1418 
1419 
1420 
1421 /* Gets a list of mntner names, retrieves those mntners from
1422    the database and extracts the 'upd-to' attributes, and
1423    returns them as a GSList */
1424 
1425 GSList * get_updto_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1426   GSList * list_of_updto = NULL;
1427   GSList * next = NULL;
1428   //GSList * to_be_returned = NULL;
1429   char * query_string = NULL, * result = NULL, * object = NULL;
1430   GSList * temp;
1431   
1432   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1433     if(tracing) {
1434       cout << "=====" << endl << "Got a mntner" << endl;
1435       cout << (char *)next->data << endl;
1436     }
1437     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1438     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1439     result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1440     if(count_objects(result) == 0){
1441       /* no such maintainer */
1442     }else if(count_objects(result) > 1){
1443       if(tracing) {
1444         cout << "More than one objects returned" << endl;
1445       }
1446     }else{ /* count_objects(result) == 1 */
1447       object = take_object(result);
1448       if(tracing) {
1449         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1450       }
1451       temp = get_attr_list(object, "upd-to");
1452       if(tracing) {
1453         cout << "TRACING: get_updto_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1454       }
1455       list_of_updto = g_slist_concat(list_of_updto, temp);
1456       if(tracing) {
1457         cout << "TRACING: get_updto_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_updto) << " nodes" << endl;
1458       }
1459       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1460       //if(tracing) {
1461       // cout << "TRACING: get_mntnfy_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1462       //}
1463       //to_be_returned = add_to_auth_vector(to_be_returned, list_of_mntnfy, (char *)next->data);
1464     }
1465   }
1466   
1467   if(tracing) {  
1468     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_slist_length(list_of_updto)); 
1469   }
1470   return list_of_updto; 
1471 }
1472 
1473 
1474 
1475 
1476 
1477 
1478 
1479 
1480 
1481 
1482 /* gets one or more route objects filters out the ones which don't have the same
1483    origin as 'char * origin' argument */
1484 char * filter_out_diff_origins(char * objects, char * origin){
     /* [<][>][^][v][top][bottom][index][help] */
1485   GSList * object_list = NULL, * next =NULL;
1486   char * objects_to_be_returned = NULL;
1487   bool code;
1488   char * key = NULL;
1489   Object * o = new Object();
1490   
1491   
1492   if(tracing) {
1493     printf("TRACING: filter_out_diff_origins\n");
1494   }
1495 
1496   /* strip the lines beginning with '%' off */
1497   objects = strip_lines(objects);
1498   
1499   /* separate the objects, store them in a linked list */
1500   object_list = take_objects(objects);
1501 
1502   for(next = object_list; next != NULL; next = g_slist_next(next)){
1503     code = o->scan((char *)next->data, strlen((char *)next->data));
1504     key = get_search_key(o, "origin", (char *)next->data);
1505     if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1506       if(objects_to_be_returned == NULL){
1507         objects_to_be_returned = strdup((char *)next->data);
1508       }else{
1509         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
1510                       strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1511         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1512         objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1513       }
1514     }
1515   }
1516 
1517   delete(o);
1518   if(tracing) {
1519     if(objects_to_be_returned != NULL){
1520       printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1521     }else {
1522       printf("TRACING: filter_out_diff_origins: returning NULL\n");
1523       
1524     }
1525   }
1526   return objects_to_be_returned; 
1527   
1528 }
1529 
1530 
1531 
1532 
1533 /* Check authorisation
1534    Applies authorisation rules according to the object type 
1535    
1536    Arguments:
1537       char *new_object: the new object,
1538       char *old_object: the old object, as found in the database,
1539       char *type: type of the object
1540       credentials_struct credentials: a struct which
1541         contains credentials of the update, such as 'From:' field of
1542         the e-mail header and passwords in the update   */
1543 
1544 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
     /* [<][>][^][v][top][bottom][index][help] */
1545    
1546    GSList *old_mntners = NULL, *new_mntners = NULL;
1547    GSList *old_auths = NULL, *new_auths = NULL;
1548    GSList *as_block_mnt_lowers = NULL;
1549    GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1550    GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1551    GSList *less_specific_mntners = NULL;
1552    GSList *aut_num_maintainers = NULL;
1553    GSList *aut_num_auth_vector = NULL;
1554    GSList *exact_match_routes = NULL;  
1555    GSList *exact_match_routes_maintainers = NULL;
1556    GSList *exact_match_routes_auth_vector = NULL;
1557    GSList *less_spec_routes = NULL;
1558    GSList *less_spec_routes_mntners = NULL;
1559    GSList *less_spec_routes_auth_vector = NULL;
1560    GSList *exact_match_inetnum_mnt_routes = NULL;
1561    GSList *exact_match_inetnum_auth_vector = NULL;
1562    GSList *less_spec_inetnum_mntners = NULL;
1563    GSList *less_spec_inetnum_auth_vector = NULL;
1564    GSList *exact_match_intenum_auth_vector = NULL;
1565    GSList *exact_match_auth_vector = NULL;
1566     
1567    char *as_block_object = NULL, *less_specific_object = NULL;
1568    char *less_specific_domain = NULL;
1569    char *less_spec_inetnum = NULL;
1570    char *exact_match_inetnum = NULL;
1571    char *less_specific_object_type = NULL;
1572    char *override_string = NULL;
1573    char *set_name = NULL;
1574    char * aut_num_object = NULL;
1575    Object *set_object = new Object();
1576    Object *temp_obj;
1577    bool code;
1578    bool aut_num_auth_OK = false;
1579 
1580    int overriden = 0;
1581    
1582    /* first check if it is overriden or not. if overriden, check the override
1583       password. If it is correct, continue, setting "overriden" to 1. If not,   
1584       immediately exit returning ERR_UP_OVF                                   */
1585    override_string = get_override((new_object == NULL) ? old_object : new_object );
1586    if(override_string == NULL){ 
1587      overriden = 0;
1588    }else if(check_override(override_string) == OVR_OK){
1589      overriden = 1; /* authorisation is overriden */
1590    }else if(check_override(override_string) == UP_OVS){
1591      return UP_OVS; /* override syntax error --it must have at least two words */
1592    }else{
1593      return UP_OVF; /* override failed! */
1594    }
1595 
1596 
1597    /*  
1598     *  Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types 
1599     */
1600    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
1601       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
1602       strcmp(type,"key-cert") == 0 ){
1603      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1604        old_mntners = get_mntners(old_object);
1605        old_auth_vector = get_auth_vector(old_mntners);
1606        return authorise(old_auth_vector, credentials, overriden);
1607      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1608        new_mntners = get_mntners(new_object);
1609        new_auth_vector = get_auth_vector(new_mntners);
1610        if(new_mntners != NULL && new_auth_vector == NULL){
1611          /* then, the mntners in 'new_mntners' do not exist. Problem. */
1612          return UP_AUF; /* auth failed */
1613        }
1614        /*printf("DEBUG: check_auth: new_auth_vector has %i, new_mntners has %i nodes\n",
1615               g_slist_length(new_auth_vector) ,g_slist_length(new_mntners));*/
1616        return authorise(new_auth_vector, credentials, overriden);
1617      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1618        old_mntners = get_mntners(old_object);
1619        old_auth_vector = get_auth_vector(old_mntners);
1620        if(old_mntners != NULL && old_auth_vector == NULL){
1621          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1622          return UP_AUF; /* auth failed */
1623        }
1624        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1625          return authorise(old_auth_vector, credentials, overriden);
1626        }else{
1627          new_mntners = get_mntners(new_object);
1628          new_auth_vector = get_auth_vector(new_mntners);
1629          if(new_mntners != NULL && new_auth_vector == NULL){
1630            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1631            return UP_AUF; /* auth failed */
1632          }
1633          return authorise(new_auth_vector, credentials, overriden);
1634        }
1635      }else{ // both are NULL, mustn't happen
1636          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1637          return UP_INT; /* internal error */
1638      }
1639    }
1640 
1641    /*  
1642     *  Handle the "auth-num" type 
1643     */
1644    else if(strcmp(type,"aut-num")  == 0 ){
1645      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1646        old_mntners = get_mntners(old_object);
1647        old_auth_vector = get_auth_vector(old_mntners);
1648        if(old_mntners != NULL && old_auth_vector == NULL){
1649          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1650          return UP_AUF; /* auth failed */
1651        }
1652        return authorise(old_auth_vector, credentials, overriden);
1653      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1654        as_block_object = get_as_block(new_object);
1655        if(as_block_object == NULL ){
1656          return UP_ABN; /* As-block does not exist */
1657          }else{
1658            as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1659            as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1660            if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1661              /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1662              return UP_AUF; /* auth failed */
1663            }
1664          if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1665            new_mntners = get_mntners(new_object);
1666            new_auth_vector = get_auth_vector(new_mntners);
1667            if(new_mntners != NULL && new_auth_vector == NULL){
1668              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1669              return UP_AUF; /* auth failed */
1670            }
1671            return authorise(new_auth_vector, credentials, overriden);
1672          }else{
1673            return UP_HOF; /* hierarchical auth failed */
1674          }
1675        }
1676      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1677        old_mntners = get_mntners(old_object);
1678        old_auth_vector = get_auth_vector(old_mntners);
1679        if(old_mntners != NULL && old_auth_vector == NULL){
1680          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1681          return UP_AUF; /* auth failed */
1682        }
1683        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1684          return authorise(old_auth_vector, credentials, overriden);
1685        }else{
1686          new_mntners = get_mntners(new_object);
1687          new_auth_vector = get_auth_vector(new_mntners);
1688          if(new_mntners != NULL && new_auth_vector == NULL){
1689            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1690            return UP_AUF; /* auth failed */
1691          }
1692          return authorise(new_auth_vector, credentials, overriden);
1693        }
1694      }else{ /* both are NULL, mustn't happen */
1695          if(tracing) {
1696            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1697          } 
1698          return UP_INT; /* internal error */
1699      }
1700    } 
1701 
1702    /*  
1703     *  Handle the "mntner/as-block" types 
1704     */
1705    else if(strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 ){
1706      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1707        old_mntners = get_mntners(old_object);
1708        old_auth_vector = get_auth_vector(old_mntners);
1709        if(old_mntners != NULL && old_auth_vector == NULL){
1710          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1711          return UP_AUF; /* auth failed */
1712        }
1713        return authorise(old_auth_vector, credentials, overriden);
1714      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1715        if(overriden || test_mode){
1716          return UP_AUTH_OK; 
1717        }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
1718          if(tracing) {
1719            cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
1720          }
1721          return UP_AUF; /* authorisation failed */
1722        }
1723      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1724        old_mntners = get_mntners(old_object);
1725        old_auth_vector = get_auth_vector(old_mntners);
1726        if(old_mntners != NULL && old_auth_vector == NULL){
1727          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1728          return UP_AUF; /* auth failed */
1729        }
1730        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1731          return authorise(old_auth_vector, credentials, overriden);
1732        }else{
1733          new_mntners = get_mntners(new_object);
1734          new_auth_vector = get_auth_vector(new_mntners);
1735          if(new_mntners != NULL && new_auth_vector == NULL){
1736            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1737            return UP_AUF; /* auth failed */
1738          }
1739          return authorise(new_auth_vector, credentials, overriden);
1740        }
1741      }else{ // both are NULL, mustn't happen
1742          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1743          return UP_INT; /* internal error */
1744      }
1745    }
1746 
1747    /*  
1748     *  Handle the "inetnum/inet6num" types 
1749     */
1750    else if(strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 ){
1751      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1752        old_mntners = get_mntners(old_object);
1753        old_auth_vector = get_auth_vector(old_mntners);
1754        if(old_mntners != NULL && old_auth_vector == NULL){
1755          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1756          return UP_AUF; /* auth failed */
1757        }
1758        return authorise(old_auth_vector, credentials, overriden);
1759      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1760        less_specific_object = get_less_specific(new_object, type);
1761        if(less_specific_object == NULL){
1762          if(overriden){
1763            return UP_AUTH_OK; 
1764          }else{
1765            return UP_HOF; /* hierarchical authorisation failed */
1766          }
1767        }else{ /* if we got an inet(6)num object */
1768          less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1769          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1770          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1771            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1772            return UP_AUF; /* auth failed */
1773          }
1774          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1775            new_mntners = get_mntners(new_object);
1776            new_auth_vector = get_auth_vector(new_mntners);
1777            if(new_mntners != NULL && new_auth_vector == NULL){
1778              /* then, the mntners in 'new_mntners' do not exist. Problem. */
1779              return UP_AUF; /* auth failed */
1780            }
1781            return authorise(new_auth_vector, credentials, overriden);
1782          }else{
1783            return UP_HOF; /* hierarchical authorisation failed */
1784          }
1785        }
1786      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1787        old_mntners = get_mntners(old_object);
1788        old_auth_vector = get_auth_vector(old_mntners);
1789        if(old_mntners != NULL && old_auth_vector == NULL){
1790          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1791          return UP_AUF; /* auth failed */
1792        }
1793        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1794          return authorise(old_auth_vector, credentials, overriden);
1795        }else{
1796          new_mntners = get_mntners(new_object);
1797          new_auth_vector = get_auth_vector(new_mntners);
1798          if(new_mntners != NULL && new_auth_vector == NULL){
1799            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1800            return UP_AUF; /* auth failed */
1801          }
1802          return authorise(new_auth_vector, credentials, overriden);
1803        }
1804      }else{ /* both are NULL, mustn't happen */
1805          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1806          return UP_INT; /* internal error */
1807      }
1808    }
1809 
1810 
1811    
1812    /*  
1813     *  Handle the "domain" type 
1814     */
1815    else if(strcmp(type,"domain")  == 0){
1816      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1817        old_mntners = get_mntners(old_object);
1818        old_auth_vector = get_auth_vector(old_mntners);
1819        if(old_mntners != NULL && old_auth_vector == NULL){
1820          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1821          return UP_AUF; /* auth failed */
1822        }
1823        return authorise(old_auth_vector, credentials, overriden);
1824      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1825        /* now, we have to find a 'less specific domain object' for this. 
1826           If there is no less specific object, then creation is possible
1827           only with overriding. */
1828       less_specific_domain = get_less_specific_domain(new_object);
1829       if(less_specific_domain == NULL){
1830         if(overriden){/* we didn't get a 'less specific' domain object */
1831            return UP_AUTH_OK; 
1832          }else{
1833            return UP_HOF; /* hierarchical authorisation failed */
1834          }
1835       }else{ /* we get a 'less specific' domain object */
1836          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
1837          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1838          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1839            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1840            return UP_AUF; /* auth failed */
1841          }
1842          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1843            new_mntners = get_mntners(new_object);
1844            new_auth_vector = get_auth_vector(new_mntners);
1845            if(new_mntners != NULL && new_auth_vector == NULL){
1846              /* then, the mntners in 'new_mntners' do not exist. Problem. */
1847              return UP_AUF; /* auth failed */
1848            }
1849            return authorise(new_auth_vector, credentials, overriden);
1850          }else{
1851            return UP_HOF; /* hierarchical authorisation failed */
1852          }
1853         
1854       }
1855      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1856        old_mntners = get_mntners(old_object);
1857        old_auth_vector = get_auth_vector(old_mntners);
1858        if(old_mntners != NULL && old_auth_vector == NULL){
1859          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1860          return UP_AUF; /* auth failed */
1861        }
1862        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1863          return authorise(old_auth_vector, credentials, overriden);
1864        }else{
1865          new_mntners = get_mntners(new_object);
1866          new_auth_vector = get_auth_vector(new_mntners);
1867          if(new_mntners != NULL && new_auth_vector == NULL){
1868            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1869            return UP_AUF; /* auth failed */
1870          }
1871          return authorise(new_auth_vector, credentials, overriden);
1872        }
1873      }else{ /* both are NULL, mustn't happen */
1874          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1875          return UP_INT; /* internal error */
1876      }
1877    }
1878    
1879 
1880    /*  
1881     *  Handle the "route" type 
1882     */
1883    else if(strcmp(type,"route")  == 0){
1884      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1885        old_mntners = get_mntners(old_object);
1886        old_auth_vector = get_auth_vector(old_mntners);
1887        if(old_mntners != NULL && old_auth_vector == NULL){
1888          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1889          return UP_AUF; /* auth failed */
1890        }
1891        return authorise(old_auth_vector, credentials, overriden);
1892      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1893        /* first we have to find the aut-num object mentioned in the 
1894           origin attribute */
1895 
1896        aut_num_object = get_aut_num_object(new_object); 
1897        if(aut_num_object == NULL){
1898          if(overriden){
1899            return UP_AUTH_OK; 
1900          }else{
1901            return UP_HOF; /* hierarchical authorisation failed */
1902          }
1903        }else{/* there is a corresponding aut-num in the db */
1904          printf("DEBUG: check_auth: will try to authorise the route using aut-num\n");
1905          aut_num_maintainers = get_mnt_routes(aut_num_object);
1906          if(aut_num_maintainers != NULL){
1907            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1908            if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1909              aut_num_auth_OK = true;
1910            }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1911              return UP_HOF;
1912            }
1913          }else{/* aut_num_maintainers is NULL */
1914             aut_num_maintainers = get_mnt_lowers(aut_num_object);
1915             if(aut_num_maintainers != NULL){
1916               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1917               if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1918                 aut_num_auth_OK = TRUE;
1919               }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1920                 return UP_HOF; /* hierarchical authorisation failed */
1921               }
1922             }else{/* aut_num_maintainers is NULL */
1923               aut_num_maintainers = get_mntners(aut_num_object);
1924               if(aut_num_maintainers != NULL){
1925                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1926                 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1927                   aut_num_auth_OK = TRUE;
1928                 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1929                   return UP_HOF; /* hierarchical authorisation failed */
1930                 }
1931               }else{/* aut_num_maintainers is NULL */
1932                 aut_num_auth_OK = TRUE;
1933               }
1934               
1935             }
1936          }
1937          if(aut_num_auth_OK){
1938            /* now, we have to find an exact match for this route object. 
1939               If there is no exact match object, then we will go on to find
1940               less specific. */
1941            exact_match_routes = get_exact_match_routes(new_object);
1942            if(exact_match_routes != NULL){
1943              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
1944              exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
1945              if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
1946                /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
1947                return UP_AUF; /* auth failed */
1948               }
1949              if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1950                /* then, check mnt_bys of the route itself */
1951                new_mntners = get_mntners(new_object);
1952                new_auth_vector = get_auth_vector(new_mntners);
1953                if(new_mntners != NULL && new_auth_vector == NULL){
1954                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
1955                  return UP_AUF; /* auth failed */
1956                }
1957                return authorise(new_auth_vector, credentials, overriden);
1958              }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1959                return UP_HOF; /* hierarchical authorisation failed */
1960              }
1961            }else{ /* exact_match_routes == NULL */
1962              /* then we have to look for less specific route objs */
1963              less_spec_routes = get_less_spec_routes(new_object);
1964              if(less_spec_routes != NULL){
1965                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
1966                less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners, 
1967                                              get_mnt_lowers_from_list(less_spec_routes));
1968                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
1969                if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
1970                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
1971                  return UP_AUF; /* auth failed */
1972                }
1973                if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1974                  /* then, check mnt_bys of the route itself */
1975                  new_mntners = get_mntners(new_object);
1976                  new_auth_vector = get_auth_vector(new_mntners);
1977                  if(new_mntners != NULL && new_auth_vector == NULL){
1978                    /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1979                    return UP_AUF; /* auth failed */
1980                  }
1981                  return authorise(new_auth_vector, credentials, overriden);
1982                }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1983                  return UP_HOF; /* hierarchical authorisation failed */
1984                }
1985             }else{/* less_spec_routes == NULL */
1986                /* so, we have to get the exact match inetnum */
1987                exact_match_inetnum = get_exact_match_inetnum(new_object);
1988                if(exact_match_inetnum != NULL){
1989                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
1990                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
1991                  if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
1992                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
1993                    return UP_AUF; /* auth failed */
1994                  }
1995                  if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
1996                    /* then, check mnt_bys of the route itself */
1997                    new_mntners = get_mntners(new_object);
1998                    new_auth_vector = get_auth_vector(new_mntners);
1999                    if(new_mntners != NULL && new_auth_vector == NULL){
2000                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2001                      return UP_AUF; /* auth failed */
2002                    }
2003                    return authorise(new_auth_vector, credentials, overriden);
2004                  }else{
2005                    return UP_HOF; /* hierarchical authorisation failed */
2006                  }
2007                }else{/* exact_match_inetnum == NULL */
2008                  /* then, we will try to find less spec inetnums */
2009                  less_spec_inetnum = get_less_spec_inetnum(new_object);
2010                  if(less_spec_inetnum != NULL){
2011                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
2012                    less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners, 
2013                                   get_mnt_lowers(less_spec_inetnum));
2014                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
2015                    if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
2016                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
2017                      return UP_AUF; /* auth failed */
2018                    }
2019                    if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
2020                      /* then, check mnt_bys of the route itself */
2021                      new_mntners = get_mntners(new_object);
2022                      new_auth_vector = get_auth_vector(new_mntners);
2023                      if(new_mntners != NULL && new_auth_vector == NULL){
2024                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2025                        return UP_AUF; /* auth failed */
2026                      }
2027                      return authorise(new_auth_vector, credentials, overriden);
2028                    }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
2029                      return UP_HOF; /* hierarchical authorisation failed */
2030                    }
2031                  }else{/* less_spec_inetnum == NULL */
2032                    /* now that we couldn't find any route or inetnum object
2033                       to be used in authentication. So, only if the auth is
2034                       overriden the object will be created. */
2035                    if(overriden){
2036                      return UP_AUTH_OK; 
2037                    }else{
2038                      return UP_HOF; /* hierarchical authorisation failed */
2039                    }
2040                  }
2041                }
2042              }
2043            }
2044          }else{/* ! aut_num_auth_OK */
2045            return UP_HOF; /* hierarchical auth failed */
2046          }
2047 
2048        }
2049           
2050      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2051        old_mntners = get_mntners(old_object);
2052        old_auth_vector = get_auth_vector(old_mntners);
2053        if(old_mntners != NULL && old_auth_vector == NULL){
2054          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2055          return UP_AUF; /* auth failed */
2056        }
2057        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2058          return authorise(old_auth_vector, credentials, overriden);
2059        }else{
2060          new_mntners = get_mntners(new_object);
2061          new_auth_vector = get_auth_vector(new_mntners);
2062          if(new_mntners != NULL && new_auth_vector == NULL){
2063            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2064            return UP_AUF; /* auth failed */
2065          }
2066          return authorise(new_auth_vector, credentials, overriden);
2067        }
2068      }else{ /* both are NULL, mustn't happen */
2069          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
2070          return UP_INT; /* internal error */
2071      }
2072    }
2073 
2074 
2075    /*  
2076     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types 
2077     */
2078    else if(strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
2079            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
2080            strcmp(type,"route-set")    == 0 ){
2081      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2082        old_mntners = get_mntners(old_object);
2083        old_auth_vector = get_auth_vector(old_mntners);
2084        if(old_mntners != NULL && old_auth_vector == NULL){
2085          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2086          return UP_AUF; /* auth failed */
2087        }
2088        return authorise(old_auth_vector, credentials, overriden);
2089      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2090         code = set_object->scan(new_object, strlen(new_object));
2091         set_name = get_search_key(set_object, type, new_object);
2092        if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
2093          new_mntners = get_mntners(new_object);
2094          new_auth_vector = get_auth_vector(new_mntners);
2095          if(new_mntners != NULL && new_auth_vector == NULL){
2096            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2097            return UP_AUF; /* auth failed */
2098          }
2099          return authorise(new_auth_vector, credentials, overriden);
2100        }else{/* the name is hierarchical */
2101          less_specific_object = get_less_specific_set(new_object, type);
2102          if(less_specific_object != NULL){/* such an object exists */
2103            temp_obj = new Object();
2104            code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
2105            less_specific_object_type = get_type(temp_obj);
2106            delete(temp_obj);
2107            if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
2108              less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2109              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2110              if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2111                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
2112               return UP_AUF; /* auth failed */
2113              }
2114              if(less_specific_auth_vector != NULL){
2115                return authorise(less_specific_auth_vector, credentials, overriden);
2116              }else{/* the less specific object doesn't contain any mnt-lower */
2117                less_specific_mntners = get_mntners(less_specific_object);
2118                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2119                if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2120                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2121                  return UP_AUF; /* auth failed */
2122                }
2123                if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs, 
2124                                                         use them  */
2125                    return authorise(less_specific_auth_vector, credentials, overriden);
2126                }else{/* the less specific object doesn't contain any mnt-by either */
2127                  if(overriden){
2128                    return UP_AUTH_OK; 
2129                  }else{
2130                    return UP_HOF; /* hierarchical authorisation failed */
2131                  }
2132                }
2133              }
2134            }else{ /* this is _not_ an aut-num object*/
2135              less_specific_mntners = get_mntners(less_specific_object);
2136              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2137              if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2138                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2139                return UP_AUF; /* auth failed */
2140              }
2141              if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
2142                return authorise(less_specific_auth_vector, credentials, overriden);
2143              }else{
2144                if(overriden){
2145                  return UP_AUTH_OK; 
2146                }else{
2147                  return UP_HOF; /* hierarchical authorisation failed */
2148                }
2149              }
2150            }
2151 
2152          }else{/* we don't have a less specific of this set object in the DB  */
2153            return UP_HOF; /* hierarchical authorisation failed */
2154          }
2155        }
2156      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2157        old_mntners = get_mntners(old_object);
2158        old_auth_vector = get_auth_vector(old_mntners);
2159        if(old_mntners != NULL && old_auth_vector == NULL){
2160          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2161          return UP_AUF; /* auth failed */
2162        }
2163        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2164          return authorise(old_auth_vector, credentials, overriden);
2165        }else{
2166          new_mntners = get_mntners(new_object);
2167          new_auth_vector = get_auth_vector(new_mntners);
2168          if(new_mntners != NULL && new_auth_vector == NULL){
2169            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2170            return UP_AUF; /* auth failed */
2171          }
2172          return authorise(new_auth_vector, credentials, overriden);
2173        }
2174      }else{ /* both are NULL, mustn't happen */
2175          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
2176          return UP_INT; /* internal error */
2177      }
2178    
2179 
2180 
2181 
2182 
2183    }else{ /* We exhausted all object classes. If we are here, then there is a problem */
2184      cout << "check_auth: This type '" << type << "' is unknown" << endl;
2185      return UP_NIY; /* not implemented yet */
2186    }
2187    return UP_AUF; /* if we come to this point, then auth failed */ 
2188 }
2189 
2190 
2191 
2192 
2193 
2194 
2195 /* Gets the old version of the given "arg" object, which is in char * format
2196    and returns the old version again in char * format */
2197 
2198 char * get_old_version(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2199 
2200     bool code = true;
2201     char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2202     Object *o;
2203     o = new Object;
2204     char *result = NULL, *origin = NULL;
2205     
2206     error = 0; 
2207     code = o->scan(arg,strlen(arg));
2208     type = get_type(o);
2209     primary_search_key = get_search_key(o, type, arg);
2210     if(tracing) {
2211       cout << "type=" << type << endl;
2212       cout << "primary_search_key=" << primary_search_key << endl;
2213     }
2214     /* prepare the search string */
2215     //search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2216     //                                      + strlen(type) + 1);
2217     /* if the object is a pn ro a ro object, then get all pn/ro's with the
2218        same NIC hdl */
2219     if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2220       /* prepare the search string */
2221       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2222                                           + strlen("person,role") + 1);
2223       sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2224     }else{
2225       /* prepare the search string */
2226       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2227                                           + strlen(type) + 1);
2228       sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2229     }
2230     result = send_and_get(QUERY_HOST, QUERY_PORT, search_string);
2231     if(tracing) {
2232       cout << "TRACING: send_and_get has returned" << endl;
2233       cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl 
2234            << result << endl;
2235     }
2236     /* Attention: here we must also check these:
2237          for ro/pn objects: The name must also the same. When the NIC hdl is the
2238                same but names are different, we must somehow return an error.
2239                Also, when we search for a person, we must also look for role objects
2240                (and vice versa) since the RIPupdate does not distinguish between
2241                role & person objects. We have to check it here.
2242          for rt objects: We also have to check the identicalness of origin
2243                attributes.                
2244                
2245           These are not yet implemented.     
2246                */
2247 
2248     if(strcmp(type,"route") == 0){
2249       if(tracing) {
2250         printf("TRACING: This is a route\n");
2251       }
2252       /* if this is a route, then we must filter out the routes with different
2253          origin attributes */
2254       origin = get_search_key(o, "origin", arg);
2255       if(tracing) {
2256         printf("TRACING: Got origin of route: %s\n", origin);
2257       }
2258       result = filter_out_diff_origins(result, origin);  
2259       if(tracing) {
2260         printf("TRACING: Filtered routes\n");
2261       }
2262     }
2263     // count the objects
2264     if(count_objects(result) == 0){
2265       result = NULL; /* we don't have such an object */
2266     }else if(count_objects(result) == 1){
2267       result = take_object(result);
2268       if(tracing) {
2269       cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2270       }
2271     }else{ /* we have more than one objects, error! */
2272       error = UP_MOR;
2273       return NULL;
2274     }
2275     return result;
2276 }
2277 
2278 
2279 
2280 
2281 /* Gets a credentials_struct whose 'from' field will be filled in and
2282    the mail header. Finds the 'From:' line in the header and sets
2283    the 'from' field to this line (all line, including the 'From:' string,
2284    since some users have put regexps which match the whole line in their
2285    'auth' attributes.) */
2286 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2287   char * header = strdup(arg);
2288   char * temp = (char *)malloc(strlen(header));
2289   while(index(header, '\n') != NULL){
2290     temp = strdup(header);
2291     temp[index(temp, '\n') - temp] = '\0';
2292     if(strstr(temp, "From:") == temp){
2293       if(tracing) {
2294         printf("TRACING: process_mail_header: Assigning %s\n", temp);
2295       }
2296       credentials_ptr->from = strdup(temp);
2297       free(temp);
2298       return;
2299     }
2300     header = header + (index(header, '\n') - header + 1);
2301   }
2302   free(temp);
2303 }
2304 
2305 
2306 
2307 
2308 
2309 
2310 void stringPack(char *dest, const char *source)
     /* [<][>][^][v][top][bottom][index][help] */
2311 {
2312 
2313   if(tracing) {
2314     printf("TRACING: stringPack running\n");
2315   }
2316         
2317 
2318 
2319 /*----------------------------------------------------------------------*\
2320 
2321 *  Function to rewrite a line of text with only one blankspace between  *
2322 *  each word.
2323 *
2324 
2325 \*----------------------------------------------------------------------*/
2326 
2327 
2328 /*
2329  * This while loop continues until the NULL character is copied into
2330  * the destination string.  If a tab character is copied into the
2331  * destination string, it is replaced with a blank-space character.
2332  *
2333  * Multiple blank-space and/or tab characters are skipped in the source
2334  * string until any other character is found.
2335  */
2336 
2337         while (1)
2338                 {
2339                 *dest = *source;
2340 
2341                 if (*dest == '\t')
2342                         (*dest = ' ');
2343 
2344                 /* Exit if have copied the end of the string. */
2345                 if (*dest == '\0')
2346                         return;
2347 
2348 /*
2349  * If the source character was a blank-space or a tab, move to the next
2350  * source character.  While the source character is a blank-space or a
2351  * tab, move to the next character (i.e. ignore these characters).  When
2352  * any other character is found in the source string, move to the next
2353  * element of the destination string.
2354  *
2355  * Otherwise, simultaneously, move to the next elements of the destination
2356  * and the source strings.
2357  */
2358 
2359 
2360 
2361                 if ( (*source == ' ') || (*source == '\t') )
2362                         {
2363                         ++source;
2364                         while ( (*source == ' ') || (*source == '\t') )
2365                                 {
2366                                 ++source;
2367                                 }
2368 
2369                         ++dest;
2370                         }
2371                 else
2372                         {
2373                         ++dest;
2374                         ++source;
2375                         }
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 /* looks if two objects are identical or not.
2413     Takes two objects as char *, and returns 1 if
2414     they are identical, returns 0 if not.
2415 
2416     Algorithm is very simple: All strings of tabs and 
2417     white spaces are collapsed into a single white space,
2418     and then the strings are compared (strcmp) */
2419 int identical(const char * old_version, const char * new_version){
     /* [<][>][^][v][top][bottom][index][help] */
2420   char * arg1 = strdup(old_version);
2421   char * arg2 = strdup(new_version);
2422   int result = 0;
2423   char *temp1, *temp2; 
2424 
2425 
2426   arg1 = g_strstrip(arg1);
2427   arg2 = g_strstrip(arg2);
2428 
2429   /* delete the 'delete:' attrib */
2430   arg2 = delete_delete_attrib(arg2);
2431   /* convert tabs to white spaces */
2432   arg1 = g_strdelimit(arg1, "\t", ' ');
2433   arg2 = g_strdelimit(arg2, "\t", ' ');
2434   
2435   temp1 = (char *)malloc(strlen(arg1)); 
2436   temp2 = (char *)malloc(strlen(arg2));
2437   stringPack(temp1, arg1);
2438   stringPack(temp2, arg2);
2439 
2440   /* if there is still \r's at the end of strings, remove them */
2441   if((temp1[strlen(temp1) - 1]) == '\r'){
2442     temp1[strlen(temp1) - 1] = '\0';
2443   }
2444   if((temp2[strlen(temp2) - 1]) == '\r'){
2445     temp2[strlen(temp2) - 1] = '\0';
2446   }
2447 
2448   result = strcmp(temp1, temp2);
2449   //printf("DEBUG: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2450   free(arg1);
2451   free(arg2);
2452   free(temp1);
2453   free(temp2);
2454   if(result  == 0){
2455     if(tracing) {
2456       printf("TRACING: identical returning 1\n");
2457     }
2458     return 1;
2459   }else{
2460     if(tracing) {
2461       printf("TRACING: identical returning 0\n");
2462     }
2463     return 0;
2464   }
2465 }
2466 
2467 
2468 
2469 
2470 
2471 
2472 /* constructs an initials string from a given name (for NIC hdl generation) */
2473 char * find_initials(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2474 
2475    char * temp, * temp2;
2476    char * initials = NULL;
2477    int len, i;
2478    char ** vector;
2479 
2480    temp = strdup(arg);
2481    g_strstrip(temp);
2482    temp2 = (char *)malloc(strlen(temp) + 1);
2483    stringPack(temp2, temp);
2484    vector = g_strsplit(temp2, " ", 0);
2485    for(i = 0; vector[i] != NULL && i < 4; i++){
2486      //printf("%i\n",i);
2487      if(strlen(vector[i]) > 0){
2488        if(initials == NULL){
2489          initials = (char *)malloc(2);
2490          initials[0] = vector[i][0]; initials[1] = '\0';
2491        }else{
2492          len = strlen(initials);
2493          initials = (char *)realloc(initials, len + 2 );
2494          initials[len] = vector[i][0];
2495          initials[len + 1] = '\0';
2496        }
2497      }
2498    }
2499    free(temp);free(temp2);g_strfreev(vector);
2500    return initials;
2501 }
2502 
2503 
2504 
2505 
2506 
2507 /*  Gets the letter combination to be used in the automatically
2508     generated NIc handle. It the letter combination is specified
2509     in the AUTO NIC handle, return that. If not, return NULL
2510     (in which case the initials of the name must be used) */
2511 char * get_combination_from_autonic(const char * autonic){
     /* [<][>][^][v][top][bottom][index][help] */
2512 
2513   GString * temp;
2514   char * str = NULL;
2515 
2516   temp = g_string_new(autonic);
2517   temp = g_string_up(temp);
2518   temp = g_string_erase(temp, 0, strlen("AUTO-"));
2519   /* delete all digits from the beginning of the string */
2520   while(temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9')){
2521     temp = g_string_erase(temp, 0, 1);
2522   }
2523   if(temp->len == 0){
2524     g_string_free(temp, TRUE);
2525     return NULL;
2526   }else{
2527     str = temp->str;
2528     g_string_free(temp, FALSE);
2529     return str;
2530   }
2531 
2532 }
2533 
2534 
2535 
2536 
2537 
2538 
2539 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2540    and  modifies the nic-hdl: attribute, returns the new object.
2541    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2542    auto_nic is set to "AUTO-1"
2543    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2544 #if 0
2545 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
     /* [<][>][^][v][top][bottom][index][help] */
2546 
2547   GString* temp_string; 
2548   char * to_be_returned = NULL;
2549   char * person_role_name= NULL;
2550   char * initials = NULL;
2551   char ** temp = NULL;
2552   int i, pos;
2553   Object * o = new Object;
2554 
2555   temp = g_strsplit(arg, "\n", 0);
2556 
2557   for(i = 0; temp[i] != NULL; i++){
2558     //printf("Line: %s\n", temp[i]);
2559     if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2560       temp_string = g_string_new(temp[i]);
2561       if(strstr(temp_string->str, "AUTO-") != NULL){
2562         auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "AUTO-"), 
2563             temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-") );
2564         auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-")] = '\0';
2565         g_strstrip(auto_nic_hdl);
2566         printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2567         pos = strstr(temp_string->str, "AUTO-") - temp_string->str;
2568         temp_string = g_string_erase(temp_string,
2569             strstr(temp_string->str, "AUTO-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2570         
2571         temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2572         temp_string = g_string_insert(temp_string, pos, "*-");
2573         o->scan(arg, strlen(arg));
2574         person_role_name = get_attribute(o, get_type(o), arg);
2575         delete(o);
2576         initials = find_initials(person_role_name);
2577         free(person_role_name);
2578         temp_string = g_string_insert(temp_string, pos, initials);
2579         free(initials);
2580         
2581         if(to_be_returned == NULL){
2582           to_be_returned = strdup(temp_string->str);
2583           g_string_free(temp_string, TRUE);
2584         }else{
2585           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2586           to_be_returned = strcat(to_be_returned, "\n");
2587           to_be_returned = strcat(to_be_returned, temp_string->str);
2588           g_string_free(temp_string, TRUE);
2589         }
2590       }else{
2591         if(to_be_returned == NULL){
2592           to_be_returned = strdup(temp[i]);
2593         }else{
2594           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2595           to_be_returned = strcat(to_be_returned, "\n");
2596           to_be_returned = strcat(to_be_returned, temp[i]);
2597         }
2598       }
2599     }else{/* if it doesn't begin with nic-hdl */
2600         if(to_be_returned == NULL){
2601           to_be_returned = strdup(temp[i]);
2602         }else{
2603           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2604           strcat(to_be_returned, "\n");
2605           strcat(to_be_returned, temp[i]);
2606         }
2607 
2608     }
2609 
2610   }
2611   g_strfreev (temp);
2612   return to_be_returned;
2613 }
2614 #endif
2615 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
     /* [<][>][^][v][top][bottom][index][help] */
2616 
2617   GString* temp_string; 
2618   char * to_be_returned = NULL;
2619   char * person_role_name= NULL;
2620   char * initials = NULL;
2621   char ** temp = NULL;
2622   int i, pos;
2623   Object * o = new Object;
2624 
2625   temp = g_strsplit(arg, "\n", 0);
2626 
2627   for(i = 0; temp[i] != NULL; i++){
2628     //printf("Line: %s\n", temp[i]);
2629     if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2630       temp_string = g_string_new(temp[i]);
2631       temp_string = g_string_down(temp_string);
2632       if(strstr(temp_string->str, "auto-") != NULL){
2633         auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "auto-"), 
2634             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2635         auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")] = '\0';
2636         g_strstrip(auto_nic_hdl);
2637         printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2638         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2639         temp_string = g_string_erase(temp_string,
2640             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2641         
2642         temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2643         temp_string = g_string_insert(temp_string, pos, "*-");
2644         o->scan(arg, strlen(arg));
2645         person_role_name = get_attribute(o, get_type(o), arg);
2646         delete(o);
2647         /* if the letter combination is already specified, get it */
2648         initials = get_combination_from_autonic(auto_nic_hdl);
2649         /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
2650         if(initials == NULL){
2651           initials = find_initials(person_role_name);
2652         }
2653         free(person_role_name);
2654         temp_string = g_string_insert(temp_string, pos, initials);
2655         free(initials);
2656         
2657         if(to_be_returned == NULL){
2658           to_be_returned = strdup(temp_string->str);
2659           g_string_free(temp_string, TRUE);
2660         }else{
2661           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2662           to_be_returned = strcat(to_be_returned, "\n");
2663           to_be_returned = strcat(to_be_returned, temp_string->str);
2664           g_string_free(temp_string, TRUE);
2665         }
2666       }else{
2667         if(to_be_returned == NULL){
2668           to_be_returned = strdup(temp[i]);
2669         }else{
2670           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2671           to_be_returned = strcat(to_be_returned, "\n");
2672           to_be_returned = strcat(to_be_returned, temp[i]);
2673         }
2674       }
2675     }else{/* if it doesn't begin with nic-hdl */
2676         if(to_be_returned == NULL){
2677           to_be_returned = strdup(temp[i]);
2678         }else{
2679           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2680           strcat(to_be_returned, "\n");
2681           strcat(to_be_returned, temp[i]);
2682         }
2683 
2684     }
2685 
2686   }
2687   g_strfreev (temp);
2688   return to_be_returned;
2689 }
2690 
2691 
2692 
2693 /* replaces the refs to AUTO NIC hdls with the assigned one */
2694 
2695 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
     /* [<][>][^][v][top][bottom][index][help] */
2696 
2697   char * auto_nic = NULL;
2698   GString* temp_string; 
2699   char * to_be_returned = NULL;
2700   char ** temp = NULL;
2701   int i, pos;
2702 
2703   //printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is running\n");
2704 
2705   temp = g_strsplit(arg, "\n", 0);
2706 
2707   for(i = 0; temp[i] != NULL; i++){
2708     //printf("Line: %s\n", temp[i]);
2709     if(   strstr(temp[i], "admin-c:") == temp[i]    /*    if it starts with admin-c */
2710        || strstr(temp[i], "tech-c:" ) == temp[i]    /* or if it starts with tech-c */
2711        || strstr(temp[i], "zone-c:" ) == temp[i]    /* or if it starts with zone-c */
2712        || strstr(temp[i], "author:" ) == temp[i]){  /* or if it starts with author */
2713       temp_string = g_string_new(temp[i]);
2714       temp_string = g_string_down(temp_string);
2715       if(strstr(temp_string->str, "auto-") != NULL){
2716         auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")  + 1);
2717         auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"), 
2718             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2719         auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0'; 
2720         g_strstrip(auto_nic);
2721         printf("DEBUG: auto_nic is [%s]\n", auto_nic);
2722         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2723         temp_string = g_string_erase(temp_string,
2724             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
2725         
2726         //temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2727         //temp_string = g_string_insert(temp_string, pos, "*-");
2728         /* if we have this AUTO NIC hdl in the hash, put it. */
2729         if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
2730           temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
2731         }else{/* else, return 0 immediately */
2732           g_strfreev (temp);
2733           return NULL;
2734         }
2735         
2736         if(to_be_returned == NULL){
2737           to_be_returned = strdup(temp_string->str);
2738           g_string_free(temp_string, TRUE);
2739         }else{
2740           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2741           to_be_returned = strcat(to_be_returned, "\n");
2742           to_be_returned = strcat(to_be_returned, temp_string->str);
2743           g_string_free(temp_string, TRUE);
2744         }
2745       }else{
2746         if(to_be_returned == NULL){
2747           to_be_returned = strdup(temp[i]);
2748         }else{
2749           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2750           to_be_returned = strcat(to_be_returned, "\n");
2751           to_be_returned = strcat(to_be_returned, temp[i]);
2752         }
2753       }
2754     }else{/* if it doesn't begin with ac,tc,ac or author */
2755         if(to_be_returned == NULL){
2756           to_be_returned = strdup(temp[i]);
2757         }else{
2758           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2759           strcat(to_be_returned, "\n");
2760           strcat(to_be_returned, temp[i]);
2761         }
2762 
2763     }
2764 
2765   }
2766   g_strfreev (temp);
2767   //free(arg);
2768   //changed_obj = strdup(to_be_returned);
2769   //free(to_be_returned);
2770   printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
2771   return to_be_returned;
2772 }
2773 
2774 
2775 
2776 
2777 
2778 
2779 
2780 
2781 /* Takes an object in a char * , and returns 1 if this object has 
2782    an AUTO NIC handle. Otherwise, returns 0 */
2783 int has_AUTO_NIC_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
2784 
2785   Object * o = new Object();
2786   GSList * attributes = NULL;
2787   bool code;
2788 
2789   code = o->scan(object, strlen(object));
2790 
2791   if(code && !(o->isDeleted)){
2792     attributes = get_attributes(o, "nic-hdl", object);
2793     if(attributes != NULL){
2794       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2795         g_slist_free(attributes);
2796         delete(o);
2797         return 1;
2798       }
2799     }
2800     /* if control reaches here, then we will return 0 */
2801     g_slist_free(attributes);
2802     delete(o);
2803     return 0; 
2804   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
2805            it contains refs to AUTO NIC hdls. */
2806     delete(o); 
2807     return 0;        
2808   }
2809     
2810 }
2811 
2812 
2813 /* Takes an object in a char * , and returns 1 if this object contains
2814    a reference to an AUTO NIC handle. Otherwise, returns 0 */
2815 int has_ref_to_AUTO_nic_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
2816 
2817   Object * o = new Object();
2818   GSList * attributes = NULL;
2819   bool code;
2820 
2821   code = o->scan(object, strlen(object));
2822 
2823   if(code && !(o->isDeleted)){
2824     attributes = get_attributes(o, "admin-c", object);
2825     if(attributes != NULL){
2826       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2827         g_slist_free(attributes);
2828         delete(o);
2829         return 1;
2830       }
2831     }
2832     g_slist_free(attributes);
2833     attributes = get_attributes(o, "tech-c", object);
2834     if(attributes != NULL){
2835       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2836         g_slist_free(attributes);
2837         delete(o);
2838         return 1;
2839       }
2840     }
2841 
2842     g_slist_free(attributes);
2843     attributes = get_attributes(o, "zone-c", object);
2844     if(attributes != NULL){
2845       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2846         g_slist_free(attributes);
2847         delete(o);
2848         return 1;
2849       }
2850     }
2851     g_slist_free(attributes);
2852     attributes = get_attributes(o, "author", object);
2853     if(attributes != NULL){
2854       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2855         g_slist_free(attributes);
2856         delete(o);
2857         return 1;
2858       }
2859     }
2860     /* if control reaches here, then we will return 0 */
2861     delete(o);
2862     return 0; 
2863   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
2864            it contains refs to AUTO NIC hdls. */
2865     delete(o); 
2866     return 0;        
2867   }
2868     
2869 }
2870 
2871 
2872 #if 0
2873 /* Checks the object's syntax, retrives the old version of it from the db, 
2874    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
2875    integrity is checked, and the object is really committed to the db.
2876    
2877      Arguments:
2878         char * arg: The object,
2879         credentials_struct credentials: The struct containing the credentials, such as 
2880           'From:' field of the e-mail update,
2881         GHashTable * NIC_hdl_hash: A hash containing 
2882         char * ack_file_name:  The file name, to be used to store ACK message 
2883 */
2884 
2885 
2886 
2887 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name){
     /* [<][>][^][v][top][bottom][index][help] */
2888     bool code = true;
2889     Object *o;
2890     char * old_version = NULL;
2891     o = new Object;
2892     int result = 0;
2893     int result_from_RIPupd = 0;
2894     char * auto_nic = NULL;
2895     char * changed_obj = NULL;
2896     char * obj_with_AUTO_NIC_hdl;
2897     char * assigned_NIC;
2898 
2899     char * value = NULL;/* these two are for */
2900     Attr * attr;        /* ack messages only */ 
2901     
2902     if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
2903        /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
2904        if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
2905          return UP_ANE; /* AUTO NIC hdl error */
2906        };
2907     }
2908     
2909     code = o->scan(arg,strlen(arg));
2910     if(code){
2911       /* is the object to be deleted? */
2912       if(o->isDeleted){
2913         //printf("DEBUG: This object is to be deleted\n"); 
2914         old_version = get_old_version(arg);
2915         if(old_version == NULL){ // the object doesn't exist in the db!
2916           //add_to_ack("\nDeletion Failed: Object doesn't exist", ack_file_name);
2917           //add_to_ack(o->type->getName(), ack_file_name);
2918           //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2919           AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s] %s\nObject doesn't exist\n", 
2920                         o->type->getName(), get_search_key(o, o->type->getName(), arg));
2921           return UP_NSO; /* no such object */
2922         }else {/* the object is in the db */
2923           if(identical(old_version, arg)){/* if the old & new versions are identical */
2924             result = check_auth(NULL, old_version, o->type->getName(), credentials);
2925             if(result == UP_AUTH_OK){ 
2926               if(tracing) {
2927                 printf("TRACING: Will send the obj to be deleted\n");
2928               }
2929               result_from_RIPupd = send_object_db(arg, NULL, "DEL");
2930               if(result_from_RIPupd == 0){
2931                 //add_to_ack("\nDeletion succeeded", ack_file_name);
2932                 //add_to_ack(o->type->getName(), ack_file_name);
2933                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2934                  AK_add_to_ack(ack_file_name, "\nDel OK: [%s] %s\n", 
2935                                o->type->getName(), get_search_key(o, o->type->getName(), arg));
2936               }else{
2937                 //add_to_ack("\nDeletion failed: Referential intergrity failure", 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] %s\nReferential intergrity failure\n",
2941                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
2942               }
2943               result_from_RIPupd = 0;
2944             }else{ /* auth failed */
2945               if(tracing) {
2946                 printf("TRACING: Auth failed\n");
2947               }
2948               if(error_msg != NULL){
2949                   cout << error_msg << endl;
2950               }
2951               //add_to_ack("\nDeletion failed: Auth failed", ack_file_name);
2952               //add_to_ack(o->type->getName(), ack_file_name);
2953               //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2954               AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s]\n%s\nAuth failed\n",
2955                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
2956               return UP_AUF; /* Auth failed */
2957             } 
2958           }else{/* the new & old versions do not match */
2959             //add_to_ack("Deletion failed: new & old versions do not match", ack_file_name);
2960             AK_add_to_ack(ack_file_name, "\nDel FAILED: new & old versions do not match\n");
2961             return UP_NOM; /* new & old versions do not match */
2962           }
2963         }
2964       }else {/* the object is _not_ to be deleted */
2965         if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
2966           /* then its nic-hdl attribute must be modified so that RIPupdate
2967              would understand that it must assign a NIC handle to it */
2968           /* but first check the auth */
2969           result = check_auth(arg, NULL, o->type->getName(), credentials);
2970           if(result == UP_AUTH_OK){
2971             if(tracing) {                                
2972                 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
2973             }
2974             auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
2975             obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
2976             if(tracing) {  
2977               printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
2978               printf("TRACING: Will send the obj to be added\n");
2979             }
2980             assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
2981             result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
2982             if(result_from_RIPupd == 0){
2983               //add_to_ack("\nCreation succeeded", ack_file_name);
2984               //add_to_ack(o->type->getName(), ack_file_name);
2985               //add_to_ack(assigned_NIC, ack_file_name);
2986               AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", 
2987                             o->type->getName(), assigned_NIC);
2988             }else{
2989               //add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name);
2990               //add_to_ack(o->type->getName(), ack_file_name);
2991               //add_to_ack(arg, ack_file_name);
2992               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
2993                             o->type->getName(), arg);
2994             }
2995             result_from_RIPupd = 0;
2996             if(tracing && assigned_NIC != NULL) {  
2997               printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
2998             }
2999             if(assigned_NIC != NULL){
3000               printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
3001               g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
3002               printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
3003             }
3004             
3005           }else{
3006             // auth failed !
3007             if(tracing) {
3008               printf("TRACING: Auth failed\n");
3009             }
3010             if(error_msg != NULL){
3011               cout << error_msg << endl;
3012             }
3013             ER_perror(0, result, "");
3014             //add_to_ack("\nCreation failed: Auth failed", ack_file_name);
3015             //add_to_ack(o->type->getName(), ack_file_name);
3016             //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3017             AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
3018                           o->type->getName(), get_search_key(o, o->type->getName(), arg));
3019             return UP_AUF; /* Auth failed */
3020           }
3021         }
3022         else{ 
3023           old_version = get_old_version(arg);
3024           if(old_version != NULL){/* so, this is an update operation */
3025             result = check_auth(arg, old_version, o->type->getName(), credentials);    
3026             if(result == UP_AUTH_OK){
3027               if(tracing) {                                
3028                 printf("TRACING: Will send the obj to be updated\n");
3029               }
3030               result_from_RIPupd = send_object_db(arg, NULL, "UPD");
3031               if(result_from_RIPupd == 0){
3032                 //add_to_ack("\nUpdate succeeded", ack_file_name);
3033                 //add_to_ack(o->type->getName(), ack_file_name);
3034                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3035                 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
3036                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3037               }else{
3038                 //add_to_ack("\nUpdate failed: Referential integrity failure", ack_file_name);
3039                 //add_to_ack(o->type->getName(), ack_file_name);
3040                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3041                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
3042                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3043               }
3044               result_from_RIPupd = 0;
3045             }else{
3046               // auth failed !
3047               if(tracing) {
3048                 printf("TRACING: Auth failed\n");
3049               }
3050               if(error_msg != NULL){
3051                 cout << error_msg << endl;
3052               }
3053               //add_to_ack("\nUpdate failed: Auth failed", ack_file_name);
3054               //add_to_ack(o->type->getName(), ack_file_name);
3055               //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3056               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
3057                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
3058               return UP_AUF; /* Auth failed */
3059             }
3060           }else { /* old_version  == NULL, so, creation */
3061             result = check_auth(arg, NULL, o->type->getName(), credentials);
3062             if(result == UP_AUTH_OK){ 
3063               if(tracing) {                                
3064                 printf("TRACING: Will send the obj to be added\n");
3065               }
3066               result_from_RIPupd = send_object_db(arg, NULL, "ADD");
3067               if(result_from_RIPupd == 0){
3068                 //add_to_ack("\nCreation succeeded", ack_file_name); 
3069                 //add_to_ack(o->type->getName(), ack_file_name);
3070                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3071                 AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
3072                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3073               }else{
3074                 //add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name); 
3075                 //add_to_ack(o->type->getName(), ack_file_name);
3076                 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3077                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
3078                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
3079               }
3080               result_from_RIPupd = 0;
3081             }else{
3082               // auth failed !
3083               if(tracing) {
3084                 printf("TRACING: Auth failed\n");
3085               }
3086               if(error_msg != NULL){
3087                 cout << error_msg << endl;
3088               }
3089               ER_perror(0, result, "");
3090               //add_to_ack("\nCreation failed: Auth failed", ack_file_name);
3091               //add_to_ack(o->type->getName(), ack_file_name);
3092               //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3093               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
3094                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
3095               return UP_AUF; /* Auth failed */
3096             }
3097           } 
3098         }
3099       }
3100     }else{// even if obj doesn't parse properly, it may be a legacy object
3101           // which the user wants to delete...
3102        if(tracing){   
3103          printf("TRACING: Object didn't parse\n");   
3104        }
3105        //add_to_ack("\nFailed: Syntax error in object", ack_file_name);
3106        //add_to_ack(arg, ack_file_name);   
3107        AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
3108        //////////////////////////////////
3109        if(o->attrs.head() != NULL){
3110          for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
3111            value = (char*)malloc((*attr).len );
3112            strncpy(value, (char *)(arg+attr->offset) ,
3113              attr->len - 1);
3114            value[attr->len - 1] = '\0';
3115            //add_to_ack(value, ack_file_name);
3116            AK_add_to_ack(ack_file_name, "%s\n", value);
3117            if(!attr->errors.empty()){
3118              //add_to_ack_string(attr->errors, ack_file_name);
3119              //cout << "Error: " << attr->errors << endl;
3120              AK_add_to_ack_string(ack_file_name, attr->errors);
3121            }
3122            free(value);
3123           }
3124         }
3125         if(o->has_error){
3126           //add_to_ack_string(o->errors, ack_file_name);
3127           //cout << "Object Error: " << o->errors << endl;
3128           AK_add_to_ack_string(ack_file_name, o->errors);
3129         }
3130        //////////////////////////////////
3131        return UP_NIY; /* Not implemented yet */
3132     }
3133 }
3134 
3135 
3136 #endif
3137 
3138 /* Gets the "From" line of the incoming mail message and finds out an 
3139    address to send the acknowledgement */
3140 char * find_to_address(const char * from_line){
     /* [<][>][^][v][top][bottom][index][help] */
3141   char * pos1 = NULL, * pos2 = NULL;
3142   char * temp = NULL;
3143   
3144   if(from_line == NULL){
3145     return NULL;
3146   }
3147   if(strstr(from_line, "From:") != from_line){/* there is a problem, the line must start with 
3148                                                  "From:" */
3149     fprintf(stderr, "The line doesn't start with 'From:'\n");
3150     return NULL;
3151   }
3152   temp = strdup(from_line + strlen("From:"));
3153   g_strstrip(temp);
3154   if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
3155     pos1 = index(temp, '<');
3156     pos2 = index(temp, '>');
3157     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
3158     temp[pos2 - pos1 - 1] = '\0';
3159     printf("DEBUG: find_to_address\n");
3160     printf("DEBUG: find_to_address temp=[%s]\n", temp);
3161     return temp;
3162   }else{/* the line contains only the address, then */
3163    return temp; 
3164   }
3165 }  
3166 

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