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. delete_override
  6. up_get_transaction_id
  7. send_object_db
  8. get_class_type
  9. get_search_key
  10. send_and_get
  11. count_objects
  12. strip_lines
  13. take_objects
  14. take_object
  15. get_as_block
  16. get_aut_num_object
  17. get_less_specific_domain
  18. get_less_specific_set
  19. get_less_specific
  20. get_less_spec_inetnum
  21. get_exact_match_inetnum
  22. get_exact_match_routes
  23. get_less_spec_routes
  24. get_mntners
  25. get_attributes
  26. get_attribute
  27. strstr_in_list
  28. get_auths
  29. get_attr_list
  30. get_mnt_lowers
  31. get_mnt_routes
  32. get_mnt_routes_from_list
  33. get_mnt_lowers_from_list
  34. get_override
  35. check_override
  36. add_to_auth_vector
  37. get_auth_vector
  38. get_mntnfy_vector
  39. get_updto_vector
  40. filter_out_diff_origins
  41. check_auth
  42. get_old_version
  43. process_mail_header
  44. stringPack
  45. delete_delete_attrib
  46. identical
  47. find_initials
  48. get_combination_from_autonic
  49. replace_AUTO_NIC_hdl
  50. replace_refs_to_AUTO_NIC_hdl
  51. has_AUTO_NIC_hdl
  52. has_ref_to_AUTO_nic_hdl
  53. process_object
  54. find_email_address
  55. replace_strings
  56. replace_globals
  57. get_class_type_char

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

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