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. up_string_pack
  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. find_email_address
  54. replace_strings
  55. replace_globals
  56. get_class_type_char

   1 /***************************************
   2   $Revision: 1.47 $
   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     if(tracing){
 613       cout << "No such as-block" << endl;
 614     }
 615     return NULL;
 616   }else if(count_objects(result) > 1){
 617     if(tracing){
 618       cout << "More than one as-block returned" << endl;
 619     }
 620     return NULL;
 621   }else{ /* count_objects(result) == 1 */
 622     return take_object(result);
 623   }
 624   
 625 }
 626 
 627 
 628 /* Takes a route_object, and returns the aut-num mentioned in origin
 629    attribute of this route */
 630 char * get_aut_num_object(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 631   bool code;
 632   char * search_key = NULL, * query_string = NULL;
 633   char * result = NULL;
 634   Object * o = new Object();
 635   
 636   code = o->scan(route_object, strlen(route_object));
 637   search_key = get_search_key(o,"origin",route_object);
 638   
 639   query_string = (char *)malloc(strlen("-Taut-num  -r ")+strlen(search_key)+1);
 640   sprintf(query_string, "-Taut-num -r %s",search_key);
 641   result = send_and_get(query_host, query_port, query_string);
 642   if(count_objects(result) == 0){
 643     if(tracing){
 644       cout << "No such aut-num" << endl;
 645     }
 646     return NULL;
 647   }else if(count_objects(result) > 1){
 648     if(tracing){
 649       cout << "More than one aut-num returned" << endl;
 650     }
 651     return NULL;
 652   }else{ /* count_objects(result) == 1 */
 653     return take_object(result);
 654   }
 655   
 656 }
 657 
 658 
 659 
 660 
 661 /* Takes a domain_object, and returns the less specific domain of it */
 662 char * get_less_specific_domain(char *domain_object){
     /* [<][>][^][v][top][bottom][index][help] */
 663   bool code;
 664   char * search_key = NULL, * query_string = NULL;
 665   char * result = NULL, * domain = NULL;
 666   Object * o = new Object();
 667   int i,j, length;
 668   char * temp = NULL;
 669   char ** splitted;
 670 
 671   code = o->scan(domain_object, strlen(domain_object));
 672   domain = get_search_key(o,"domain",domain_object);
 673 
 674   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
 675   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
 676 
 677   for(i=1; splitted[i] != NULL; i++){
 678     /* in the following for loop, we will construct the 'less spec' domains
 679        to be looked up in the DB */ 
 680     for(j=i; splitted[j] !=NULL; j++){
 681       length = 0;
 682       if(temp!=NULL){
 683         length = strlen(temp); 
 684       }
 685       temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2); 
 686       if(j==i){
 687         temp = (char *)strdup(splitted[j]);
 688       }else{
 689         sprintf(temp, "%s.%s", temp, splitted[j]);
 690       }
 691     }
 692     query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
 693     sprintf(query_string, "-Tdomain -r -R %s", temp);
 694     result = send_and_get(query_host, query_port, query_string);
 695     if(count_objects(result) == 0){
 696     }else if(count_objects(result) > 1){
 697       if(tracing){
 698         cout << "TRACING: get_less_specific_domain: More than one domains returned" << endl;
 699       }
 700       return NULL; /* error condition */
 701     }else{ /* count_objects(result) == 1 */
 702       return take_object(result);
 703     }
 704     
 705   }
 706   /* release the memory allocated to **splitted */
 707   for(i=0; splitted[i] != NULL; i++){ 
 708     free(splitted[i]);
 709   }  
 710   /* so, we couldn't  find any 'less specific' domain */
 711   return NULL;
 712 }
 713 
 714 
 715 
 716 
 717 
 718 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
 719    by striping down the object's name ( eg, for as35:rs-trial:rs-myset, 
 720    as35:rs-trial is tried ) */
 721 char * get_less_specific_set(char *set_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 722   bool code;
 723   char * search_key = NULL, * query_string = NULL;
 724   char * result = NULL;
 725   Object * o = new Object();
 726   int i;
 727   
 728   code = o->scan(set_object, strlen(set_object));
 729   search_key = get_search_key(o, type, set_object);
 730   delete(o);
 731 
 732   for(i = strlen(search_key) -1; i > -1; i--){
 733     if(search_key[i] == ':'){
 734       search_key[i] = '\0'; /* truncate the string */
 735       break;
 736     }
 737     if(i == 0){/* if we've reached the beginning of the string 
 738                 (this means there wasn't any ';' in the string) */
 739       free(search_key);
 740       search_key = NULL;
 741     }
 742   }
 743   if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since 
 744                                                         we make sure that the name of the 
 745                                                         set_object contains a ':' in a proper place */
 746     return NULL;
 747   }
 748 
 749    
 750   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
 751   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r  %s", search_key);
 752   result = send_and_get(query_host, query_port, query_string);
 753   if(count_objects(result) == 0){
 754     cout << "No such object"  << endl;
 755     return NULL;
 756   }else if(count_objects(result) > 1){
 757     cout << "More than one objects returned" << endl;
 758     return NULL;
 759   }else{ /* count_objects(result) == 1 */
 760     return take_object(result);
 761   }
 762   
 763 }
 764 
 765 
 766 
 767 
 768 
 769 
 770 
 771 /* Takes an inetnum or inet6num object and returns one less specific of it */
 772 char * get_less_specific(char *inetnum_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 773   bool code;
 774   char * search_key = NULL, * query_string = NULL;
 775   char * result = NULL;
 776   Object * o = new Object();
 777   
 778   code = o->scan(inetnum_object, strlen(inetnum_object));
 779   search_key = get_search_key(o, type, inetnum_object);
 780   
 781   query_string = (char *)malloc(strlen("-Tinet6num -r -l ") + strlen(search_key) + 1);
 782   sprintf(query_string, "-T%s -r -l %s",type, search_key);
 783   result = send_and_get(query_host, query_port, query_string);
 784   if(count_objects(result) == 0){
 785     cout << "No such " << type << endl;
 786     return NULL;
 787   }else if(count_objects(result) > 1){
 788     cout << "More than one " << type << " returned" << endl;
 789     return NULL;
 790   }else{ /* count_objects(result) == 1 */
 791     return take_object(result);
 792   }
 793   
 794 }
 795 
 796 
 797 
 798 /* Takes a route object and returns one less specific inetnum */
 799 char * get_less_spec_inetnum(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 800   bool code;
 801   char * search_key = NULL, * query_string = NULL;
 802   char * result = NULL;
 803   Object * o = new Object();
 804   
 805   code = o->scan(route_object, strlen(route_object));
 806   search_key = get_search_key(o, "route", route_object);
 807   
 808   query_string = (char *)malloc(strlen("-Tinetnum -r -l ") + strlen(search_key) + 1);
 809   sprintf(query_string, "-Tinetnum -r -l %s", search_key);
 810   result = send_and_get(query_host, query_port, query_string);
 811   if(count_objects(result) == 0){
 812     cout << "No such inetnum" << endl;
 813     return NULL;
 814   }else if(count_objects(result) > 1){
 815     cout << "More than one inetnums returned" << endl;
 816     return NULL;
 817   }else{ /* count_objects(result) == 1 */
 818     return take_object(result);
 819   }
 820   
 821 }
 822 
 823 
 824 /* Takes a route object and returns exact match inetnum */
 825 char * get_exact_match_inetnum(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 826   bool code;
 827   char * search_key = NULL, * query_string = NULL;
 828   char * result = NULL;
 829   Object * o = new Object();
 830   
 831   code = o->scan(route_object, strlen(route_object));
 832   search_key = get_search_key(o, "route", route_object);
 833   
 834   query_string = (char *)malloc(strlen("-Tinetnum -r -x ") + strlen(search_key) + 1);
 835   sprintf(query_string, "-Tinetnum -r -x %s", search_key);
 836   result = send_and_get(query_host, query_port, query_string);
 837   if(count_objects(result) == 0){
 838     cout << "No such inetnum" << endl;
 839     return NULL;
 840   }else if(count_objects(result) > 1){
 841     cout << "More than one inetnums returned" << endl;
 842     return NULL;
 843   }else{ /* count_objects(result) == 1 */
 844     return take_object(result);
 845   }
 846   
 847 }
 848 
 849 
 850 
 851 /* Takes a route object and returns exact matches of this route */
 852 GSList * get_exact_match_routes(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 853   bool code;
 854   char * search_key = NULL, * query_string = NULL;
 855   char * result = NULL;
 856   Object * o = new Object();
 857   
 858   code = o->scan(route_object, strlen(route_object));
 859   search_key = get_search_key(o, "route", route_object);
 860   
 861   query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(search_key) + 1);
 862   sprintf(query_string, "-Troute -r -x %s", search_key);
 863   result = send_and_get(query_host, query_port, query_string);
 864   if(count_objects(result) == 0){
 865     //cout << "get_exact_match_routes: No such route" << endl;
 866     return NULL;
 867   }else{ /* count_objects(result) == 1 */
 868     return take_objects(result);
 869   }
 870   
 871 }
 872 
 873 
 874 
 875 /* Takes a route object and returns (immediate) less specifics of this route */
 876 GSList * get_less_spec_routes(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 877   bool code;
 878   char * search_key = NULL, * query_string = NULL;
 879   char * result = NULL;
 880   Object * o = new Object();
 881   
 882   code = o->scan(route_object, strlen(route_object));
 883   search_key = get_search_key(o, "route", route_object);
 884   
 885   query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(search_key) + 1);
 886   sprintf(query_string, "-Troute -r -l %s", search_key);
 887   result = send_and_get(query_host, query_port, query_string);
 888   if(count_objects(result) == 0){
 889     cout << "get_less_spec_routes: No such route" << endl;
 890     return NULL;
 891   }else{ /* count_objects(result) == 1 */
 892     return take_objects(result);
 893   }
 894   
 895 }
 896 
 897 
 898 
 899 /* Gets an object as a string and returns its 'mnt-by' attributes as a 
 900    GSList (linked list)   */
 901 /* No need for this function any more in fact. 'get_attr_list' can be used instead.
 902    All calls to get_mntners(object) must be converted into get_attr_list(object, "mnt-by") */
 903 
 904 GSList *get_mntners(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 905   bool code;
 906   Object * o;
 907   Attr *attr;
 908   char *value  = NULL;
 909   GSList *list_of_mntners = NULL;
 910   char * object; 
 911 
 912   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
 913    (no harm in having more than one) */
 914   object = (char *)malloc(strlen(arg) + 2);
 915   sprintf(object, "%s\n", arg);
 916 
 917   if(tracing) {
 918     printf("TRACING: get_mntners is running\n");
 919   }
 920   o = new Object;
 921   code = o->scan(object,strlen(object));
 922   
 923   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 924     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 925     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 926         attr->len - strlen(attr->type->name()) -2 );
 927     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 928     if(strcmp(attr->type->name(),"mnt-by") == 0){
 929       if(tracing) {
 930         cout << "TRACING: get_mntners: adding " << g_strstrip(value) << endl;
 931       }
 932       list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
 933     }
 934     free(value);
 935   }
 936 
 937   free(object);
 938   return list_of_mntners; 
 939 }
 940 
 941 
 942 /* Gets a preparsed object, its text and an attribute name. Returns a list of
 943    attribute values */
 944 GSList *get_attributes(Object * o, const char * attrib, const char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 945 
 946   char * value = NULL;
 947   Attr *attr;
 948   GSList *list_of_attributes = NULL;
 949 
 950   
 951   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 952     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 953     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 954         attr->len - strlen(attr->type->name()) -2 );
 955     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 956     if(strcmp(attr->type->name(), attrib) == 0){
 957       if(tracing) {
 958         cout << "TRACING: get_attributes: adding " << g_strstrip(value) << endl;
 959       }
 960       list_of_attributes = g_slist_append(list_of_attributes, g_strstrip(value));
 961     }
 962   }
 963 
 964   
 965   return list_of_attributes; 
 966 }
 967 
 968 
 969 /* Gets a preparsed object, an attribute name. Returns the value of first occurence
 970    of this attribute */
 971 char *get_attribute(Object * o, const char * attrib, char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 972 
 973   char * value = NULL;
 974   Attr *attr;
 975 
 976   if(tracing) {
 977     printf("TRACING: get_attributes is running\n");
 978   }
 979   
 980   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 981     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 982     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 983         attr->len - strlen(attr->type->name()) -2 );
 984     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 985     if(strcmp(attr->type->name(), attrib) == 0){
 986       if(tracing) {
 987         cout << "TRACING: get_attribute: will return " << value << endl;
 988       }
 989       return value;
 990     }else{
 991       free(value);
 992     }
 993   }
 994 
 995   if(tracing) {
 996     printf("TRACING: get_attribute is returning\n");
 997   }
 998   
 999   return NULL; 
1000 }
1001 
1002 
1003 
1004 /* Gets a GSList of strings and returns 1 if one of them starts with substr, 0 otherwise */
1005 int strstr_in_list(GSList * list, const char * substr){
     /* [<][>][^][v][top][bottom][index][help] */
1006 
1007  GSList * next = NULL;
1008  char * word; 
1009 
1010   if(tracing) {
1011     printf("TRACING: strstr_in_list is running\n");
1012   }
1013  
1014  for( next = list; next != NULL ; next = g_slist_next(next) ){
1015    word = strdup((char *)next->data);
1016    g_strup(word);
1017    if(strstr(word, substr) == word){
1018      free(word);
1019      return 1;
1020    }
1021    free(word);
1022  }
1023  /* none of them matched, so return 0 */
1024  return 0; 
1025 }
1026 
1027 
1028 
1029 
1030 
1031 /* Gets a (maintainer) object as a string and returns its 'auth' attributes 
1032    as a GSList (linked list) */
1033 
1034 GSList *get_auths(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1035   bool code;
1036   Object * o;
1037   Attr *attr;
1038   char *value  = NULL;
1039   GSList *list_of_auths = NULL;
1040 
1041   if(tracing){
1042     printf("TRACING: get_auths is running\n");
1043   }
1044   o = new Object;
1045   code = o->scan(object,strlen(object));
1046   
1047   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1048     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1049     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1050         attr->len - strlen(attr->type->name()) -2 );
1051     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1052     if(strcmp(attr->type->name(),"auth") == 0){
1053       if(tracing) {
1054         cout << "TRACING: get_auths: adding " << g_strstrip(value) << endl;
1055       }
1056       list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
1057       if(tracing) {
1058         cout << "TRACING: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
1059       }
1060     }
1061   }
1062 
1063   if(tracing) {
1064     cout << "TRACING: get_auths: returning (with " << g_slist_length(list_of_auths) << " nodes)" << endl;
1065   }
1066   return list_of_auths; 
1067 }
1068 
1069 
1070 
1071 
1072 /* Gets an object as a string an returns its 'attr_type' attributes as a 
1073    GSList (linked list) */
1074 
1075 GSList *get_attr_list(char * arg, char * attr_type){
     /* [<][>][^][v][top][bottom][index][help] */
1076   bool code;
1077   Object * o;
1078   Attr *attr;
1079   char *value  = NULL;
1080   GSList *list_of_attrs = NULL;
1081   char * object;
1082 
1083   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
1084    (no harm in having more than one) */
1085   object = (char *)malloc(strlen(arg) + 2);
1086   sprintf(object, "%s\n", arg);
1087 
1088   if(tracing) {
1089     printf("TRACING: get_attr_list is running, object is \n#%s#\n", object);
1090   }
1091   o = new Object;
1092   code = o->scan(object,strlen(object));
1093   
1094   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1095     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1096     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1097         attr->len - strlen(attr->type->name()) -2 );
1098     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1099     if(strcmp(attr->type->name(), attr_type) == 0){
1100       if(tracing) {
1101         cout << "TRACING: get_attr_list: adding " << g_strstrip(value) << endl;
1102       }
1103       list_of_attrs = g_slist_append(list_of_attrs, g_strstrip(value));
1104     }
1105   }
1106 
1107   free(object);
1108   return list_of_attrs; 
1109 }
1110 
1111 
1112 
1113 
1114 
1115 
1116 /* Gets an object as a string an returns its mnt_lower attributes as a 
1117    GSList (linked list) */
1118 
1119 GSList *get_mnt_lowers(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1120   bool code;
1121   Object * o;
1122   Attr *attr;
1123   char *value  = NULL;
1124   GSList *list_of_mnt_lowers = NULL;
1125 
1126 
1127   if(tracing) {
1128     printf("TRACING: get_mnt_lowers is running\n");
1129   }
1130   o = new Object;
1131   code = o->scan(object,strlen(object));
1132   
1133   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1134     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1135     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1136         attr->len - strlen(attr->type->name()) -2 );
1137     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1138     if(strcmp(attr->type->name(),"mnt-lower") == 0){
1139       if(tracing) {
1140         cout << "TRACING: get_mnt_lowers: adding " << g_strstrip(value) << endl;
1141       }
1142       list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
1143     }
1144   }
1145 
1146 
1147   return list_of_mnt_lowers; 
1148 }
1149 
1150 
1151 /* Gets an object as a string an returns its mnt_routes attributes as a 
1152    GSList (linked list) */
1153 
1154 GSList *get_mnt_routes(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1155   bool code;
1156   Object * o;
1157   Attr *attr;
1158   char *value  = NULL;
1159   GSList *list_of_mnt_routes = NULL;
1160 
1161   if(tracing) {
1162   cout << "TRACING: get_mnt_routes is running" << endl;
1163   }
1164   o = new Object;
1165   code = o->scan(object,strlen(object));
1166   
1167   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1168     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1169     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1170         attr->len - strlen(attr->type->name()) -2 );
1171     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1172     if(strcmp(attr->type->name(),"mnt-routes") == 0){
1173       if(tracing) {
1174         cout << "TRACING: get_mnt_routes: adding " << g_strstrip(value) << endl;
1175       }
1176       list_of_mnt_routes = g_slist_append(list_of_mnt_routes, strdup(g_strstrip(value)));
1177     }
1178   }
1179 
1180   return list_of_mnt_routes; 
1181 }
1182 
1183 
1184 /* Gets a linked list of objects and returns the mnt_routes attribs of
1185    them in a linked list */
1186 GSList *get_mnt_routes_from_list(GSList * objects){
     /* [<][>][^][v][top][bottom][index][help] */
1187   GSList *next = NULL;
1188   GSList *list_of_mnt_routes = NULL;
1189   
1190   for( next = objects; next != NULL ; next = g_slist_next(next) ){
1191     list_of_mnt_routes = g_slist_concat(list_of_mnt_routes, get_mnt_routes((char *)next->data));
1192   }
1193 
1194   return list_of_mnt_routes;
1195 }
1196 
1197 
1198 
1199 /* Gets a linked list of objects and returns the mnt_routes attribs of
1200    them in a linked list */
1201 GSList *get_mnt_lowers_from_list(GSList * objects){
     /* [<][>][^][v][top][bottom][index][help] */
1202   GSList *next = NULL;
1203   GSList *list_of_mnt_lowers = NULL;
1204   
1205   for( next = objects; next != NULL ; next = g_slist_next(next) ){
1206     list_of_mnt_lowers = g_slist_concat(list_of_mnt_lowers, get_mnt_lowers((char *)next->data));
1207   }
1208 
1209   return list_of_mnt_lowers;
1210 }
1211 
1212 
1213 
1214 /* retrieves the override password from the 'override' attribute  
1215    of the object. If none, it returns NULL   */
1216 char *get_override(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1217   bool code;
1218   Object * o;
1219   Attr *attr;
1220   char *value  = NULL;
1221 
1222   if(tracing){
1223     printf("TRACING: get_override is running\n");
1224   }
1225   o = new Object;
1226   code = o->scan(object,strlen(object));
1227   
1228   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1229     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1230     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1231         attr->len - strlen(attr->type->name()) -2 );
1232     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1233     if(strcmp(attr->type->name(),"override") == 0){
1234       if(tracing) {
1235         cout << "TRACING: get_override: returning " << g_strstrip(value) << endl;
1236       }
1237       return  strdup(g_strstrip(value));
1238     }
1239   }
1240   /* there was no 'override' attrib, so return NULL */
1241   return NULL; 
1242 }
1243 
1244 
1245 
1246 
1247 
1248 
1249 /* checks override string (password) 
1250    returns OVR_OK if it is correct password */
1251 int check_override(char * string){
     /* [<][>][^][v][top][bottom][index][help] */
1252    char ** temp;
1253    int i;
1254    char * crypted_password = strdup(overridecryptedpw);
1255    if(string == NULL) {
1256      if(tracing) {
1257        printf("TRACING: check_override is returning FAILED\n");
1258      }
1259      return UP_OVF; /* override attempt failed */ 
1260    }else{
1261     /* split the string */
1262      temp = g_strsplit (string, " ", 0);
1263 
1264      for(i=0; temp[i] != NULL; i++){
1265        if(strlen(temp[i]) != 0){
1266          if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0){
1267            g_strfreev(temp);
1268            if(tracing) {
1269              printf("TRACING: check_override is returning OK\n", string);
1270            }
1271            return OVR_OK; 
1272          }
1273        }
1274      }
1275 
1276      g_strfreev(temp);         
1277      /* we couldn't find a word matching the override password */ 
1278           return UP_OVF; /* override attempt failed */
1279    }
1280 }
1281 
1282 
1283 
1284 
1285 
1286 
1287 
1288 
1289 
1290 
1291 
1292 
1293 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
1294    add new elements to GSList of struct auth_struct and  returns the new
1295    GSList of struct auth_struct  */
1296 
1297 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
     /* [<][>][^][v][top][bottom][index][help] */
1298    GSList * next;
1299    char * auth_attrib = NULL;
1300    char * auth_attrib_uppercase = NULL, * argument = NULL;
1301    auth_struct * temp = NULL;
1302    int index = 1;
1303       
1304    for(next = auths; next != NULL; next = g_slist_next(next)){
1305      auth_attrib = strdup((char *)next->data);
1306      auth_attrib = g_strstrip(auth_attrib);
1307      if(tracing) {
1308        cout << "TRACING: add_to_auth_vector: " << auth_attrib << endl;
1309      }
1310      /* Take the auth attribute and convert it into uppercase for comparisons */
1311      auth_attrib_uppercase = strdup(auth_attrib);
1312      g_strup(auth_attrib_uppercase);
1313      
1314      if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
1315        /* take the argument of the auth attribute */
1316        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1317        g_strstrip(argument);
1318        if(tracing) {
1319          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1320        }
1321        temp = (auth_struct *)malloc(sizeof(auth_struct));
1322        temp->type = AU_CRYPT_PW;
1323        temp->auth = argument;
1324        temp->mntner_name = mntner_name;
1325        temp->index = index++;
1326        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1327      }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
1328        /* take the argument of the auth attribute */
1329        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1330        g_strstrip(argument);
1331        if(tracing) {
1332          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1333        }
1334        temp = (auth_struct *)malloc(sizeof(auth_struct));
1335        temp->type = AU_MAIL_FROM;
1336        temp->auth = argument;
1337        temp->mntner_name = mntner_name;
1338        temp->index = index++;
1339        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1340      }else if(strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase){
1341        /* take the argument of the auth attribute */
1342        temp = (auth_struct *)malloc(sizeof(auth_struct));
1343        temp->type = AU_NONE;
1344        temp->auth = NULL;
1345        temp->mntner_name = mntner_name;
1346        temp->index = index++;
1347        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1348     }else if(strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase){
1349        argument = strdup(auth_attrib + strlen("PGPKEY-"));
1350        g_strstrip(argument);
1351        if(tracing) {
1352          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1353        }
1354        temp = (auth_struct *)malloc(sizeof(auth_struct));
1355        temp->type = AU_PGP;
1356        temp->mntner_name = mntner_name;
1357        temp->index = index++;
1358        temp->auth = argument;
1359        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1360      }else{
1361        if(tracing){
1362          cout << "TRACING: Error: invalid auth attrib: " << auth_attrib << endl;
1363        }
1364        return NULL;
1365      }
1366    }
1367    free(auth_attrib_uppercase);
1368    free(auth_attrib); 
1369    return list_of_auth_struct;
1370 
1371 }
1372 
1373 
1374 
1375 
1376 
1377 
1378 
1379 
1380 
1381 /* Gets a list of mntner names, retrieves those mntners from
1382    the database and extracts the 'auth' attributes, and
1383    constructs the authorisation vector, which is a GSList of
1384    struct auth_struct */
1385 
1386 GSList * get_auth_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1387   GSList * list_of_auths = NULL;
1388   GSList * next = NULL;
1389   GSList * to_be_returned = NULL;
1390   char * query_string = NULL, * result = NULL, * object = NULL;
1391   GSList * temp;
1392 
1393   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1394     if(tracing) {
1395       cout << "=====" << endl << "Got a mntner" << endl;
1396       cout << (char *)next->data << endl;
1397     }
1398     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1399     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1400     result = send_and_get(query_host, query_port, query_string);
1401     if(count_objects(result) == 0){
1402       /* no such maintainer */
1403       return NULL;
1404     }else if(count_objects(result) > 1){
1405       if(tracing) {
1406         cout << "More than one objects returned" << endl;
1407       }
1408     }else{ /* count_objects(result) == 1 */
1409       object = take_object(result);
1410       if(tracing) {
1411         printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1412       }
1413       temp = get_auths(object);
1414       if(tracing) {
1415         cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1416       }
1417       list_of_auths = g_slist_concat(list_of_auths, temp);
1418       if(tracing) {
1419         cout << "TRACING: get_auth_vector: list_of_auths has now " <<  g_slist_length(list_of_auths) << " nodes" << endl;
1420       }
1421       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1422       if(tracing) {
1423        cout << "TRACING: get_auth_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1424       }
1425       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1426     }
1427   }
1428   
1429   if(tracing) {  
1430     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1431   }
1432   return to_be_returned; 
1433 }
1434 
1435 
1436 
1437 
1438 
1439 
1440 
1441 /* Gets a list of mntner names, retrieves those mntners from
1442    the database and extracts the 'mnt-by' attributes, and
1443    returns them as a GSList */
1444 
1445 GSList * get_mntnfy_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1446   GSList * list_of_mntnfy = NULL;
1447   GSList * next = NULL;
1448   //GSList * to_be_returned = NULL;
1449   char * query_string = NULL, * result = NULL, * object = NULL;
1450   GSList * temp;
1451   
1452   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1453     if(tracing) {
1454       cout << "=====" << endl << "Got a mntner" << endl;
1455       cout << (char *)next->data << endl;
1456     }
1457     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1458     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1459     result = send_and_get(query_host, query_port, query_string);
1460     if(count_objects(result) == 0){
1461       /* no such maintainer */
1462     }else if(count_objects(result) > 1){
1463       if(tracing) {
1464         cout << "More than one objects returned" << endl;
1465       }
1466     }else{ /* count_objects(result) == 1 */
1467       object = take_object(result);
1468       if(tracing) {
1469         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1470       }
1471       temp = get_attr_list(object, "mnt-nfy");
1472       if(tracing) {
1473         cout << "TRACING: get_mntnfy_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1474       }
1475       list_of_mntnfy = g_slist_concat(list_of_mntnfy, temp);
1476       if(tracing) {
1477         cout << "TRACING: get_mntnfy_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_mntnfy) << " nodes" << endl;
1478       }
1479     }
1480   }
1481   
1482   if(tracing) {  
1483     printf("TRACING: get_auth_vector: list_of_mntnfy has %i nodes\n", g_slist_length(list_of_mntnfy)); 
1484   }
1485   return list_of_mntnfy; 
1486 }
1487 
1488 
1489 
1490 
1491 
1492 
1493 /* Gets a list of mntner names, retrieves those mntners from
1494    the database and extracts the 'upd-to' attributes, and
1495    returns them as a GSList */
1496 
1497 GSList * get_updto_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1498   GSList * list_of_updto = NULL;
1499   GSList * next = NULL;
1500   char * query_string = NULL, * result = NULL, * object = NULL;
1501   GSList * temp;
1502   
1503   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1504     if(tracing) {
1505       cout << "=====" << endl << "Got a mntner" << endl;
1506       cout << (char *)next->data << endl;
1507     }
1508     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1509     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1510     result = send_and_get(query_host, query_port, query_string);
1511     if(count_objects(result) == 0){
1512       /* no such maintainer */
1513     }else if(count_objects(result) > 1){
1514       if(tracing) {
1515         cout << "More than one objects returned" << endl;
1516       }
1517     }else{ /* count_objects(result) == 1 */
1518       object = take_object(result);
1519       if(tracing) {
1520         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1521       }
1522       temp = get_attr_list(object, "upd-to");
1523       if(tracing) {
1524         cout << "TRACING: get_updto_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1525       }
1526       list_of_updto = g_slist_concat(list_of_updto, temp);
1527       if(tracing) {
1528         cout << "TRACING: get_updto_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_updto) << " nodes" << endl;
1529       }
1530     }
1531   }
1532   
1533   if(tracing) {  
1534     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_slist_length(list_of_updto)); 
1535   }
1536   return list_of_updto; 
1537 }
1538 
1539 
1540 
1541 
1542 
1543 
1544 
1545 
1546 
1547 
1548 /* gets one or more route objects filters out the ones which don't have the same
1549    origin as 'char * origin' argument */
1550 char * filter_out_diff_origins(char * objects, char * origin){
     /* [<][>][^][v][top][bottom][index][help] */
1551   GSList * object_list = NULL, * next =NULL;
1552   char * objects_to_be_returned = NULL;
1553   bool code;
1554   char * key = NULL;
1555   Object * o = new Object();
1556   
1557   
1558   if(tracing) {
1559     printf("TRACING: filter_out_diff_origins\n");
1560   }
1561 
1562   /* strip the lines beginning with '%' off */
1563   objects = strip_lines(objects);
1564   
1565   /* separate the objects, store them in a linked list */
1566   object_list = take_objects(objects);
1567 
1568   for(next = object_list; next != NULL; next = g_slist_next(next)){
1569     code = o->scan((char *)next->data, strlen((char *)next->data));
1570     key = get_search_key(o, "origin", (char *)next->data);
1571     if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1572       if(objects_to_be_returned == NULL){
1573         objects_to_be_returned = strdup((char *)next->data);
1574       }else{
1575         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
1576                       strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1577         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1578         objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1579       }
1580     }
1581   }
1582 
1583   delete(o);
1584   if(tracing) {
1585     if(objects_to_be_returned != NULL){
1586       printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1587     }else {
1588       printf("TRACING: filter_out_diff_origins: returning NULL\n");
1589       
1590     }
1591   }
1592   return objects_to_be_returned; 
1593   
1594 }
1595 
1596 
1597 
1598 
1599 /* Check authorisation
1600    Applies authorisation rules according to the object type 
1601    
1602    Arguments:
1603       char *new_object: the new object,
1604       char *old_object: the old object, as found in the database,
1605       char *type: type of the object
1606       credentials_struct credentials: a struct which
1607         contains credentials of the update, such as 'From:' field of
1608         the e-mail header and passwords in the update   */
1609 
1610 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
     /* [<][>][^][v][top][bottom][index][help] */
1611    
1612    GSList *old_mntners = NULL, *new_mntners = NULL;
1613    GSList *old_auths = NULL, *new_auths = NULL;
1614    GSList *as_block_mnt_lowers = NULL;
1615    GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1616    GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1617    GSList *less_specific_mntners = NULL;
1618    GSList *aut_num_maintainers = NULL;
1619    GSList *aut_num_auth_vector = NULL;
1620    GSList *exact_match_routes = NULL;  
1621    GSList *exact_match_routes_maintainers = NULL;
1622    GSList *exact_match_routes_auth_vector = NULL;
1623    GSList *less_spec_routes = NULL;
1624    GSList *less_spec_routes_mntners = NULL;
1625    GSList *less_spec_routes_auth_vector = NULL;
1626    GSList *exact_match_inetnum_mnt_routes = NULL;
1627    GSList *exact_match_inetnum_auth_vector = NULL;
1628    GSList *less_spec_inetnum_mntners = NULL;
1629    GSList *less_spec_inetnum_auth_vector = NULL;
1630    GSList *exact_match_intenum_auth_vector = NULL;
1631    GSList *exact_match_auth_vector = NULL;
1632     
1633    char *as_block_object = NULL, *less_specific_object = NULL;
1634    char *less_specific_domain = NULL;
1635    char *less_spec_inetnum = NULL;
1636    char *exact_match_inetnum = NULL;
1637    char *less_specific_object_type = NULL;
1638    char *override_string = NULL;
1639    char *set_name = NULL;
1640    char * aut_num_object = NULL;
1641    Object *set_object = new Object();
1642    Object *temp_obj;
1643    bool code;
1644    bool aut_num_auth_OK = false;
1645 
1646    int overriden = 0;
1647    
1648    /* first check if it is overriden or not. if overriden, check the override
1649       password. If it is correct, continue, setting "overriden" to 1. If not,   
1650       immediately exit returning ERR_UP_OVF                                   */
1651    override_string = get_override((new_object == NULL) ? old_object : new_object );
1652    if(override_string == NULL){ 
1653      overriden = 0;
1654    }else if(check_override(override_string) == OVR_OK){
1655      overriden = 1; /* authorisation is overriden */
1656      free(override_string);override_string = NULL;
1657    }else if(check_override(override_string) == UP_OVS){
1658      free(override_string);override_string = NULL;
1659      return UP_OVS; /* override syntax error --it must have at least two words */
1660    }else{
1661      free(override_string);override_string = NULL;
1662      return UP_OVF; /* override failed! */
1663    }
1664 
1665 
1666    /*  
1667     *  Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types 
1668     */
1669    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
1670       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
1671       strcmp(type,"key-cert") == 0 ){
1672      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1673        old_mntners = get_mntners(old_object);
1674        old_auth_vector = get_auth_vector(old_mntners);
1675        return authorise(old_auth_vector, credentials, overriden);
1676      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1677        new_mntners = get_mntners(new_object);
1678        new_auth_vector = get_auth_vector(new_mntners);
1679        if(new_mntners != NULL && new_auth_vector == NULL){
1680          /* then, the mntners in 'new_mntners' do not exist. Problem. */
1681          return UP_AUF; /* auth failed */
1682        }
1683        return authorise(new_auth_vector, credentials, overriden);
1684      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1685        old_mntners = get_mntners(old_object);
1686        old_auth_vector = get_auth_vector(old_mntners);
1687        if(old_mntners != NULL && old_auth_vector == NULL){
1688          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1689          return UP_AUF; /* auth failed */
1690        }
1691        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1692          return authorise(old_auth_vector, credentials, overriden);
1693        }else{
1694          new_mntners = get_mntners(new_object);
1695          new_auth_vector = get_auth_vector(new_mntners);
1696          if(new_mntners != NULL && new_auth_vector == NULL){
1697            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1698            return UP_AUF; /* auth failed */
1699          }
1700          return authorise(new_auth_vector, credentials, overriden);
1701        }
1702      }else{ // both are NULL, mustn't happen
1703          if(tracing){
1704            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1705          }
1706          return UP_INT; /* internal error */
1707      }
1708    }
1709 
1710    /*  
1711     *  Handle the "auth-num" type 
1712     */
1713    else if(strcmp(type,"aut-num")  == 0 ){
1714      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1715        old_mntners = get_mntners(old_object);
1716        old_auth_vector = get_auth_vector(old_mntners);
1717        if(old_mntners != NULL && old_auth_vector == NULL){
1718          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1719          return UP_AUF; /* auth failed */
1720        }
1721        return authorise(old_auth_vector, credentials, overriden);
1722      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1723        as_block_object = get_as_block(new_object);
1724        if(as_block_object == NULL ){
1725          return UP_ABN; /* As-block does not exist */
1726          }else{
1727            as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1728            as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1729            if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1730              /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1731              return UP_AUF; /* auth failed */
1732            }
1733          if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1734            new_mntners = get_mntners(new_object);
1735            new_auth_vector = get_auth_vector(new_mntners);
1736            if(new_mntners != NULL && new_auth_vector == NULL){
1737              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1738              return UP_AUF; /* auth failed */
1739            }
1740            return authorise(new_auth_vector, credentials, overriden);
1741          }else{
1742            return UP_HOF; /* hierarchical auth failed */
1743          }
1744        }
1745      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1746        old_mntners = get_mntners(old_object);
1747        old_auth_vector = get_auth_vector(old_mntners);
1748        if(old_mntners != NULL && old_auth_vector == NULL){
1749          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1750          return UP_AUF; /* auth failed */
1751        }
1752        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1753          return authorise(old_auth_vector, credentials, overriden);
1754        }else{
1755          new_mntners = get_mntners(new_object);
1756          new_auth_vector = get_auth_vector(new_mntners);
1757          if(new_mntners != NULL && new_auth_vector == NULL){
1758            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1759            return UP_AUF; /* auth failed */
1760          }
1761          return authorise(new_auth_vector, credentials, overriden);
1762        }
1763      }else{ /* both are NULL, mustn't happen */
1764          if(tracing) {
1765            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1766          } 
1767          return UP_INT; /* internal error */
1768      }
1769    } 
1770 
1771    /*  
1772     *  Handle the "mntner/as-block" types 
1773     */
1774    else if(strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 ){
1775      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1776        old_mntners = get_mntners(old_object);
1777        old_auth_vector = get_auth_vector(old_mntners);
1778        if(old_mntners != NULL && old_auth_vector == NULL){
1779          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1780          return UP_AUF; /* auth failed */
1781        }
1782        return authorise(old_auth_vector, credentials, overriden);
1783      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1784        if(overriden || test_mode){
1785          return UP_AUTH_OK; 
1786        }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
1787          if(tracing) {
1788            cout << "TRACING: check_auth: '" << type << "' creation requested" << endl;
1789          }
1790          return UP_AUF; /* authorisation failed */
1791        }
1792      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1793        old_mntners = get_mntners(old_object);
1794        old_auth_vector = get_auth_vector(old_mntners);
1795        if(old_mntners != NULL && old_auth_vector == NULL){
1796          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1797          return UP_AUF; /* auth failed */
1798        }
1799        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1800          return authorise(old_auth_vector, credentials, overriden);
1801        }else{
1802          new_mntners = get_mntners(new_object);
1803          new_auth_vector = get_auth_vector(new_mntners);
1804          if(new_mntners != NULL && new_auth_vector == NULL){
1805            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1806            return UP_AUF; /* auth failed */
1807          }
1808          return authorise(new_auth_vector, credentials, overriden);
1809        }
1810      }else{ // both are NULL, mustn't happen
1811          if(tracing){
1812            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1813          }
1814          return UP_INT; /* internal error */
1815      }
1816    }
1817 
1818    /*  
1819     *  Handle the "inetnum/inet6num" types 
1820     */
1821    else if(strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 ){
1822      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1823        old_mntners = get_mntners(old_object);
1824        old_auth_vector = get_auth_vector(old_mntners);
1825        if(old_mntners != NULL && old_auth_vector == NULL){
1826          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1827          return UP_AUF; /* auth failed */
1828        }
1829        return authorise(old_auth_vector, credentials, overriden);
1830      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1831        less_specific_object = get_less_specific(new_object, type);
1832        if(less_specific_object == NULL){
1833          if(overriden){
1834            return UP_AUTH_OK; 
1835          }else{
1836            return UP_HOF; /* hierarchical authorisation failed */
1837          }
1838        }else{ /* if we got an inet(6)num object */
1839          less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1840          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1841          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1842            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1843            return UP_AUF; /* auth failed */
1844          }
1845          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1846            new_mntners = get_mntners(new_object);
1847            new_auth_vector = get_auth_vector(new_mntners);
1848            if(new_mntners != NULL && new_auth_vector == NULL){
1849              /* then, the mntners in 'new_mntners' do not exist. Problem. */
1850              return UP_AUF; /* auth failed */
1851            }
1852            return authorise(new_auth_vector, credentials, overriden);
1853          }else{
1854            return UP_HOF; /* hierarchical authorisation failed */
1855          }
1856        }
1857      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1858        old_mntners = get_mntners(old_object);
1859        old_auth_vector = get_auth_vector(old_mntners);
1860        if(old_mntners != NULL && old_auth_vector == NULL){
1861          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1862          return UP_AUF; /* auth failed */
1863        }
1864        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1865          return authorise(old_auth_vector, credentials, overriden);
1866        }else{
1867          new_mntners = get_mntners(new_object);
1868          new_auth_vector = get_auth_vector(new_mntners);
1869          if(new_mntners != NULL && new_auth_vector == NULL){
1870            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1871            return UP_AUF; /* auth failed */
1872          }
1873          return authorise(new_auth_vector, credentials, overriden);
1874        }
1875      }else{ /* both are NULL, mustn't happen */
1876          if(tracing){
1877            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1878          }
1879          return UP_INT; /* internal error */
1880      }
1881    }
1882 
1883 
1884    
1885    /*  
1886     *  Handle the "domain" type 
1887     */
1888    else if(strcmp(type,"domain")  == 0){
1889      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1890        old_mntners = get_mntners(old_object);
1891        old_auth_vector = get_auth_vector(old_mntners);
1892        if(old_mntners != NULL && old_auth_vector == NULL){
1893          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1894          return UP_AUF; /* auth failed */
1895        }
1896        return authorise(old_auth_vector, credentials, overriden);
1897      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1898        /* now, we have to find a 'less specific domain object' for this. 
1899           If there is no less specific object, then creation is possible
1900           only with overriding. */
1901       less_specific_domain = get_less_specific_domain(new_object);
1902       if(less_specific_domain == NULL){
1903         if(overriden){/* we didn't get a 'less specific' domain object */
1904            return UP_AUTH_OK; 
1905          }else{
1906            return UP_HOF; /* hierarchical authorisation failed */
1907          }
1908       }else{ /* we get a 'less specific' domain object */
1909          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
1910          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1911          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1912            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1913            return UP_AUF; /* auth failed */
1914          }
1915          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1916            new_mntners = get_mntners(new_object);
1917            new_auth_vector = get_auth_vector(new_mntners);
1918            if(new_mntners != NULL && new_auth_vector == NULL){
1919              /* then, the mntners in 'new_mntners' do not exist. Problem. */
1920              return UP_AUF; /* auth failed */
1921            }
1922            return authorise(new_auth_vector, credentials, overriden);
1923          }else{
1924            return UP_HOF; /* hierarchical authorisation failed */
1925          }
1926         
1927       }
1928      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1929        old_mntners = get_mntners(old_object);
1930        old_auth_vector = get_auth_vector(old_mntners);
1931        if(old_mntners != NULL && old_auth_vector == NULL){
1932          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1933          return UP_AUF; /* auth failed */
1934        }
1935        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1936          return authorise(old_auth_vector, credentials, overriden);
1937        }else{
1938          new_mntners = get_mntners(new_object);
1939          new_auth_vector = get_auth_vector(new_mntners);
1940          if(new_mntners != NULL && new_auth_vector == NULL){
1941            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1942            return UP_AUF; /* auth failed */
1943          }
1944          return authorise(new_auth_vector, credentials, overriden);
1945        }
1946      }else{ /* both are NULL, mustn't happen */
1947          if(tracing){
1948            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1949          }
1950          return UP_INT; /* internal error */
1951      }
1952    }
1953    
1954 
1955    /*  
1956     *  Handle the "route" type 
1957     */
1958    else if(strcmp(type,"route")  == 0){
1959      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1960        old_mntners = get_mntners(old_object);
1961        old_auth_vector = get_auth_vector(old_mntners);
1962        if(old_mntners != NULL && old_auth_vector == NULL){
1963          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1964          return UP_AUF; /* auth failed */
1965        }
1966        return authorise(old_auth_vector, credentials, overriden);
1967      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1968        /* first we have to find the aut-num object mentioned in the 
1969           origin attribute */
1970 
1971        aut_num_object = get_aut_num_object(new_object); 
1972        if(aut_num_object == NULL){
1973          if(overriden){
1974            return UP_AUTH_OK; 
1975          }else{
1976            return UP_HOF; /* hierarchical authorisation failed */
1977          }
1978        }else{/* there is a corresponding aut-num in the db */
1979          if(tracing){
1980            printf("TRACING: check_auth: will try to authorise the route using aut-num\n");
1981          }
1982          aut_num_maintainers = get_mnt_routes(aut_num_object);
1983          if(aut_num_maintainers != NULL){
1984            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1985            if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1986              aut_num_auth_OK = true;
1987            }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1988              return UP_HOF;
1989            }
1990          }else{/* aut_num_maintainers is NULL */
1991             aut_num_maintainers = get_mnt_lowers(aut_num_object);
1992             if(aut_num_maintainers != NULL){
1993               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1994               if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1995                 aut_num_auth_OK = TRUE;
1996               }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1997                 return UP_HOF; /* hierarchical authorisation failed */
1998               }
1999             }else{/* aut_num_maintainers is NULL */
2000               aut_num_maintainers = get_mntners(aut_num_object);
2001               if(aut_num_maintainers != NULL){
2002                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
2003                 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
2004                   aut_num_auth_OK = TRUE;
2005                 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
2006                   return UP_HOF; /* hierarchical authorisation failed */
2007                 }
2008               }else{/* aut_num_maintainers is NULL */
2009                 aut_num_auth_OK = TRUE;
2010               }
2011               
2012             }
2013          }
2014          if(aut_num_auth_OK){
2015            /* now, we have to find an exact match for this route object. 
2016               If there is no exact match object, then we will go on to find
2017               less specific. */
2018            exact_match_routes = get_exact_match_routes(new_object);
2019            if(exact_match_routes != NULL){
2020              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
2021              exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
2022              if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
2023                /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
2024                return UP_AUF; /* auth failed */
2025               }
2026              if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
2027                /* then, check mnt_bys of the route itself */
2028                new_mntners = get_mntners(new_object);
2029                new_auth_vector = get_auth_vector(new_mntners);
2030                if(new_mntners != NULL && new_auth_vector == NULL){
2031                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
2032                  return UP_AUF; /* auth failed */
2033                }
2034                return authorise(new_auth_vector, credentials, overriden);
2035              }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
2036                return UP_HOF; /* hierarchical authorisation failed */
2037              }
2038            }else{ /* exact_match_routes == NULL */
2039              /* then we have to look for less specific route objs */
2040              less_spec_routes = get_less_spec_routes(new_object);
2041              if(less_spec_routes != NULL){
2042                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
2043                less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners, 
2044                                              get_mnt_lowers_from_list(less_spec_routes));
2045                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
2046                if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
2047                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
2048                  return UP_AUF; /* auth failed */
2049                }
2050                if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
2051                  /* then, check mnt_bys of the route itself */
2052                  new_mntners = get_mntners(new_object);
2053                  new_auth_vector = get_auth_vector(new_mntners);
2054                  if(new_mntners != NULL && new_auth_vector == NULL){
2055                    /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2056                    return UP_AUF; /* auth failed */
2057                  }
2058                  return authorise(new_auth_vector, credentials, overriden);
2059                }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
2060                  return UP_HOF; /* hierarchical authorisation failed */
2061                }
2062             }else{/* less_spec_routes == NULL */
2063                /* so, we have to get the exact match inetnum */
2064                exact_match_inetnum = get_exact_match_inetnum(new_object);
2065                if(exact_match_inetnum != NULL){
2066                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
2067                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
2068                  if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
2069                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
2070                    return UP_AUF; /* auth failed */
2071                  }
2072                  if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
2073                    /* then, check mnt_bys of the route itself */
2074                    new_mntners = get_mntners(new_object);
2075                    new_auth_vector = get_auth_vector(new_mntners);
2076                    if(new_mntners != NULL && new_auth_vector == NULL){
2077                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2078                      return UP_AUF; /* auth failed */
2079                    }
2080                    return authorise(new_auth_vector, credentials, overriden);
2081                  }else{
2082                    return UP_HOF; /* hierarchical authorisation failed */
2083                  }
2084                }else{/* exact_match_inetnum == NULL */
2085                  /* then, we will try to find less spec inetnums */
2086                  less_spec_inetnum = get_less_spec_inetnum(new_object);
2087                  if(less_spec_inetnum != NULL){
2088                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
2089                    less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners, 
2090                                   get_mnt_lowers(less_spec_inetnum));
2091                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
2092                    if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
2093                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
2094                      return UP_AUF; /* auth failed */
2095                    }
2096                    if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
2097                      /* then, check mnt_bys of the route itself */
2098                      new_mntners = get_mntners(new_object);
2099                      new_auth_vector = get_auth_vector(new_mntners);
2100                      if(new_mntners != NULL && new_auth_vector == NULL){
2101                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2102                        return UP_AUF; /* auth failed */
2103                      }
2104                      return authorise(new_auth_vector, credentials, overriden);
2105                    }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
2106                      return UP_HOF; /* hierarchical authorisation failed */
2107                    }
2108                  }else{/* less_spec_inetnum == NULL */
2109                    /* now that we couldn't find any route or inetnum object
2110                       to be used in authentication. So, only if the auth is
2111                       overriden the object will be created. */
2112                    if(overriden){
2113                      return UP_AUTH_OK; 
2114                    }else{
2115                      return UP_HOF; /* hierarchical authorisation failed */
2116                    }
2117                  }
2118                }
2119              }
2120            }
2121          }else{/* ! aut_num_auth_OK */
2122            return UP_HOF; /* hierarchical auth failed */
2123          }
2124 
2125        }
2126           
2127      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2128        old_mntners = get_mntners(old_object);
2129        old_auth_vector = get_auth_vector(old_mntners);
2130        if(old_mntners != NULL && old_auth_vector == NULL){
2131          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2132          return UP_AUF; /* auth failed */
2133        }
2134        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2135          return authorise(old_auth_vector, credentials, overriden);
2136        }else{
2137          new_mntners = get_mntners(new_object);
2138          new_auth_vector = get_auth_vector(new_mntners);
2139          if(new_mntners != NULL && new_auth_vector == NULL){
2140            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2141            return UP_AUF; /* auth failed */
2142          }
2143          return authorise(new_auth_vector, credentials, overriden);
2144        }
2145      }else{ /* both are NULL, mustn't happen */
2146          if(tracing){
2147            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2148          }
2149          return UP_INT; /* internal error */
2150      }
2151    }
2152 
2153 
2154    /*  
2155     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types 
2156     */
2157    else if(strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
2158            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
2159            strcmp(type,"route-set")    == 0 ){
2160      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2161        old_mntners = get_mntners(old_object);
2162        old_auth_vector = get_auth_vector(old_mntners);
2163        if(old_mntners != NULL && old_auth_vector == NULL){
2164          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2165          return UP_AUF; /* auth failed */
2166        }
2167        return authorise(old_auth_vector, credentials, overriden);
2168      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2169         code = set_object->scan(new_object, strlen(new_object));
2170         set_name = get_search_key(set_object, type, new_object);
2171        if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
2172          new_mntners = get_mntners(new_object);
2173          new_auth_vector = get_auth_vector(new_mntners);
2174          if(new_mntners != NULL && new_auth_vector == NULL){
2175            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2176            return UP_AUF; /* auth failed */
2177          }
2178          return authorise(new_auth_vector, credentials, overriden);
2179        }else{/* the name is hierarchical */
2180          less_specific_object = get_less_specific_set(new_object, type);
2181          if(less_specific_object != NULL){/* such an object exists */
2182            temp_obj = new Object();
2183            code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
2184            less_specific_object_type = get_class_type(temp_obj);
2185            delete(temp_obj);
2186            if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
2187              less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2188              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2189              if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2190                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
2191               return UP_AUF; /* auth failed */
2192              }
2193              if(less_specific_auth_vector != NULL){
2194                return authorise(less_specific_auth_vector, credentials, overriden);
2195              }else{/* the less specific object doesn't contain any mnt-lower */
2196                less_specific_mntners = get_mntners(less_specific_object);
2197                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2198                if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2199                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2200                  return UP_AUF; /* auth failed */
2201                }
2202                if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs, 
2203                                                         use them  */
2204                    return authorise(less_specific_auth_vector, credentials, overriden);
2205                }else{/* the less specific object doesn't contain any mnt-by either */
2206                  if(overriden){
2207                    return UP_AUTH_OK; 
2208                  }else{
2209                    return UP_HOF; /* hierarchical authorisation failed */
2210                  }
2211                }
2212              }
2213            }else{ /* this is _not_ an aut-num object*/
2214              less_specific_mntners = get_mntners(less_specific_object);
2215              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2216              if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2217                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2218                return UP_AUF; /* auth failed */
2219              }
2220              if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
2221                return authorise(less_specific_auth_vector, credentials, overriden);
2222              }else{
2223                if(overriden){
2224                  return UP_AUTH_OK; 
2225                }else{
2226                  return UP_HOF; /* hierarchical authorisation failed */
2227                }
2228              }
2229            }
2230 
2231          }else{/* we don't have a less specific of this set object in the DB  */
2232            return UP_HOF; /* hierarchical authorisation failed */
2233          }
2234        }
2235      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2236        old_mntners = get_mntners(old_object);
2237        old_auth_vector = get_auth_vector(old_mntners);
2238        if(old_mntners != NULL && old_auth_vector == NULL){
2239          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2240          return UP_AUF; /* auth failed */
2241        }
2242        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2243          return authorise(old_auth_vector, credentials, overriden);
2244        }else{
2245          new_mntners = get_mntners(new_object);
2246          new_auth_vector = get_auth_vector(new_mntners);
2247          if(new_mntners != NULL && new_auth_vector == NULL){
2248            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2249            return UP_AUF; /* auth failed */
2250          }
2251          return authorise(new_auth_vector, credentials, overriden);
2252        }
2253      }else{ /* both are NULL, mustn't happen */
2254          if(tracing){
2255            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2256          }
2257          return UP_INT; /* internal error */
2258      }
2259    
2260 
2261 
2262 
2263 
2264    }else{ /* We exhausted all object classes. If we are here, then there is a problem */
2265      cout << "check_auth: This type '" << type << "' is unknown" << endl;
2266      return UP_NIY; /* not implemented yet */
2267    }
2268    return UP_AUF; /* if we come to this point, then auth failed */ 
2269 }
2270 
2271 
2272 
2273 
2274 
2275 
2276 /* Gets the old version of the given "arg" object, which is in char * format
2277    and returns the old version again in char * format */
2278 
2279 char * get_old_version(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2280 
2281     bool code = true;
2282     char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2283     Object *o;
2284     o = new Object;
2285     char *result = NULL, *origin = NULL;
2286     
2287     error = 0; 
2288     code = o->scan(arg,strlen(arg));
2289     type = get_class_type(o);
2290     primary_search_key = get_search_key(o, type, arg);
2291     if(tracing) {
2292       cout << "type=" << type << endl;
2293       cout << "primary_search_key=" << primary_search_key << endl;
2294     }
2295     /* if the object is a pn ro a ro object, then get all pn/ro's with the
2296        same NIC hdl */
2297     if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2298       /* prepare the search string */
2299       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2300                                           + strlen("person,role") + 2);
2301       sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2302     }else{
2303       /* prepare the search string */
2304       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2305                                           + strlen(type) + 2);
2306       sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2307     }
2308     result = send_and_get(query_host, query_port, search_string);
2309     if(tracing) {
2310       cout << "TRACING: send_and_get has returned" << endl;
2311       cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl 
2312            << result << endl;
2313     }
2314     /* Attention: here we must also check these:
2315          for ro/pn objects: The name must also the same. When the NIC hdl is the
2316                same but names are different, we must somehow return an error.
2317                Also, when we search for a person, we must also look for role objects
2318                (and vice versa) since the RIPupdate does not distinguish between
2319                role & person objects. We have to check it here.
2320          for rt objects: We also have to check the identicalness of origin
2321                attributes.                
2322                
2323           These are not yet implemented.     
2324                */
2325 
2326     if(strcmp(type,"route") == 0){
2327       if(tracing) {
2328         printf("TRACING: This is a route\n");
2329       }
2330       /* if this is a route, then we must filter out the routes with different
2331          origin attributes */
2332       origin = get_search_key(o, "origin", arg);
2333       if(tracing) {
2334         printf("TRACING: Got origin of route: %s\n", origin);
2335       }
2336       result = filter_out_diff_origins(result, origin);  
2337       if(tracing) {
2338         printf("TRACING: Filtered routes\n");
2339       }
2340     }
2341     // count the objects
2342     if(count_objects(result) == 0){
2343       result = NULL; /* we don't have such an object */
2344     }else if(count_objects(result) == 1){
2345       result = take_object(result);
2346       if(tracing) {
2347       cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2348       }
2349     }else{ /* we have more than one objects, error! */
2350       error = UP_MOR;
2351       return NULL;
2352     }
2353     return result;
2354 }
2355 
2356 
2357 
2358 
2359 /* Gets a credentials_struct whose 'from' field will be filled in and
2360    the mail header. Finds the 'From:' line in the header and sets
2361    the 'from' field to this line (all line, including the 'From:' string,
2362    since some users have put regexps which match the whole line in their
2363    'auth' attributes.) */
2364 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2365   char * header = strdup(arg);
2366   char * temp = (char *)malloc(strlen(header));
2367   while(index(header, '\n') != NULL){
2368     temp = strdup(header);
2369     temp[index(temp, '\n') - temp] = '\0';
2370     if(strstr(temp, "From:") == temp){
2371       if(tracing) {
2372         printf("TRACING: process_mail_header: Assigning %s\n", temp);
2373       }
2374       credentials_ptr->from = strdup(temp);
2375       free(temp);
2376       return;
2377     }
2378     header = header + (index(header, '\n') - header + 1);
2379   }
2380   free(temp);
2381 }
2382 
2383 
2384 
2385 
2386 
2387 
2388 void up_string_pack(char *dest, const char *source){
     /* [<][>][^][v][top][bottom][index][help] */
2389    
2390   if(tracing) {
2391     printf("TRACING: up_string_pack running\n");
2392   }
2393         
2394 
2395 
2396 /*----------------------------------------------------------------------*\
2397 
2398 *  Function to rewrite a line of text with only one blankspace between  *
2399 *  each word.
2400 *
2401 
2402 \*----------------------------------------------------------------------*/
2403 
2404 
2405 /*
2406  * This while loop continues until the NULL character is copied into
2407  * the destination string.  If a tab character is copied into the
2408  * destination string, it is replaced with a blank-space character.
2409  *
2410  * Multiple blank-space and/or tab characters are skipped in the source
2411  * string until any other character is found.
2412  */
2413 
2414         while (1)
2415                 {
2416                 *dest = *source;
2417 
2418                 if (*dest == '\t')
2419                         (*dest = ' ');
2420 
2421                 /* Exit if have copied the end of the string. */
2422                 if (*dest == '\0')
2423                         return;
2424 
2425 /*
2426  * If the source character was a blank-space or a tab, move to the next
2427  * source character.  While the source character is a blank-space or a
2428  * tab, move to the next character (i.e. ignore these characters).  When
2429  * any other character is found in the source string, move to the next
2430  * element of the destination string.
2431  *
2432  * Otherwise, simultaneously, move to the next elements of the destination
2433  * and the source strings.
2434  */
2435 
2436 
2437 
2438                 if ( (*source == ' ') || (*source == '\t') )
2439                         {
2440                         ++source;
2441                         while ( (*source == ' ') || (*source == '\t') )
2442                                 {
2443                                 ++source;
2444                                 }
2445 
2446                         ++dest;
2447                         }
2448                 else
2449                         {
2450                         ++dest;
2451                         ++source;
2452                         }
2453                 }
2454 }
2455 
2456 
2457 
2458 
2459 
2460 
2461 
2462 
2463 /* strips lines beginning with "delete:" off  */
2464 char * delete_delete_attrib(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2465 
2466     char ** temp = NULL;
2467     char * string = NULL;
2468     int i;
2469 
2470     if(arg == NULL){
2471        return NULL;
2472     }
2473 
2474     /* split the string into lines */
2475     temp = g_strsplit (arg, "\n", 0);
2476 
2477     for(i=0; temp[i] != NULL; i++){
2478       /* if the line begins with "delete:", then do not copy it */
2479       if(strstr(temp[i], "delete:") != temp[i]){
2480         if(string == NULL){
2481           string = strdup(temp[i]);
2482         }else{
2483           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
2484           string = strcat(string, "\n");
2485           string = strcat(string, temp[i]);
2486         }
2487       }
2488     }
2489     g_strfreev(temp);
2490     return string;
2491 }
2492 
2493 
2494 
2495 
2496 
2497 /* looks if two objects are identical or not.
2498     Takes two objects as char *, and returns 1 if
2499     they are identical, returns 0 if not.
2500 
2501     Algorithm is very simple: All strings of tabs and 
2502     white spaces are collapsed into a single white space,
2503     and then the strings are compared (strcmp) */
2504 int identical(const char * old_version, const char * new_version){
     /* [<][>][^][v][top][bottom][index][help] */
2505   char * arg1 = strdup(old_version);
2506   char * arg2 = strdup(new_version);
2507   int result = 0;
2508   char *temp1, *temp2; 
2509 
2510 
2511   arg1 = g_strstrip(arg1);
2512   arg2 = g_strstrip(arg2);
2513 
2514   /* delete the 'delete:' attrib */
2515   arg2 = delete_delete_attrib(arg2);
2516   /* convert tabs to white spaces */
2517   arg1 = g_strdelimit(arg1, "\t", ' ');
2518   arg2 = g_strdelimit(arg2, "\t", ' ');
2519   
2520   temp1 = (char *)malloc(strlen(arg1) + 1); 
2521   temp2 = (char *)malloc(strlen(arg2) + 1);
2522   up_string_pack(temp1, arg1);
2523   up_string_pack(temp2, arg2);
2524 
2525   /* if there is still \r's at the end of strings, remove them */
2526   if((temp1[strlen(temp1) - 1]) == '\r'){
2527     temp1[strlen(temp1) - 1] = '\0';
2528   }
2529   if((temp2[strlen(temp2) - 1]) == '\r'){
2530     temp2[strlen(temp2) - 1] = '\0';
2531   }
2532 
2533   result = strcmp(temp1, temp2);
2534   if(tracing){
2535     printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2536     printf("TRACING: identical: the lengths are:\n[%i]\n[%i]\n", strlen(temp1), strlen(temp2));
2537   }
2538   free(arg1);
2539   free(arg2);
2540   free(temp1);
2541   free(temp2);
2542   if(result  == 0){
2543     if(tracing) {
2544       printf("TRACING: identical returning 1\n");
2545     }
2546     return 1;
2547   }else{
2548     if(tracing) {
2549       printf("TRACING: identical returning 0\n");
2550     }
2551     return 0;
2552   }
2553 }
2554 
2555 
2556 
2557 
2558 
2559 
2560 /* constructs an initials string from a given name (for NIC hdl generation) */
2561 char * find_initials(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2562 
2563    char * temp, * temp2;
2564    char * initials = NULL;
2565    int len, i;
2566    char ** vector;
2567 
2568    temp = strdup(arg);
2569    g_strstrip(temp);
2570    temp2 = (char *)malloc(strlen(temp) + 1);
2571    up_string_pack(temp2, temp);
2572    vector = g_strsplit(temp2, " ", 0);
2573    for(i = 0; vector[i] != NULL && i < 4; i++){
2574      if(strlen(vector[i]) > 0){
2575        if(initials == NULL){
2576          initials = (char *)malloc(2);
2577          initials[0] = vector[i][0]; initials[1] = '\0';
2578        }else{
2579          len = strlen(initials);
2580          initials = (char *)realloc(initials, len + 2 );
2581          initials[len] = vector[i][0];
2582          initials[len + 1] = '\0';
2583        }
2584      }
2585    }
2586    free(temp);free(temp2);g_strfreev(vector);
2587    return initials;
2588 }
2589 
2590 
2591 
2592 
2593 
2594 /*  Gets the letter combination to be used in the automatically
2595     generated NIc handle. It the letter combination is specified
2596     in the AUTO NIC handle, return that. If not, return NULL
2597     (in which case the initials of the name must be used) */
2598 char * get_combination_from_autonic(const char * autonic){
     /* [<][>][^][v][top][bottom][index][help] */
2599 
2600   GString * temp;
2601   char * str = NULL;
2602 
2603   temp = g_string_new(autonic);
2604   temp = g_string_up(temp);
2605   temp = g_string_erase(temp, 0, strlen("AUTO-"));
2606   /* delete all digits from the beginning of the string */
2607   while(temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9')){
2608     temp = g_string_erase(temp, 0, 1);
2609   }
2610   if(temp->len == 0){
2611     g_string_free(temp, TRUE);
2612     return NULL;
2613   }else{
2614     str = temp->str;
2615     g_string_free(temp, FALSE);
2616     return str;
2617   }
2618 
2619 }
2620 
2621 
2622 
2623 
2624 
2625 
2626 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2627    and  modifies the nic-hdl: attribute, returns the new object.
2628    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2629    auto_nic is set to "AUTO-1"
2630    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2631 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
     /* [<][>][^][v][top][bottom][index][help] */
2632 
2633   GString* temp_string; 
2634   char * to_be_returned = NULL;
2635   char * person_role_name= NULL;
2636   char * initials = NULL;
2637   char ** temp = NULL;
2638   int i, pos;
2639   Object * o = new Object;
2640 
2641   temp = g_strsplit(arg, "\n", 0);
2642 
2643   for(i = 0; temp[i] != NULL; i++){
2644     if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2645       temp_string = g_string_new(temp[i]);
2646       temp_string = g_string_down(temp_string);
2647       if(strstr(temp_string->str, "auto-") != NULL){
2648         auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "auto-"), 
2649             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2650         auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")] = '\0';
2651         g_strstrip(auto_nic_hdl);
2652         if(tracing){
2653           printf("TRACING: auto_nic is [%s]\n", auto_nic_hdl);
2654         }
2655         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2656         temp_string = g_string_erase(temp_string,
2657             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2658         /* as the suffix to the AUTO nic handle we use the first updatable
2659            source. Since currently we don't support multiple sources,
2660            this is not a problem but when we support it, we must change this */ 
2661         temp_string = g_string_insert(temp_string, pos, sources[0]);
2662         temp_string = g_string_insert(temp_string, pos, "*-");
2663         o->scan(arg, strlen(arg));
2664         person_role_name = get_attribute(o, get_class_type(o), arg);
2665         delete(o);
2666         /* if the letter combination is already specified, get it */
2667         initials = get_combination_from_autonic(auto_nic_hdl);
2668         /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
2669         if(initials == NULL){
2670           initials = find_initials(person_role_name);
2671         }
2672         free(person_role_name);
2673         temp_string = g_string_insert(temp_string, pos, initials);
2674         free(initials);
2675         
2676         if(to_be_returned == NULL){
2677           to_be_returned = strdup(temp_string->str);
2678           g_string_free(temp_string, TRUE);
2679         }else{
2680           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2681           to_be_returned = strcat(to_be_returned, "\n");
2682           to_be_returned = strcat(to_be_returned, temp_string->str);
2683           g_string_free(temp_string, TRUE);
2684         }
2685       }else{
2686         if(to_be_returned == NULL){
2687           to_be_returned = strdup(temp[i]);
2688         }else{
2689           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2690           to_be_returned = strcat(to_be_returned, "\n");
2691           to_be_returned = strcat(to_be_returned, temp[i]);
2692         }
2693       }
2694     }else{/* if it doesn't begin with nic-hdl */
2695         if(to_be_returned == NULL){
2696           to_be_returned = strdup(temp[i]);
2697         }else{
2698           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2699           strcat(to_be_returned, "\n");
2700           strcat(to_be_returned, temp[i]);
2701         }
2702 
2703     }
2704 
2705   }
2706   g_strfreev (temp);
2707   return to_be_returned;
2708 }
2709 
2710 
2711 
2712 /* replaces the refs to AUTO NIC hdls with the assigned one */
2713 
2714 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
     /* [<][>][^][v][top][bottom][index][help] */
2715 
2716   char * auto_nic = NULL;
2717   GString* temp_string; 
2718   char * to_be_returned = NULL;
2719   char ** temp = NULL;
2720   int i, pos;
2721 
2722 
2723   temp = g_strsplit(arg, "\n", 0);
2724 
2725   for(i = 0; temp[i] != NULL; i++){
2726     if(   strstr(temp[i], "admin-c:") == temp[i]    /*    if it starts with admin-c */
2727        || strstr(temp[i], "tech-c:" ) == temp[i]    /* or if it starts with tech-c */
2728        || strstr(temp[i], "zone-c:" ) == temp[i]    /* or if it starts with zone-c */
2729        || strstr(temp[i], "author:" ) == temp[i]){  /* or if it starts with author */
2730       temp_string = g_string_new(temp[i]);
2731       temp_string = g_string_down(temp_string);
2732       if(strstr(temp_string->str, "auto-") != NULL){
2733         auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")  + 1);
2734         auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"), 
2735             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2736         auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0'; 
2737         g_strstrip(auto_nic);
2738         if(tracing){
2739           printf("TRACING: auto_nic is [%s]\n", auto_nic);
2740         }
2741         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2742         temp_string = g_string_erase(temp_string,
2743             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
2744         
2745         /* if we have this AUTO NIC hdl in the hash, put it. */
2746         if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
2747           temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
2748         }else{/* else, return 0 immediately */
2749           g_strfreev (temp);
2750           return NULL;
2751         }
2752         
2753         if(to_be_returned == NULL){
2754           to_be_returned = strdup(temp_string->str);
2755           g_string_free(temp_string, TRUE);
2756         }else{
2757           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2758           to_be_returned = strcat(to_be_returned, "\n");
2759           to_be_returned = strcat(to_be_returned, temp_string->str);
2760           g_string_free(temp_string, TRUE);
2761         }
2762       }else{
2763         if(to_be_returned == NULL){
2764           to_be_returned = strdup(temp[i]);
2765         }else{
2766           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2767           to_be_returned = strcat(to_be_returned, "\n");
2768           to_be_returned = strcat(to_be_returned, temp[i]);
2769         }
2770       }
2771     }else{/* if it doesn't begin with ac,tc,ac or author */
2772         if(to_be_returned == NULL){
2773           to_be_returned = strdup(temp[i]);
2774         }else{
2775           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2776           strcat(to_be_returned, "\n");
2777           strcat(to_be_returned, temp[i]);
2778         }
2779 
2780     }
2781 
2782   }
2783   g_strfreev (temp);
2784   if(tracing){
2785     printf("TRACING: replace_first_ref_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
2786   }
2787   return to_be_returned;
2788 }
2789 
2790 
2791 
2792 
2793 
2794 
2795 
2796 
2797 /* Takes an object in a char * , and returns 1 if this object has 
2798    an AUTO NIC handle. Otherwise, returns 0 */
2799 int has_AUTO_NIC_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
2800 
2801   Object * o = new Object();
2802   GSList * attributes = NULL;
2803   bool code;
2804 
2805   code = o->scan(object, strlen(object));
2806 
2807   if(code && !(o->isDeleted)){
2808     attributes = get_attributes(o, "nic-hdl", object);
2809     if(attributes != NULL){
2810       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2811         g_slist_free(attributes);
2812         delete(o);
2813         return 1;
2814       }
2815     }
2816     /* if control reaches here, then we will return 0 */
2817     g_slist_free(attributes);
2818     delete(o);
2819     return 0; 
2820   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
2821            it contains refs to AUTO NIC hdls. */
2822     delete(o); 
2823     return 0;        
2824   }
2825     
2826 }
2827 
2828 
2829 /* Takes an object in a char * , and returns 1 if this object contains
2830    a reference to an AUTO NIC handle. Otherwise, returns 0 */
2831 int has_ref_to_AUTO_nic_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
2832 
2833   Object * o = new Object();
2834   GSList * attributes = NULL;
2835   bool code;
2836 
2837   code = o->scan(object, strlen(object));
2838 
2839   if(code && !(o->isDeleted)){
2840     attributes = get_attributes(o, "admin-c", object);
2841     if(attributes != NULL){
2842       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2843         g_slist_free(attributes);
2844         delete(o);
2845         return 1;
2846       }
2847     }
2848     g_slist_free(attributes);
2849     attributes = get_attributes(o, "tech-c", object);
2850     if(attributes != NULL){
2851       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2852         g_slist_free(attributes);
2853         delete(o);
2854         return 1;
2855       }
2856     }
2857 
2858     g_slist_free(attributes);
2859     attributes = get_attributes(o, "zone-c", object);
2860     if(attributes != NULL){
2861       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2862         g_slist_free(attributes);
2863         delete(o);
2864         return 1;
2865       }
2866     }
2867     g_slist_free(attributes);
2868     attributes = get_attributes(o, "author", object);
2869     if(attributes != NULL){
2870       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2871         g_slist_free(attributes);
2872         delete(o);
2873         return 1;
2874       }
2875     }
2876     /* if control reaches here, then we will return 0 */
2877     delete(o);
2878     return 0; 
2879   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
2880            it contains refs to AUTO NIC hdls. */
2881     delete(o); 
2882     return 0;        
2883   }
2884     
2885 }
2886 
2887 
2888 
2889 
2890 
2891 
2892 
2893 
2894 
2895 /* Gets the "From" line of the incoming mail message and finds out an 
2896    address to send the acknowledgement */
2897 char * find_email_address(const char * from_line){
     /* [<][>][^][v][top][bottom][index][help] */
2898   char * pos1 = NULL, * pos2 = NULL;
2899   char * temp = NULL;
2900   
2901   if(from_line == NULL){
2902     return NULL;
2903   }
2904   if(strstr(from_line, "From:") != from_line){
2905     temp = strdup(from_line);
2906   }else{
2907     temp = strdup(from_line + strlen("From:"));
2908   }
2909   g_strstrip(temp);
2910   if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
2911     pos1 = index(temp, '<');
2912     pos2 = index(temp, '>');
2913     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
2914     temp[pos2 - pos1 - 1] = '\0';
2915     if(tracing) {
2916      printf("TRACING: find_email_address temp=[%s]\n", temp);
2917     }
2918 
2919     return temp;
2920   }else{/* the line contains only the address, then */
2921    return temp; 
2922   }
2923 }  
2924 
2925 
2926 
2927 /* replaces the erase_str occurences with insert_str in g_str */
2928 GString * replace_strings(GString * g_str, const char * erase_str, const char * insert_str){
     /* [<][>][^][v][top][bottom][index][help] */
2929 
2930   int pos;
2931   
2932   if(insert_str == NULL){/* then don't do anything */
2933     return g_str;
2934   }
2935    
2936   /* replace erase_str with insert_str */
2937   while(strstr(g_str->str, erase_str) != NULL){
2938     pos = strstr(g_str->str, erase_str) - g_str->str;
2939     g_str = g_string_erase(g_str, pos, strlen(erase_str));
2940     if(insert_str != NULL){
2941       g_str = g_string_insert(g_str, pos, insert_str);
2942     }
2943   }
2944   return g_str;
2945   
2946 }
2947 
2948 
2949 /* Duplicates the given arg, and replaces 
2950     $FROM,
2951     $SUBJECT,
2952     $MDATE,
2953     $MSGID,
2954     $CC,
2955     $HUMAILBOX
2956     $AUTOBOX
2957 
2958     and $TIME & $DATE
2959     
2960     strings with the corresponding variables.
2961     
2962 */
2963 char * replace_globals(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2964 
2965   GString * g_str;
2966   int pos; 
2967   char * to_be_returned;
2968   time_t cur_time;
2969   char * temp, * time_str, * date_str;
2970 
2971 
2972   /* get time */
2973   cur_time = time(NULL);
2974   temp = strdup(ctime(&cur_time));
2975   /* temp is now something like "Fri Sep 13 00:00:00 1986\n\0", fields are const width */ 
2976   
2977   time_str = (char *)malloc(9);  
2978   time_str = strncpy(time_str, temp + 11, 8);
2979   time_str[8] = '\0';  
2980             
2981   date_str = (char *)malloc(16);
2982   date_str = strncpy(date_str, temp, 11);
2983   date_str[11] = '\0';
2984   date_str = strncat(date_str, temp + 20, 4);
2985   
2986    
2987   free(temp);
2988                                          
2989   g_str = g_string_new(arg);
2990 
2991   g_str = replace_strings(g_str, "$TIME", time_str);
2992 
2993   g_str = replace_strings(g_str, "$DATE", date_str);
2994 
2995   g_str = replace_strings(g_str, "$SUBJECT", update_mail_subject);
2996 
2997   g_str = replace_strings(g_str, "$FROM", update_mail_sender);
2998 
2999   g_str = replace_strings(g_str, "$MDATE", update_mail_date); 
3000 
3001   g_str = replace_strings(g_str, "$MSGID", update_mail_ID);
3002 
3003   g_str = replace_strings(g_str, "$CC", update_mail_cc);
3004 
3005   g_str = replace_strings(g_str, "$HUMAILBOX", humailbox);
3006 
3007   g_str = replace_strings(g_str, "$AUTOBOX", autobox);
3008 
3009   free(time_str);
3010   free(date_str);
3011 
3012   to_be_returned = strdup(g_str->str); 
3013   g_string_free(g_str, 1); 
3014   return to_be_returned;
3015 }
3016 
3017 /* Get the type of the object, which is represented as a char * */
3018 char * get_class_type_char(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
3019   bool code;
3020   Object * o;
3021   char * type; 
3022   char * temp; 
3023 
3024   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
3025    (no harm in having more than one) */
3026   temp = (char *)malloc(strlen(object) + 2);
3027   sprintf(temp, "%s\n", object);
3028 
3029   if(tracing) {
3030     printf("TRACING: get_class_type_char is running, object is \n[%s]\n", object);
3031   }
3032   o = new Object;
3033   code = o->scan(temp,strlen(temp));
3034   
3035   type = get_class_type(o);
3036 
3037   free(temp);
3038   delete(o);
3039   return type; 
3040 
3041 }

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