modules/up/UP_util.cc

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

FUNCTIONS

This source file includes following functions.
  1. authorise
  2. interpret_ripdb_result
  3. get_assigned_nic
  4. delete_override
  5. up_get_transaction_id
  6. send_object_db
  7. get_class_type
  8. get_search_key
  9. send_and_get
  10. count_objects
  11. strip_lines
  12. take_objects
  13. take_object
  14. get_as_block
  15. get_aut_num_object
  16. get_less_specific_domain
  17. get_less_specific_set
  18. get_less_specific
  19. get_less_spec_inetnum
  20. get_exact_match_inetnum
  21. get_exact_match_routes
  22. get_less_spec_routes
  23. get_mntners
  24. get_attributes
  25. get_attribute
  26. strstr_in_list
  27. get_auths
  28. get_attr_list
  29. get_mnt_lowers
  30. get_mnt_routes
  31. get_mnt_routes_from_list
  32. get_mnt_lowers_from_list
  33. get_override
  34. check_override
  35. add_to_auth_vector
  36. get_auth_vector
  37. get_mntnfy_vector
  38. get_updto_vector
  39. up_filter_out_diff_origins
  40. up_filter_out_diff_nichdls
  41. UP_filter_out_same_origins
  42. check_auth
  43. get_old_version
  44. process_mail_header
  45. up_string_pack
  46. delete_delete_attrib
  47. UP_replace_strings
  48. UP_replace_GStrings
  49. identical
  50. find_initials
  51. get_combination_from_autonic
  52. replace_AUTO_NIC_hdl
  53. replace_refs_to_AUTO_NIC_hdl
  54. UP_put_assigned_NIC
  55. has_AUTO_NIC_hdl
  56. has_ref_to_AUTO_nic_hdl
  57. find_email_address
  58. UP_remove_EOLs
  59. UP_replace_globals
  60. get_class_type_char
  61. UP_add_to_upd_log
  62. UP_log_networkupdate
  63. UP_is_object

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

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