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. replace_AUTO_NIC_hdl
  47. replace_refs_to_AUTO_NIC_hdl
  48. has_AUTO_NIC_hdl
  49. has_ref_to_AUTO_nic_hdl
  50. process_object
  51. find_to_address

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

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