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. UP_replace_strings
  47. UP_replace_GStrings
  48. identical
  49. find_initials
  50. get_combination_from_autonic
  51. replace_AUTO_NIC_hdl
  52. replace_refs_to_AUTO_NIC_hdl
  53. has_AUTO_NIC_hdl
  54. has_ref_to_AUTO_nic_hdl
  55. find_email_address
  56. UP_remove_EOLs
  57. UP_replace_globals
  58. get_class_type_char

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

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