modules/up/UP_util.c

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

DEFINITIONS

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

   1 /***************************************
   2   $Revision: 1.27 $
   3 
   4   UP module utilities
   5 
   6   Status: REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (17/01/2000) Created.
  13                 denis (31/08/2001) Modified for new API
  14   ******************/ /******************
  15   Copyright (c) 2000,2001,2002                    RIPE NCC
  16  
  17   All Rights Reserved
  18   
  19   Permission to use, copy, modify, and distribute this software and its
  20   documentation for any purpose and without fee is hereby granted,
  21   provided that the above copyright notice appear in all copies and that
  22   both that copyright notice and this permission notice appear in
  23   supporting documentation, and that the name of the author not be
  24   used in advertising or publicity pertaining to distribution of the
  25   software without specific, written prior permission.
  26   
  27   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  28   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  29   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  30   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  31   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  32   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33  ***************************************/
  34 
  35 #include <time.h>
  36 #include "dbupdate.h"
  37 #include "UP_extrnl_syntax.h"
  38 #include "ud.h"
  39 #include "notification.h"
  40 
  41 extern int tracing;
  42 extern char * overridecryptedpw;
  43 extern int test_mode;
  44 extern char * updlog;
  45 extern char * update_host;
  46 extern int update_port;
  47 extern char * query_host;
  48 extern int query_port;
  49 extern char * humailbox;
  50 extern char * autobox;
  51 extern char * netupdclientIP;
  52 
  53 extern int reading_from_mail;
  54 extern int networkupdate;
  55 extern int webupdate; 
  56 extern char *netupdclientIP;
  57 
  58 extern char *update_mail_sender;
  59 extern char *update_mail_subject;
  60 extern char *update_mail_date;
  61 extern char *update_mail_ID;
  62 extern char *update_mail_cc;
  63 
  64 extern char *header_type;
  65 extern char *text_type;
  66 
  67 extern char *current_source;
  68 extern char *DBhost;
  69 extern int  DBport;
  70 extern char *DBuser;
  71 extern char *DBname;
  72 extern char *DBpasswd;
  73 
  74 extern char * allocmnt;
  75 
  76 
  77 /* authorise function takes the auth_vector, credentials struct, and 'overriden'
  78    variable. If overriden == 1, then it immediately returns UP_AUTH_OK 
  79    (because this means that the update contained a valid override attribute).
  80    Else, it goes through the auth_vector and when it finds a an "auth:"
  81    attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
  82    UP_AUF (authorisation failed) */
  83    
  84 int authorise(GSList * auth_vector, credentials_struct credentials, int overriden)
     /* [<][>][^][v][top][bottom][index][help] */
  85 {
  86   int result = 0;
  87 
  88   if (tracing)
  89   {
  90     printf("TRACING: authorise started with override: %i\n", overriden);
  91   }
  92     
  93   /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
  94   if (overriden == 1)
  95   {
  96     return UP_AUTH_OK;
  97   }
  98   else
  99   {
 100     result = AU_authorise(auth_vector, credentials);
 101     if (tracing)
 102         {
 103       printf("TRACING: authorise: AU_authorise returned %i\n", result);
 104     }
 105     
 106     if (result > 0)
 107         {
 108       return UP_AUTH_OK;
 109     }
 110     else
 111         {
 112       return UP_AUF; /* authorisation failed */
 113     }
 114   }
 115 }
 116 
 117 
 118 
 119 /* interprets the result string coming from RIPupd
 120    It is called by send_object_db.
 121    It returns the error no returned from RIPupd.  */
 122    
 123 int interpret_ripdb_result(const char * string)
     /* [<][>][^][v][top][bottom][index][help] */
 124 {
 125    char * error_no = NULL;
 126    char ** temp = NULL, ** temp2 = NULL;
 127    int i;
 128    int err = 0;
 129      
 130   /* if the string is NULL or empty, then return error */
 131   if (string == NULL || strlen(string) == 0)
 132   {
 133     return 0; 
 134   }
 135 
 136   /* split the string into lines */
 137   temp = g_strsplit(string , "\n", 0);
 138   for (i = 0; temp[i] != NULL; i++)
 139   {
 140     if (i == 0)
 141         { /* this line must contain "%ERROR " string in the beginning */
 142       temp2 = g_strsplit(temp[0], " ", 0);
 143       error_no = strdup(temp2[1]);
 144       g_strfreev(temp2);
 145       err = atoi(error_no);
 146       if (tracing)
 147           {
 148         printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
 149       }
 150     }
 151         else if (error_no != NULL && strcmp(error_no, "0") != 0)
 152         {
 153     }
 154   }
 155   g_strfreev(temp);
 156   if (error_no != NULL)
 157   {
 158     free(error_no);
 159   }
 160   return err; /* 0 means no error in this context */
 161 }
 162 
 163 
 164 
 165 /* Gets assigned NIC hdl from the string that is returned from 
 166    RIPupdate */
 167 void get_assigned_nic(char * nic_hdl, const char * string)
     /* [<][>][^][v][top][bottom][index][help] */
 168 {
 169    char * error_no = NULL;
 170    char ** temp = NULL, ** temp2 = NULL;
 171    int i;
 172      
 173   if (tracing)
 174   {                                
 175       printf("TRACING: get_assigned_nic is running\n");
 176   }
 177 
 178   /* if the string is NULL or empty, then return error */
 179   if (string == NULL || strlen(string) == 0)
 180   {
 181     return; 
 182   }
 183 
 184   /* split the string into lines */
 185   temp = g_strsplit(string , "\n", 0);
 186   for (i = 0; temp[i] != NULL; i++)
 187   {
 188     if (i == 0)
 189         { /* this line must contain "%ERROR " string in the beginning */
 190       temp2 = g_strsplit(temp[0], " ", 0);
 191       error_no = strdup(temp2[1]);
 192       g_strfreev(temp2);
 193       if (tracing)
 194           {
 195         printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
 196       }
 197     }
 198         else if (error_no != NULL && strcmp(error_no, "0") != 0)
 199         {
 200     }
 201         else if (error_no != NULL && strcmp(error_no, "0") == 0 && i == 1)
 202         { /* look for assigned NIC hdl */
 203       /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
 204          need to extract EK3-RIPE part */
 205       nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,  
 206                                  rindex(temp[i],']') - rindex(temp[i],'[') - 1);
 207       nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
 208       if (tracing && nic_hdl != NULL)
 209           {
 210         printf("TRACING: get_assigned_nic will return [%s]\n", nic_hdl);
 211       }
 212       g_strfreev(temp);
 213       return;
 214     }
 215   }
 216   g_strfreev(temp);
 217   return;
 218 }
 219 
 220 
 221 
 222 /* Obtains a transaction ID for an object. Will be called from send_object_db */
 223 int up_get_transaction_id()
     /* [<][>][^][v][top][bottom][index][help] */
 224 {
 225   SQ_connection_t * sql_connection;
 226   SQ_result_set_t *result;
 227   int error;
 228   long new_id;
 229 
 230   sql_connection = SQ_get_connection(DBhost, DBport, DBname, DBuser, DBpasswd); 
 231   if (!sql_connection)
 232   {
 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   {
 239     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
 240     exit(1);
 241   }
 242 
 243   new_id = mysql_insert_id(sql_connection);
 244 
 245   SQ_close_connection(sql_connection);  
 246 
 247   return new_id;
 248 }
 249 
 250 
 251 
 252 /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
 253    assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl 
 254    assigned_NIC must be allocated enough memory before send_object_db is called 
 255    
 256    If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
 257    */
 258 up_ripupd_result_struct * send_object_db(rpsl_object_t *object, char * assigned_NIC, char * operation)
     /* [<][>][^][v][top][bottom][index][help] */
 259 {
 260   int sockfd, numbytes;  
 261   char buf[MAXDATASIZE + 1];
 262   struct hostent *he;
 263   struct sockaddr_in their_addr; /* connector's address information */
 264   char *result_string = NULL;
 265   int err = 0;
 266   char *to_be_sent = NULL;
 267   int tr_id;
 268   char * tr_id_str;
 269   char * tempstr;
 270   rpsl_object_t *sent_object;
 271   rpsl_attr_t *removed_attr;
 272   rpsl_error_t return_error;
 273 
 274   up_ripupd_result_struct * return_struct;
 275 
 276   if (tracing)
 277   { 
 278     printf("TRACING: send_object_db is running: assigned_NIC : [%s]; operation: [%s]\n", assigned_NIC ? assigned_NIC : "", operation);
 279   }
 280   return_struct = (up_ripupd_result_struct *)malloc(sizeof(up_ripupd_result_struct));
 281   return_struct->error_str = NULL;
 282   
 283   /* copy the object, remove the override password and create a text string */
 284   sent_object = rpsl_object_copy(object);
 285   removed_attr = rpsl_object_remove_attr_name(sent_object,"override",&return_error);
 286   to_be_sent = rpsl_object_get_text(sent_object,0);
 287   rpsl_object_delete(sent_object);
 288 
 289   if (tracing)
 290   { 
 291     printf("TRACING: send_object_db: to_be_sent : [\n%s]\n", to_be_sent);
 292   }
 293 
 294   /* get the transaction ID, to be sent to RIPupdate*/
 295   tr_id = up_get_transaction_id();
 296 
 297   /* convert it into a string */
 298   tr_id_str = (char *)malloc(64);
 299   sprintf(tr_id_str, "%d", tr_id);
 300 
 301   if (tracing)
 302   { 
 303     printf("TRACING: send_object_db: tr_id_str : [%s]\n", tr_id_str);
 304   }
 305 
 306   if ((he=gethostbyname(update_host)) == NULL)
 307   {  /* get the host info */
 308       perror("gethostbyname");
 309       exit(1);
 310   }
 311 
 312   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
 313   {
 314       perror("socket");
 315       exit(1);
 316   }
 317 
 318   their_addr.sin_family = AF_INET;      /* host byte order */
 319   their_addr.sin_port = htons(update_port);    /* short, network byte order */
 320   their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 321   bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 322 
 323 
 324   if (connect(sockfd, (struct sockaddr *)&their_addr, 
 325                                                                         sizeof(struct sockaddr)) == -1)
 326   {
 327       perror("connect");
 328       exit(1);
 329   }
 330 
 331   if (send(sockfd, operation , strlen(operation), 0) == -1)
 332       perror("send");
 333   if (send(sockfd, " ", strlen(" "), 0) == -1)
 334       perror("send");    
 335   if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
 336       perror("send");    
 337   if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
 338       perror("send");
 339   if (send(sockfd, to_be_sent, strlen(to_be_sent), 0) == -1)
 340       perror("send");
 341   if (send(sockfd, "\n\n", 2, 0)  == -1)
 342       perror("send");
 343   /* send the ACK now */
 344   if (send(sockfd, "ACK ",strlen("ACK "), 0)  == -1)
 345       perror("send");
 346   if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
 347       perror("send");    
 348   if (send(sockfd, "\n\n",strlen("\n\n"), 0)  == -1)
 349       perror("send");
 350 
 351   if (tracing)
 352   { 
 353     printf("TRACING: send_object_db: send complete\n");
 354   }
 355       
 356 
 357   while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0)
 358   {
 359       buf[numbytes] = '\0';
 360       if (tracing)
 361       {
 362         printf("received from socket [\n%s]\n",buf);
 363       }
 364       if (result_string == NULL)
 365       {
 366         result_string = strdup(buf);
 367       }
 368       else
 369       {
 370         result_string = (char *)realloc(result_string, 
 371                                            strlen(result_string) + strlen(buf) + 1);
 372         result_string = strcat(result_string, buf);
 373       }
 374       if (strstr(result_string,"\n\n") != NULL)
 375       { /* if the result_string contains
 376          an empty line at the end, we will close */
 377         break;
 378       };
 379   }
 380 
 381   free(tr_id_str);
 382   err = interpret_ripdb_result(result_string);
 383 
 384   if (tracing)
 385   { 
 386     printf("TRACING: send_object_db: interpret_ripdb_result returned : [%i]\n", err);
 387   }
 388 
 389   if (assigned_NIC != NULL)
 390   { /* if the caller of the function expected to get a NIC handle */
 391     get_assigned_nic(assigned_NIC, result_string);
 392   }
 393   close(sockfd);
 394   free(to_be_sent);
 395   return_struct->result = err;
 396   
 397   /*return_struct->error_str = strdup(result_string); */
 398   /* According to the error no got from RIPupdate, construct an error string  */
 399   switch (return_struct->result)
 400   {
 401     case 0: break; 
 402     case ERROR_U_MEM: 
 403     case ERROR_U_DBS:
 404     case ERROR_U_BADOP:
 405     case ERROR_U_COP:
 406     case ERROR_U_NSUP:
 407     case ERROR_U_BUG:
 408       tempstr = (char *)malloc(1024);
 409       snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
 410           return_struct->result);
 411       return_struct->error_str = tempstr;
 412       break; 
 413     case ERROR_U_OBJ:
 414       if (tracing)
 415       {
 416          printf("\nresult_string [%s]\n\n", result_string);
 417       }
 418       tempstr = (char *)malloc(1024);
 419       /* if the object contains refs to unknown objects */
 420       if (strstr(result_string, "dummy") != NULL || 
 421             strstr(result_string, "reference cannot be resolved") != NULL )
 422       {
 423         /* if the response from RIPupd contains "dummy not allowed" string 
 424            or a reference that cannot be resolved */
 425         snprintf(tempstr, 1024, "***Error: Unknown object referenced");
 426       }
 427           else if (strstr(result_string, "key-cert") != NULL)
 428           {
 429       /* if the response from RIPupd contains "no key-cert object" string */
 430       snprintf(tempstr, 1024, "***Error: Unknown key-cert object referenced"); 
 431       }
 432       else
 433       {
 434       /* then, the object is referenced from other objects */
 435         snprintf(tempstr, 1024, "***Error: Object is referenced from other objects");
 436       }
 437       return_struct->error_str = tempstr;
 438       break; 
 439     case ERROR_U_AUT:
 440       tempstr = (char *)malloc(1024);
 441       snprintf(tempstr, 1024, "***Error: Membership authorisation failure");
 442       return_struct->error_str = tempstr;
 443       break; 
 444     default: 
 445       tempstr = (char *)malloc(1024);
 446       snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
 447           return_struct->result);
 448       return_struct->error_str = tempstr;
 449       break; 
 450   }
 451   return return_struct; 
 452 }
 453 
 454 
 455 
 456 /* takes an object (pre-parsed) and returns its first attrib if it is not
 457    a person/role, and returns the nic-hdl if it is a person/role object */
 458 char * get_search_key(rpsl_object_t *object, const char * type)
     /* [<][>][^][v][top][bottom][index][help] */
 459 {
 460     char *primary_key = NULL;
 461         char *lctype;
 462         GList *attr_list;
 463 
 464     if(object == NULL) return NULL;
 465         
 466         lctype = strdup(type);
 467         g_strdown(lctype);
 468         if ( strcmp(lctype, "person") == 0 || strcmp(lctype, "role") == 0 )
 469         {
 470                 /* this is a person or role object */
 471                 /* get the nic-hdl attribute */
 472                 attr_list = rpsl_object_get_attr(object, "nic-hdl");
 473         }
 474         else
 475         {
 476                 /* this is NOT a person or role object */
 477                 /* get the class attribute */
 478                 attr_list = rpsl_object_get_attr(object, type);
 479         }
 480 
 481         if ( attr_list )
 482         {
 483                 primary_key = rpsl_attr_get_clean_value((rpsl_attr_t *)(attr_list->data));
 484         }
 485         free(lctype);
 486         return primary_key ;
 487 }
 488 
 489 
 490 
 491 /* sends char * arg to the specified host's specified port, and
 492    returns the reply as a string. This is used to query the
 493    whois host. Probably we must use WC (whois client) module here,
 494    but it must be extented */
 495 char * send_and_get(char * host, int port, char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 496 {
 497         int sockfd, numbytes; 
 498         char * result = NULL; 
 499         char buf[MAXDATASIZE + 1];
 500         struct hostent *he;
 501         struct sockaddr_in their_addr; /* connector's address information */
 502   
 503         if(tracing)
 504                 { 
 505           printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
 506         }
 507 
 508         if ((he=gethostbyname(host)) == NULL)
 509                 {  /* get the host info */
 510             perror("gethostbyname");
 511             exit(1);
 512         }
 513 
 514         if(tracing) 
 515                 { 
 516           printf("TRACING: send_and_get: called gethostbyname\n");
 517         }
 518 
 519         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
 520                 {
 521             perror("socket");
 522             exit(1);
 523         }
 524 
 525         if(tracing)
 526                 { 
 527           printf("TRACING: send_and_get: called socket\n");
 528         }
 529 
 530         their_addr.sin_family = AF_INET;      /* host byte order */
 531         their_addr.sin_port = htons(port);    /* short, network byte order */
 532         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 533         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 534 
 535         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 536                                               sizeof(struct sockaddr)) == -1)
 537         {
 538             perror("connect");
 539             exit(1);
 540         }
 541         if (send(sockfd, arg , strlen(arg), 0) == -1)
 542                perror("send");
 543         if (send(sockfd, "\n",1,0)  == -1)
 544                perror("send");
 545 
 546         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0)
 547                 {
 548             buf[numbytes] = '\0';
 549             if (result == NULL)
 550                         {
 551               result = strdup(buf);
 552             }
 553                         else
 554                         {
 555               result = (char *)realloc(result, strlen(result) + strlen(buf) + 1);
 556               result = strcat(result, buf);
 557             }
 558         }
 559 
 560         close(sockfd);
 561         return result;
 562 }
 563 
 564 
 565 
 566 /* counts the number of objects in a string */
 567 int count_objects(char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 568 {
 569     int count = 0;
 570     char *pos = NULL;
 571     char *temp = NULL;
 572 
 573     if(tracing) 
 574         {
 575       printf("TRACING: count_objects running\n");
 576     }
 577     
 578     if(arg != NULL)
 579         {
 580       temp = strdup(arg);
 581     }
 582         else
 583         {
 584       return 0;
 585     }
 586     
 587     if ( isalpha( (int)(arg[0]) ) )
 588         {
 589       count++;
 590     }
 591         else if (arg[0] == '\n' && isalpha( (int)(arg[1]) ) )
 592         {
 593       count++;
 594     }
 595     while ( (pos = strstr(temp,"\n\n")) )
 596         {
 597       pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
 598       if ( isalpha( (int)(pos[2]) ) )
 599           {
 600         count++;
 601       }
 602     }
 603     if(tracing) 
 604         {
 605       printf("TRACING: count_objects returning %d\n", count);
 606     }
 607     free(temp);
 608     return count;
 609 }
 610 
 611 
 612 
 613 /* strips lines beginning with '%' off  */
 614 char * strip_lines(char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 615 {
 616     char ** temp = NULL;
 617     char * string = NULL;
 618     int i;
 619 
 620     if (arg == NULL)
 621         {
 622        return NULL;
 623     }
 624 
 625     /* split the string into lines */
 626     temp = g_strsplit (arg, "\n", 0);
 627 
 628     for (i=0; temp[i] != NULL; i++)
 629         {
 630       if (temp[i][0] != '%')
 631           {
 632         if (string == NULL)
 633                 {
 634           string = strdup(temp[i]);
 635         }
 636                 else
 637                 {
 638           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
 639           string = strcat(string, "\n");
 640           string = strcat(string, temp[i]);
 641         }
 642       }
 643     }
 644     return string;
 645 }
 646 
 647 
 648 /* Separates the objects in the given char * arg using "\n\n" as
 649    separator. Returns a linked list whose data consist of separated
 650    objects as  char *  */
 651 
 652 GList * take_objects(char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 653 {
 654     char ** objects=NULL;
 655     char ** temp = NULL;
 656     char * temp_object;
 657     GList * tobereturned = NULL;
 658     int i;
 659 
 660     arg = strip_lines(arg);
 661 
 662     objects =  g_strsplit(arg, "\n\n", 1000);
 663     temp = objects;
 664     for (i=0; temp[i] != NULL; i++)
 665         {
 666       /* strip off the trailing and leading white spaces-eols*/
 667       g_strstrip(temp[i]);
 668       if (strlen(temp[i]) > 0)
 669           { /* if not an empty string */
 670         /* here we must add a "\n" at the end of the object, since RAToolSet parser can't
 671           find the last attrib otherwise */
 672         temp_object = (char *)malloc(strlen(temp[i]) + 2);
 673         snprintf(temp_object, strlen(temp[i]) + 2, "%s\n", temp[i]);  
 674         tobereturned = g_list_append(tobereturned, temp_object);
 675       }
 676     }
 677     return tobereturned;
 678 }
 679 
 680 
 681 
 682 /* takes the first object in the given char *, using empty lines as
 683    separator */
 684 char * take_object(char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 685 {
 686     GList * objects;
 687     char * object;
 688 
 689     objects = take_objects(arg);
 690     if (g_list_length(objects) > 0)
 691         {
 692       object = strdup((char *)(g_list_nth_data(objects, 0)));
 693     }
 694         else
 695         {
 696       return NULL;
 697     }
 698     g_list_free(objects);
 699 
 700     return object;
 701 }
 702 
 703 
 704 
 705 /* Takes an autnum_object, and returns the as-block containing this aut-num */
 706 char * get_as_block(rpsl_object_t *autnum_object)
     /* [<][>][^][v][top][bottom][index][help] */
 707 {
 708   char * search_key = NULL, * query_string = NULL;
 709   char * result = NULL;
 710   char *return_value = NULL;
 711   
 712   search_key = get_search_key(autnum_object,"aut-num");
 713   
 714   query_string = (char *)malloc(strlen("-Tas-block -s  -r ")+strlen(current_source)+strlen(search_key)+1);
 715   sprintf(query_string, "-Tas-block -s %s -r %s", current_source,search_key);
 716   result = send_and_get(query_host, query_port, query_string);
 717   free(query_string);
 718 
 719   if (count_objects(result) == 0)
 720   {
 721     if (tracing)
 722         {
 723       printf("No such as-block\n"); 
 724     }
 725         free(result);
 726     return NULL;
 727   }
 728   else if (count_objects(result) > 1)
 729   {
 730     if (tracing)
 731         {
 732       printf("More than one as-block returned\n");
 733     }
 734         free(result);
 735     return NULL;
 736   }
 737   else
 738   { /* count_objects(result) == 1 */
 739     return_value = take_object(result);
 740         free(result);
 741     return return_value;
 742   }
 743 }
 744 
 745 
 746 /* Takes a route_object, and returns the aut-num mentioned in origin
 747    attribute of this route */
 748 char * get_aut_num_object(rpsl_object_t *route_object)
     /* [<][>][^][v][top][bottom][index][help] */
 749 {
 750   char * search_key = NULL, * query_string = NULL;
 751   char * result = NULL;
 752   char *return_value = NULL;
 753   
 754   search_key = get_search_key(route_object,"origin");
 755   
 756   query_string = (char *)malloc(strlen("-Taut-num -s  -r ")+strlen(current_source)+strlen(search_key)+1);
 757   sprintf(query_string, "-Taut-num -s %s -r %s", current_source,search_key);
 758   result = send_and_get(query_host, query_port, query_string);
 759   free(query_string);
 760 
 761   if (count_objects(result) == 0)
 762   {
 763     if (tracing)
 764         {
 765       printf("No such aut-num\n");
 766     }
 767         free(result);
 768     return NULL;
 769   }
 770   else if (count_objects(result) > 1)
 771   {
 772     if (tracing)
 773         {
 774       printf("More than one aut-num returned\n");
 775     }
 776         free(result);
 777     return NULL;
 778   }
 779   else
 780   { /* count_objects(result) == 1 */
 781     return_value = take_object(result);
 782         free(result);
 783     return return_value;
 784   }
 785 }
 786 
 787 
 788 
 789 /* Takes a parsed domain_object, and returns the less specific domain of it */
 790 char * get_less_specific_domain(rpsl_object_t *domain_object)
     /* [<][>][^][v][top][bottom][index][help] */
 791 {
 792   char *query_string = NULL;
 793   char *result = NULL, *domain = NULL;
 794   char *return_value = NULL;
 795   int i,j, length;
 796   char *temp = NULL;
 797   char **splitted;
 798 
 799   domain = get_search_key(domain_object,"domain");
 800 
 801   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
 802   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
 803 
 804   for (i=1; splitted[i] != NULL; i++)
 805   {
 806     /* in the following for loop, we will construct the 'less spec' domains
 807        to be looked up in the DB */ 
 808     for (j=i; splitted[j] !=NULL; j++)
 809         {
 810       if (j==i)
 811           {
 812         temp = (char *)strdup(splitted[j]);
 813       }
 814           else
 815           {
 816         length = strlen(temp); 
 817         temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2); 
 818                 strcat(temp, ".");
 819                 strcat(temp, splitted[j]);
 820       }
 821     }
 822 
 823     query_string = (char *)malloc( strlen("-Tdomain -s  -r -R ")+strlen(current_source)+strlen(temp)+1 );
 824     sprintf(query_string, "-Tdomain -s %s -r -R %s", current_source,temp);
 825     result = send_and_get(query_host, query_port, query_string);
 826     free(query_string);
 827         free(temp);
 828 
 829     if (count_objects(result) == 0)
 830         {
 831           /* do nothing */
 832           free(result);
 833     }
 834         else if (count_objects(result) > 1)
 835         {
 836       if (tracing)
 837           {
 838         printf("TRACING: get_less_specific_domain: More than one domains returned\n");
 839       }
 840           free(result);
 841       return NULL; /* error condition */
 842     }
 843         else
 844         { /* count_objects(result) == 1 */
 845       return_value = take_object(result);
 846           free(result);
 847       return return_value;
 848     }
 849   }
 850   g_strfreev(splitted);
 851 
 852   /* so, we couldn't  find any 'less specific' domain */
 853   return NULL;
 854 }
 855 
 856 
 857 
 858 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
 859    by striping down the object's name ( eg, for as35:rs-trial:rs-myset, 
 860    as35:rs-trial is tried ) */
 861 char * get_less_specific_set(rpsl_object_t *set_object, const char *type)
     /* [<][>][^][v][top][bottom][index][help] */
 862 {
 863   char *search_key = NULL, *query_string = NULL;
 864   char *result = NULL;
 865   char *return_value = NULL;
 866   int i;
 867   
 868   search_key = get_search_key(set_object, type);
 869 
 870   for (i = strlen(search_key) -1; i > -1; i--)
 871   {
 872     if (search_key[i] == ':')
 873         {
 874       search_key[i] = '\0'; /* truncate the string */
 875       break;
 876     }
 877     if (i == 0)
 878         { /* if we've reached the beginning of the string 
 879       (this means there wasn't any ';' in the string) */
 880       free(search_key);
 881       search_key = NULL;
 882     }
 883   }
 884   if ( search_key == NULL || strlen(search_key) == 0)
 885   { /* this mustn't happen in fact, since 
 886     we make sure that the name of the 
 887     set_object contains a ':' in a proper place */
 888     return NULL;
 889   }
 890    
 891   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set,route-set -s  -r ") 
 892            + strlen(current_source) + strlen(search_key) + 1);
 893   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set,route-set -s %s -r %s", current_source,search_key);
 894   result = send_and_get(query_host, query_port, query_string);
 895   free(search_key);
 896   free(query_string);
 897 
 898   if (count_objects(result) == 0)
 899   {
 900     if (tracing)
 901     {
 902       printf("get_less_specific_set: No such object\n");
 903         }
 904         free(result);
 905     return NULL;
 906   }
 907   else if (count_objects(result) > 1)
 908   {
 909     if (tracing)
 910     {
 911       printf("get_less_specific_set: More than one objects returned\n");
 912         }
 913         free(result);
 914     return NULL;
 915   }
 916   else
 917   { /* count_objects(result) == 1 */
 918     return_value = take_object(result);
 919         free(result);
 920     return return_value;
 921   }
 922 }
 923 
 924 
 925 
 926 /* Takes an inetnum or inet6num object and returns one more/less specific of it */
 927 char * get_specific(rpsl_object_t *inetnum_object, const char *type, char *flag)
     /* [<][>][^][v][top][bottom][index][help] */
 928 {
 929   char *search_key = NULL, *query_string = NULL;
 930   char *result = NULL;
 931   char *return_value = NULL;
 932   
 933   search_key = get_search_key(inetnum_object, type);
 934   
 935   query_string = (char *)malloc(strlen("-Tinet6num  -s  -r  ")+strlen(current_source) + strlen(flag) + strlen(search_key) + 1);
 936   sprintf(query_string, "-T%s -s %s -r %s %s",type, current_source, flag, search_key);
 937   result = send_and_get(query_host, query_port, query_string);
 938   free(search_key);
 939   free(query_string);
 940 
 941   if (count_objects(result) == 0)
 942   {
 943     if (tracing)
 944       printf("TRACING: get_specific: No %s %s returned\n", flag, type);
 945         free(result);
 946     return NULL;
 947   }
 948 /*  else if (count_objects(result) > 1)
 949   {
 950     if (tracing)
 951       printf("TRACING: get_specific: More than one %s %s returned\n", flag, type);
 952         free(result);
 953     return NULL;
 954   }   */
 955   else
 956   { /* count_objects(result) >= 1 */
 957     return_value = take_object(result);
 958         free(result);
 959     return return_value;
 960   }
 961 }
 962 
 963 
 964 
 965 /* Takes a parsed route object and returns one less specific inetnum */
 966 char * get_less_spec_inetnum(rpsl_object_t *route_object)
     /* [<][>][^][v][top][bottom][index][help] */
 967 {
 968   char * search_key = NULL, * query_string = NULL;
 969   char * result = NULL;
 970   char * return_value = NULL;
 971   
 972   search_key = get_search_key(route_object, "route");
 973   
 974   query_string = (char *)malloc(strlen("-Tinetnum -s  -r -l ")+strlen(current_source) + strlen(search_key) + 1);
 975   sprintf(query_string, "-Tinetnum -s %s -r -l %s", current_source,search_key);
 976   result = send_and_get(query_host, query_port, query_string);
 977   free(search_key);
 978   free(query_string);
 979 
 980   if (count_objects(result) == 0)
 981   {
 982     if (tracing)
 983         {
 984       printf("get_less_spec_inetnum: No such inetnum\n");
 985         }
 986         free(result);
 987     return NULL;
 988   }
 989   else if (count_objects(result) > 1)
 990   {
 991     if (tracing)
 992         {
 993       printf("get_less_spec_inetnum: More than one inetnums returned\n");
 994         }
 995         free(result);
 996     return NULL;
 997   }
 998   else
 999   { /* count_objects(result) == 1 */
1000     return_value = take_object(result);
1001         free(result);
1002     return return_value;
1003   }
1004 }
1005 
1006 
1007 /* Takes a parsed route object and returns exact match inetnum */
1008 char * get_exact_match_inetnum(rpsl_object_t *route_object)
     /* [<][>][^][v][top][bottom][index][help] */
1009 {
1010   char * search_key = NULL, * query_string = NULL;
1011   char * result = NULL;
1012   char * return_value = NULL;
1013   
1014   search_key = get_search_key(route_object, "route");
1015   
1016   query_string = (char *)malloc(strlen("-Tinetnum -s  -r -x ")+strlen(current_source) + strlen(search_key) + 1);
1017   sprintf(query_string, "-Tinetnum -s %s -r -x %s", current_source,search_key);
1018   result = send_and_get(query_host, query_port, query_string);
1019   free(search_key);
1020   free(query_string);
1021 
1022   if (count_objects(result) == 0)
1023   {
1024     if (tracing)
1025         {
1026       printf("get_exact_match_inetnum: No such inetnum\n");
1027         }
1028         free(result);
1029     return NULL;
1030   }
1031   else if (count_objects(result) > 1)
1032   {
1033     if (tracing)
1034         {
1035       printf("get_exact_match_inetnum: More than one inetnums returned\n");
1036         }
1037         free(result);
1038     return NULL;
1039   }
1040   else
1041   { /* count_objects(result) == 1 */
1042     return_value = take_object(result);
1043         free(result);
1044     return return_value;
1045   }
1046 }
1047 
1048 
1049 
1050 /* Takes a route object and returns exact matches of this route */
1051 GList *get_exact_match_routes(rpsl_object_t *route_object)
     /* [<][>][^][v][top][bottom][index][help] */
1052 {
1053   char *search_key = NULL, *query_string = NULL;
1054   char *result = NULL;
1055   GList * return_value = NULL;
1056   
1057   search_key = get_search_key(route_object, "route");
1058   
1059   query_string = (char *)malloc(strlen("-Troute -s  -r -x ")+strlen(current_source) + strlen(search_key) + 1);
1060   sprintf(query_string, "-Troute -s %s -r -x %s", current_source,search_key);
1061   result = send_and_get(query_host, query_port, query_string);
1062   free(search_key);
1063   free(query_string);
1064 
1065   if (count_objects(result) == 0)
1066   {
1067     if (tracing)
1068         {
1069       printf("get_exact_match_routes: No such route\n");
1070         }
1071         free(result);
1072     return NULL;
1073   }
1074   else
1075   { /* count_objects(result) >= 1 */
1076     return_value = take_objects(result);
1077         free(result);
1078     return return_value;
1079   }
1080 }
1081 
1082 
1083 
1084 /* Takes a route object and returns (immediate) less specifics of this route */
1085 GList *get_less_spec_routes(rpsl_object_t *route_object)
     /* [<][>][^][v][top][bottom][index][help] */
1086 {
1087   char *search_key = NULL, *query_string = NULL;
1088   char *result = NULL;
1089   GList * return_value = NULL;
1090   
1091   search_key = get_search_key(route_object, "route");
1092   
1093   query_string = (char *)malloc(strlen("-Troute -s  -r -l ")+strlen(current_source) + strlen(search_key) + 1);
1094   sprintf(query_string, "-Troute -s %s -r -l %s", current_source,search_key);
1095   result = send_and_get(query_host, query_port, query_string);
1096   free(search_key);
1097   free(query_string);
1098 
1099   if (count_objects(result) == 0)
1100   {
1101     if(tracing)
1102         {
1103       printf("get_less_spec_routes: No such route\n");
1104         }
1105         free(result);
1106     return NULL;
1107   }
1108   else
1109   { /* count_objects(result) >= 1 */
1110     return_value = take_objects(result);
1111         free(result);
1112     return return_value;
1113   }
1114 }
1115 
1116 
1117 
1118 /* Gets an object as a parsed structure and returns its 'mnt-by' attributes as a 
1119    GList (linked list)   */
1120 
1121 GList *get_mntners(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
1122 {
1123   GList *list_of_mntners = NULL;
1124 
1125   if(tracing)
1126   {
1127     printf("TRACING: get_mntners is running\n");
1128   }
1129 
1130   list_of_mntners = rpsl_object_get_attr(object, "mnt-by");
1131 
1132   rpsl_attr_split_multiple(&list_of_mntners);
1133 
1134   return list_of_mntners; 
1135 }
1136 
1137 
1138 
1139 /* Gets an object as a parsed structure and returns its 'mnt-irt' attributes as a 
1140    GList (linked list)   */
1141 
1142 GList *get_irts(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
1143 {
1144   GList *list_of_irts = NULL;
1145 
1146   if(tracing)
1147   {
1148     printf("TRACING: get_irts is running\n");
1149   }
1150 
1151   list_of_irts = rpsl_object_get_attr(object, "mnt-irt");
1152   rpsl_attr_split_multiple(&list_of_irts);
1153 
1154   return list_of_irts; 
1155 }
1156 
1157 
1158 
1159 /* Gets a GList of strings and returns 1 if one of them starts with substr, 0 otherwise */
1160 int strstr_in_list(GList *list, const char *substr)
     /* [<][>][^][v][top][bottom][index][help] */
1161 {
1162  GList * item = NULL;
1163  char * word; 
1164 
1165   if (tracing)
1166   {
1167     printf("TRACING: strstr_in_list is running\n");
1168   }
1169  
1170  for ( item = list; item != NULL ; item = g_list_next(item) )
1171  {
1172    word = strdup((char *)(item->data));
1173    g_strup(word);
1174    if (strstr(word, substr) == word)
1175    {
1176      free(word);
1177      return 1;
1178    }
1179    free(word);
1180  }
1181  /* none of them matched, so return 0 */
1182  return 0; 
1183 }
1184 
1185 /* Gets a GList of attr structures and returns 1 if one of their (upper case)values 
1186    starts with substr, otherwise returns 0 */
1187 int strstr_in_attr_list(GList * list, const char * substr)
     /* [<][>][^][v][top][bottom][index][help] */
1188 {
1189  GList * item = NULL;
1190  char * word; 
1191 
1192   if (tracing)
1193   {
1194     printf("TRACING: strstr_in_attr_list is running\n");
1195   }
1196  
1197  for( item = list; item != NULL ; item = g_list_next(item) )
1198  {
1199    word = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
1200    g_strup(word);
1201    if (strstr(word, substr) == word)
1202    {
1203      free(word);
1204      return 1;
1205    }
1206    free(word);
1207  }
1208  /* none of them matched, so return 0 */
1209  return 0; 
1210 }
1211 
1212 
1213 
1214 /* Gets a (maintainer/irt) object as a string and returns its 'auth' attributes 
1215    as a GList (linked list) */
1216 
1217 GList *get_auths(char * object_str)
     /* [<][>][^][v][top][bottom][index][help] */
1218 {
1219   const char *name = NULL;
1220   char *value = NULL;
1221   GList *attr;
1222   rpsl_object_t *object;
1223   GList *list_of_auths = NULL;
1224 
1225   if(tracing)
1226   {
1227     printf("TRACING: get_auths is running\n");
1228   }
1229   object = rpsl_object_init(object_str);
1230   
1231   list_of_auths = rpsl_object_get_attr(object, "auth");
1232   rpsl_attr_split_multiple(&list_of_auths);
1233   
1234   if(tracing) 
1235   {
1236         if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1237         {
1238           /* thre was an error during the parsing */
1239           name = rpsl_object_get_class(object);
1240           if ( name )
1241           {
1242                 attr = rpsl_object_get_attr(object, name);
1243                 if ( attr )
1244                 {
1245                   value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1246                   if ( value )
1247                   {
1248                         printf("TRACING: get_auths: error parsing object %s\n", value );
1249                         free(value);
1250                   }
1251                   else
1252                         printf("TRACING: get_auths: error parsing object\n");
1253 
1254                   rpsl_attr_delete_list(attr);
1255                 }
1256           }
1257         }
1258     printf("TRACING: get_auths: returning (with %d nodes)\n", g_list_length(list_of_auths));
1259   }
1260 
1261   rpsl_object_delete(object);
1262   return list_of_auths; 
1263 }
1264 
1265 
1266 
1267 /* Gets a parsed object and returns its 'attr_type' attributes as a 
1268    GList (linked list) */
1269 
1270 GList *get_attr_list(rpsl_object_t *object, const char *attr_type)
     /* [<][>][^][v][top][bottom][index][help] */
1271 {
1272   GList *list_of_attrs = NULL;
1273   char *object_str = NULL;
1274 
1275   if (tracing)
1276   {
1277     object_str = rpsl_object_get_text(object,0);
1278     printf("TRACING: get_attr_list is running searching for %s, object is [\n%s]\n", attr_type ? attr_type : "NULL", object_str ? object_str : "NULL");
1279     free(object_str);
1280   }
1281 
1282   list_of_attrs = rpsl_object_get_attr(object, attr_type);
1283   rpsl_attr_split_multiple(&list_of_attrs);
1284 
1285   return list_of_attrs; 
1286 }
1287 
1288 
1289 
1290 /* Gets a parsed object and returns its mnt_lower attributes as a 
1291    GList (linked list) */
1292 
1293 GList *get_mnt_lowers(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
1294 {
1295   GList *list_of_mnt_lowers = NULL;
1296 
1297   if (tracing)
1298   {
1299     printf("TRACING: get_mnt_lowers is running\n");
1300   }
1301 
1302   list_of_mnt_lowers = rpsl_object_get_attr(object, "mnt-lower");
1303   rpsl_attr_split_multiple(&list_of_mnt_lowers);
1304   
1305   return list_of_mnt_lowers; 
1306 }
1307 
1308 
1309 /* Gets a parsed object and returns its mnt_routes attributes as a 
1310    GList (linked list) */
1311 
1312 GList *get_mnt_routes(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
1313 {
1314   GList *list_of_mnt_routes = NULL;
1315 
1316   if (tracing)
1317   {
1318     printf("TRACING: get_mnt_routes is running\n");
1319   }
1320 
1321   list_of_mnt_routes = rpsl_object_get_attr(object, "mnt-routes");
1322   rpsl_attr_split_multiple(&list_of_mnt_routes );
1323 
1324   return list_of_mnt_routes; 
1325 }
1326 
1327 
1328 /* Gets a linked list of object strings and returns the mnt_routes attribs of
1329    them in a linked list */
1330 GList *get_mnt_routes_from_list(GList *objects_str)
     /* [<][>][^][v][top][bottom][index][help] */
1331 {
1332   GList *objects_str_item = NULL;
1333   GList *list_of_mnt_routes = NULL;
1334   const char *name = NULL;
1335   char *value = NULL;
1336   GList *attr;
1337   rpsl_object_t *object;
1338   
1339   for ( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
1340   {
1341         object = rpsl_object_init((char *)(objects_str_item->data));
1342 
1343         if (tracing)
1344         {
1345       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1346           {
1347                 /* thre was an error during the parsing */
1348                 name = rpsl_object_get_class(object);
1349                 if ( name )
1350                 {
1351                   attr = rpsl_object_get_attr(object, name);
1352                   if ( attr )
1353                   {
1354                     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1355                         if ( value )
1356                         {
1357                       printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
1358                           free(value);
1359                         }
1360                         else
1361                       printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
1362 
1363                         rpsl_attr_delete_list(attr);
1364                   }
1365                 }
1366           }
1367         }
1368 
1369     list_of_mnt_routes = g_list_concat(list_of_mnt_routes, get_mnt_routes(object));
1370     rpsl_object_delete(object);
1371   }
1372 
1373   return list_of_mnt_routes;
1374 }
1375 
1376 
1377 /* Gets a linked list of object strings and returns the mnt_lowers attribs of
1378    them in a linked list */
1379 GList *get_mnt_lowers_from_list(GList * objects_str)
     /* [<][>][^][v][top][bottom][index][help] */
1380 {
1381   GList *objects_str_item = NULL;
1382   GList *list_of_mnt_lowers = NULL;
1383   const char *name = NULL;
1384   char *value = NULL;
1385   GList *attr;
1386   rpsl_object_t *object;
1387   
1388   for( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
1389   {
1390         object = rpsl_object_init((char *)(objects_str_item->data));
1391 
1392         if (tracing)
1393         {
1394       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1395           {
1396                 /* thre was an error during the parsing */
1397                 name = rpsl_object_get_class(object);
1398                 if ( name )
1399                 {
1400                   attr = rpsl_object_get_attr(object, name);
1401                   if ( attr )
1402                   {
1403                     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1404                         if ( value )
1405                         {
1406                       printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
1407                           free(value);
1408                         }
1409                         else
1410                       printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
1411 
1412                         rpsl_attr_delete_list(attr);
1413                   }
1414                 }
1415           }
1416         }
1417 
1418     list_of_mnt_lowers = g_list_concat(list_of_mnt_lowers, get_mnt_lowers(object));
1419     rpsl_object_delete(object);
1420   }
1421 
1422   return list_of_mnt_lowers;
1423 }
1424 
1425 
1426 /* Gets a linked list of object strings and returns the mnt-by attribs of
1427    them in a linked list */
1428 GList *get_mntners_from_list(GList *objects_str)
     /* [<][>][^][v][top][bottom][index][help] */
1429 {
1430   GList *objects_str_item = NULL;
1431   GList *list_of_mntners = NULL;
1432   const char *name = NULL;
1433   char *value = NULL;
1434   GList *attr;
1435   rpsl_object_t *object;
1436   
1437   for ( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
1438   {
1439         object = rpsl_object_init((char *)(objects_str_item->data));
1440 
1441         if (tracing)
1442         {
1443       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1444           {
1445                 /* thre was an error during the parsing */
1446                 name = rpsl_object_get_class(object);
1447                 if ( name )
1448                 {
1449                   attr = rpsl_object_get_attr(object, name);
1450                   if ( attr )
1451                   {
1452                     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1453                         if ( value )
1454                         {
1455                       printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
1456                           free(value);
1457                         }
1458                         else
1459                       printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
1460 
1461                         rpsl_attr_delete_list(attr);
1462                   }
1463                 }
1464           }
1465         }
1466 
1467     list_of_mntners = g_list_concat(list_of_mntners, get_mntners(object));
1468     rpsl_object_delete(object);
1469   }
1470 
1471   return list_of_mntners;
1472 }
1473 
1474 
1475 
1476 /* retrieves the override password from the 'override' attribute  
1477    of the object. If none, it returns NULL   */
1478 char *get_override(rpsl_object_t * object)
     /* [<][>][^][v][top][bottom][index][help] */
1479 {
1480 
1481   GList *attr_list;
1482 
1483   if(tracing)
1484   {
1485     printf("TRACING: get_override is running\n");
1486   }
1487   
1488   attr_list = rpsl_object_get_attr(object, "override");
1489   if ( ! attr_list )
1490   {
1491     /* there was no 'override' attrib, so return NULL */
1492     return NULL;
1493   }
1494 
1495   /* there should only be one item in this list, 
1496      return the clean value of that attribute */
1497   return strdup(rpsl_attr_get_value((rpsl_attr_t *)(attr_list->data)));
1498 }
1499 
1500 
1501 
1502 /* checks override string (password) 
1503    returns OVR_OK if it is correct password */
1504 int check_override(char * string)
     /* [<][>][^][v][top][bottom][index][help] */
1505 {
1506    char ** temp;
1507    int i;
1508    char * crypted_password = strdup(overridecryptedpw);
1509 
1510    if(string == NULL) 
1511    {
1512      if(tracing) 
1513          {
1514        printf("TRACING: check_override is returning FAILED\n");
1515      }
1516          free (crypted_password);
1517      return UP_OVF; /* override attempt failed */ 
1518    }
1519    else
1520    {
1521     /* split the string */
1522      temp = g_strsplit (string, " ", 0);
1523 
1524      for(i=0; temp[i] != NULL; i++)
1525          {
1526        if(strlen(temp[i]) != 0)
1527            {
1528          if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0)
1529                  {
1530            if(tracing) 
1531                    {
1532              printf("TRACING: check_override is returning %s OK\n", string);
1533            }
1534            g_strfreev(temp);
1535                    free (crypted_password);
1536            return OVR_OK; 
1537          }
1538        }
1539      }
1540 
1541      /* we couldn't find a word matching the override password */ 
1542      g_strfreev(temp);         
1543          free (crypted_password);
1544      return UP_OVF; /* override attempt failed */
1545    }
1546 }
1547 
1548 
1549 
1550 
1551 /* takes a GSList of struct auth_struct and a GList of auths, and a mntner/irt name,
1552    add new elements to GSList of struct auth_struct and  returns the new
1553    GSList of struct auth_struct  */
1554 
1555 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GList * auths, char * mntner_name)
     /* [<][>][^][v][top][bottom][index][help] */
1556 {
1557    GList * auth_item;
1558    char * auth_attrib = NULL;
1559    char * auth_attrib_uppercase = NULL, * argument = NULL;
1560    auth_struct * temp = NULL;
1561    int index = 1;
1562    
1563    for (auth_item = auths; auth_item != NULL; auth_item = g_list_next(auth_item))
1564    {
1565      auth_attrib = rpsl_attr_get_clean_value((rpsl_attr_t *)(auth_item->data));
1566      if(tracing)
1567          {
1568        printf("TRACING: add_to_auth_vector: %s\n", auth_attrib);
1569      }
1570      /* Take the auth attribute and convert it into uppercase for comparisons */
1571      auth_attrib_uppercase = strdup(auth_attrib);
1572      g_strup(auth_attrib_uppercase);
1573      
1574      if ( strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase )
1575          {
1576        /* take the argument of the auth attribute */
1577        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1578        g_strstrip(argument);
1579        if(tracing) 
1580            {
1581          printf("TRACING: add_to_auth_vector: adding new CRYPT-PW argument: %s\n", argument);
1582        }
1583        temp = (auth_struct *)malloc(sizeof(auth_struct));
1584        temp->type = AU_CRYPT_PW;
1585        temp->auth = argument;
1586        temp->mntner_name = mntner_name;
1587        temp->index = index++;
1588        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1589      }
1590      else if ( strstr(auth_attrib_uppercase,"MD5-PW") == auth_attrib_uppercase )
1591          {
1592        /* take the argument of the auth attribute */
1593        argument = strdup(auth_attrib + strlen("MD5-PW"));
1594        g_strstrip(argument);
1595        if(tracing) 
1596            {
1597          printf("TRACING: add_to_auth_vector: adding new MD5-PW argument: %s\n", argument);
1598        }
1599        temp = (auth_struct *)malloc(sizeof(auth_struct));
1600        temp->type = AU_MD5_PW;
1601        temp->auth = argument;
1602        temp->mntner_name = mntner_name;
1603        temp->index = index++;
1604        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1605      }
1606          else if (strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase)
1607          {
1608        /* take the argument of the auth attribute */
1609        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1610        g_strstrip(argument);
1611        if(tracing)
1612            {
1613          printf("TRACING: add_to_auth_vector: adding new MAIL-FROM argument: %s\n", argument);
1614        }
1615        temp = (auth_struct *)malloc(sizeof(auth_struct));
1616        temp->type = AU_MAIL_FROM;
1617        temp->auth = argument;
1618        temp->mntner_name = mntner_name;
1619        temp->index = index++;
1620        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1621      }
1622          else if (strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase)
1623          {
1624        /* take the argument of the auth attribute */
1625        if(tracing)
1626            {
1627          printf("TRACING: add_to_auth_vector: adding new NONE argument\n");
1628        }
1629        temp = (auth_struct *)malloc(sizeof(auth_struct));
1630        temp->type = AU_NONE;
1631        temp->auth = NULL;
1632        temp->mntner_name = mntner_name;
1633        temp->index = index++;
1634        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1635     }
1636         else if (strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase)
1637         {
1638        argument = strdup(auth_attrib + strlen("PGPKEY-"));
1639        g_strstrip(argument);
1640        if(tracing)
1641            {
1642          printf("TRACING: add_to_auth_vector: adding new PGPKEY argument: %s\n", argument);
1643        }
1644        temp = (auth_struct *)malloc(sizeof(auth_struct));
1645        temp->type = AU_PGP;
1646        temp->mntner_name = mntner_name;
1647        temp->index = index++;
1648        temp->auth = argument;
1649        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1650      }
1651          else
1652          {
1653        if (tracing)
1654            {
1655          printf("TRACING: Error: invalid auth attrib: %s\n", auth_attrib);
1656        }
1657        return NULL;
1658      }
1659  
1660      free(auth_attrib_uppercase);
1661      free(auth_attrib); 
1662    }
1663 
1664    return list_of_auth_struct;
1665 }
1666 
1667 
1668 
1669 
1670 /* Gets a list of mntner names, retrieves those mntners from
1671    the database and extracts the 'auth' attributes, and
1672    constructs the authorisation vector, which is a GSList of
1673    struct auth_struct */
1674 
1675 GSList * get_auth_vector(GList * mntners)
     /* [<][>][^][v][top][bottom][index][help] */
1676 {
1677   GList * list_of_auths = NULL;
1678   GList * mntner_item = NULL;
1679   GSList * to_be_returned = NULL;
1680   char * query_string = NULL, * result = NULL, * object_str = NULL;
1681   char *value;
1682 
1683   for( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
1684   {
1685     value = rpsl_attr_get_clean_value((rpsl_attr_t *)(mntner_item->data));
1686     if(tracing) 
1687         {
1688       printf("=====\nget_auth_vector: Got a mntner\n%s\n", value  );
1689     }
1690     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
1691     sprintf(query_string, "-Tmntner -s %s -r %s",current_source,value);
1692     result = send_and_get(query_host, query_port, query_string);
1693         free(query_string);
1694     if (count_objects(result) == 0)
1695         {
1696       /* no such maintainer */
1697       if(tracing)
1698           {
1699         printf("get_auth_vector: No such maintainer %s\n", value);
1700       }
1701           free(result);
1702           free(value);
1703       return NULL;
1704     }
1705         else if (count_objects(result) > 1)
1706         {
1707       if(tracing)
1708           {
1709         printf("get_auth_vector: More than one objects returned for %s\n", value);
1710       }
1711     }
1712         else
1713         { /* count_objects(result) == 1 */
1714       object_str = take_object(result);
1715       if(tracing)
1716           {
1717         printf("TRACING: get_auth_vector: Calling get_auths with object [\n%s]\n", object_str);
1718       }
1719 
1720       list_of_auths = get_auths(object_str);
1721       if(tracing)
1722           {
1723         printf("TRACING: get_auth_vector: get_auths returned (with %d nodes)\n", g_list_length(list_of_auths)) ;
1724       }
1725 
1726       /* add this to the auth_vector. ( mntner_item->data->value is the name of the maintainer  ) */
1727       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)value);
1728       if(tracing)
1729           {
1730        printf("TRACING: get_auth_vector: to_be_returned has now %d nodes\n",  g_slist_length(to_be_returned));
1731       }
1732           
1733           rpsl_attr_delete_list(list_of_auths);
1734     }
1735         free(value);
1736         free(result);
1737   }
1738   
1739   if(tracing) 
1740   {  
1741     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1742   }
1743   return to_be_returned; 
1744 }
1745 
1746 
1747 
1748 /* Gets a list of irt names, retrieves those irts from
1749    the database and extracts the 'auth' attributes, and
1750    constructs the authorisation vector, which is a GSList of
1751    struct auth_struct */
1752 
1753 GSList * get_irt_auth_vector(GList * irts)
     /* [<][>][^][v][top][bottom][index][help] */
1754 {
1755   GList * list_of_auths = NULL;
1756   GList * irt_item = NULL;
1757   GSList * to_be_returned = NULL;
1758   char * query_string = NULL, * result = NULL, * object_str = NULL;
1759   char *value;
1760 
1761   for( irt_item = irts; irt_item != NULL ; irt_item = g_list_next(irt_item) )
1762   {
1763     value = rpsl_attr_get_clean_value((rpsl_attr_t *)(irt_item->data));
1764     if(tracing) 
1765         {
1766       printf("=====\nget_irt_auth_vector: Got an irt\n%s\n", value  );
1767     }
1768     query_string = (char *)malloc(strlen("-Tirt -s  -r ")+strlen(current_source)+strlen(value)+1);
1769     sprintf(query_string, "-Tirt -s %s -r %s",current_source,value);
1770     result = send_and_get(query_host, query_port, query_string);
1771         free(query_string);
1772     if (count_objects(result) == 0)
1773         {
1774       /* no such irt */
1775       if(tracing)
1776           {
1777         printf("get_irt_auth_vector: No such irt %s\n", value);
1778       }
1779           free(result);
1780           free(value);
1781       return NULL;
1782     }
1783         else if (count_objects(result) > 1)
1784         {
1785       if(tracing)
1786           {
1787         printf("get_irt_auth_vector: More than one objects returned for %s\n", value);
1788       }
1789     }
1790         else
1791         { /* count_objects(result) == 1 */
1792       object_str = take_object(result);
1793       if(tracing)
1794           {
1795         printf("TRACING: get_irt_auth_vector: Calling get_auths with object [\n%s]\n", object_str);
1796       }
1797 
1798       list_of_auths = get_auths(object_str);
1799       if(tracing)
1800           {
1801         printf("TRACING: get_irt_auth_vector: get_auths returned (with %d nodes)\n", g_list_length(list_of_auths)) ;
1802       }
1803 
1804       /* add this to the auth_vector. ( irt_item->data->value is the name of the irt  ) */
1805       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)value);
1806       if(tracing)
1807           {
1808        printf("TRACING: get_irt_auth_vector: to_be_returned has now %d nodes\n",  g_slist_length(to_be_returned));
1809       }
1810           
1811           rpsl_attr_delete_list(list_of_auths);
1812     }
1813         free(value);
1814         free(result);
1815   }
1816   
1817   if(tracing) 
1818   {  
1819     printf("TRACING: get_irt_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1820   }
1821   return to_be_returned; 
1822 }
1823 
1824 
1825 
1826 
1827 /* Gets a list of mntner attributes, retrieves those mntners from
1828    the database and extracts the 'mnt-nfy' attributes, and
1829    returns them as a GList */
1830 
1831 GList * get_mntnfy_vector(GList *mntners)
     /* [<][>][^][v][top][bottom][index][help] */
1832 {
1833   GList * list_of_mntnfy = NULL;
1834   GList * mntner_item = NULL;
1835   GList * temp;
1836   const GList * error_list = NULL;
1837   char * query_string = NULL, * result = NULL, * object_str = NULL;
1838   char *value;
1839   rpsl_object_t *object;
1840   
1841   for ( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
1842   {
1843         value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(mntner_item->data) );
1844     if (tracing)
1845         {
1846       printf( "=====\nGot a mntner\n%s\n", value );
1847     }
1848     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
1849     sprintf(query_string, "-Tmntner -s %s -r %s", current_source,value);
1850     result = send_and_get(query_host, query_port, query_string);
1851         free(query_string);
1852     if (count_objects(result) == 0)
1853         {
1854       /* no such maintainer */
1855       if(tracing)
1856           {
1857         printf("get_mntnfy_vector: No such maintainer %s\n", value);
1858       }
1859     }
1860         else if (count_objects(result) > 1)
1861         {
1862       if (tracing)
1863           {
1864         printf("get_mntnfy_vector: More than one objects returned for maintainer %s\n", value);
1865       }
1866     }
1867         else
1868         { /* count_objects(result) == 1 */
1869       object_str = take_object(result);
1870           object = rpsl_object_init(object_str);
1871           error_list = rpsl_object_errors(object);
1872 
1873       if (tracing)
1874           {
1875         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1876       }
1877 
1878       temp = get_attr_list(object, "mnt-nfy");
1879 
1880       if (tracing)
1881           {
1882         printf("TRACING: get_mntnfy_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
1883       }
1884 
1885       list_of_mntnfy = g_list_concat(list_of_mntnfy, temp);
1886 
1887       if (tracing)
1888           {
1889         printf("TRACING: get_mntnfy_vector: list_of_mntnfy has now %i nodes\n", g_list_length(list_of_mntnfy));
1890       }
1891       rpsl_object_delete(object);
1892     }
1893         free(value);
1894         free(result);
1895   }
1896   
1897   if (tracing)
1898   {  
1899     printf("TRACING: get_mntnfy_vector: list_of_mntnfy has %i nodes\n", g_list_length(list_of_mntnfy)); 
1900   }
1901   return list_of_mntnfy; 
1902 }
1903 
1904 
1905 
1906 
1907 /* Gets a list of irt attributes, retrieves those irts from
1908    the database and extracts the 'irt-nfy' attributes, and
1909    returns them as a GList */
1910 
1911 GList * get_irtnfy_vector(GList *irts)
     /* [<][>][^][v][top][bottom][index][help] */
1912 {
1913   GList * list_of_irtnfy = NULL;
1914   GList * irt_item = NULL;
1915   GList * temp;
1916   const GList * error_list = NULL;
1917   char * query_string = NULL, * result = NULL, * object_str = NULL;
1918   char *value;
1919   rpsl_object_t *object;
1920   
1921   for ( irt_item = irts; irt_item != NULL ; irt_item = g_list_next(irt_item) )
1922   {
1923         value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(irt_item->data) );
1924     if (tracing)
1925         {
1926       printf( "=====\nGot a irt\n%s\n", value );
1927     }
1928     query_string = (char *)malloc(strlen("-Tirt -s  -r ")+strlen(current_source)+strlen(value)+1);
1929     sprintf(query_string, "-Tirt -s %s -r %s", current_source,value);
1930     result = send_and_get(query_host, query_port, query_string);
1931         free(query_string);
1932     if (count_objects(result) == 0)
1933         {
1934       /* no such irt */
1935       if(tracing)
1936           {
1937         printf("get_irtnfy_vector: No such irt %s\n", value);
1938       }
1939     }
1940         else if (count_objects(result) > 1)
1941         {
1942       if (tracing)
1943           {
1944         printf("get_irtnfy_vector: More than one objects returned for irt %s\n", value);
1945       }
1946     }
1947         else
1948         { /* count_objects(result) == 1 */
1949       object_str = take_object(result);
1950           object = rpsl_object_init(object_str);
1951           error_list = rpsl_object_errors(object);
1952 
1953       if (tracing)
1954           {
1955         printf("TRACING: get_irtnfy_vector: Calling get_attr_list\n");
1956       }
1957 
1958       temp = get_attr_list(object, "irt-nfy");
1959 
1960       if (tracing)
1961           {
1962         printf("TRACING: get_irtnfy_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
1963       }
1964 
1965       list_of_irtnfy = g_list_concat(list_of_irtnfy, temp);
1966 
1967       if (tracing)
1968           {
1969         printf("TRACING: get_irtnfy_vector: list_of_irtnfy has now %i nodes\n", g_list_length(list_of_irtnfy));
1970       }
1971       rpsl_object_delete(object);
1972     }
1973         free(value);
1974         free(result);
1975   }
1976   
1977   if (tracing)
1978   {  
1979     printf("TRACING: get_irtnfy_vector: list_of_irtnfy has %i nodes\n", g_list_length(list_of_irtnfy)); 
1980   }
1981   return list_of_irtnfy; 
1982 }
1983 
1984 
1985 
1986 /* Gets a list of mntner names, retrieves those mntners from
1987    the database and extracts the 'upd-to' attributes, and
1988    returns them as a GList */
1989 
1990 GList * get_updto_vector(GList * mntners)
     /* [<][>][^][v][top][bottom][index][help] */
1991 {
1992   GList * list_of_updto = NULL;
1993   GList * mntner_item = NULL;
1994   char * query_string = NULL, * result = NULL, * object_str = NULL;
1995   GList * temp;
1996   const GList * error_list = NULL;
1997   char *value;
1998   rpsl_object_t *object;
1999   
2000   for ( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
2001   {
2002         value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(mntner_item->data) );
2003     if (tracing)
2004         {
2005       printf( "=====\nGot a mntner\n%s\n", value );
2006     }
2007     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
2008     sprintf(query_string, "-Tmntner -s %s -r %s", current_source,value);
2009     result = send_and_get(query_host, query_port, query_string);
2010     if (count_objects(result) == 0)
2011         {
2012       /* no such maintainer */
2013       if(tracing)
2014           {
2015         printf("get_updto_vector: No such maintainer %s\n", value);
2016       }
2017     }
2018         else if(count_objects(result) > 1)
2019         {
2020       if (tracing)
2021           {
2022         printf("get_updto_vector: More than one objects returned for maintainer %s\n", value);
2023       }
2024     }
2025         else
2026         { /* count_objects(result) == 1 */
2027       object_str = take_object(result);
2028           object = rpsl_object_init(object_str);
2029           error_list = rpsl_object_errors(object);
2030 
2031       if (tracing)
2032           {
2033         printf("TRACING: get_updto_vector: Calling get_attr_list\n");
2034       }
2035 
2036       temp = get_attr_list(object, "upd-to");
2037 
2038       if (tracing)
2039           {
2040         printf("TRACING: get_updto_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
2041       }
2042 
2043       list_of_updto = g_list_concat(list_of_updto, temp);
2044 
2045       if (tracing)
2046           {
2047         printf("TRACING: get_updto_vector: list_of_mntnfy has now %i nodes\n",  g_list_length(list_of_updto));
2048       }
2049       rpsl_object_delete(object);
2050     }
2051         free(value);
2052         free(result);
2053   }
2054   
2055   if (tracing)
2056   {  
2057     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_list_length(list_of_updto)); 
2058   }
2059   return list_of_updto; 
2060 }
2061 
2062 
2063 
2064 
2065 /* gets one or more route objects filters out the ones which don't have the same
2066    origin as 'char * origin' argument */
2067 char * up_filter_out_diff_origins(char * objects_str, char * origin)
     /* [<][>][^][v][top][bottom][index][help] */
2068 {
2069   GList * object_str_list = NULL, * object_str_item =NULL;
2070   const GList *error_list = NULL; 
2071   char * objects_to_be_returned = NULL;
2072   char * key = NULL;
2073   rpsl_object_t *object;
2074   
2075   if (tracing) 
2076   {
2077     printf("TRACING: up_filter_out_diff_origins\n");
2078   }
2079 
2080   /* strip the lines beginning with '%' off */
2081   objects_str = strip_lines(objects_str);
2082   
2083   /* separate the objects, store them in a linked list */
2084   object_str_list = take_objects(objects_str);
2085 
2086   for (object_str_item = object_str_list; object_str_item != NULL; object_str_item = g_list_next(object_str_item))
2087   {
2088     object = rpsl_object_init((char *)(object_str_item->data));
2089         error_list = rpsl_object_errors(object);
2090     key = get_search_key(object, "origin");
2091     if (key != NULL && strcasecmp(g_strstrip(origin), key) == 0)
2092         {
2093       if (objects_to_be_returned == NULL)
2094           {
2095         objects_to_be_returned = strdup((char *)(object_str_item->data));
2096       }
2097           else
2098           {
2099         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
2100                       strlen(objects_to_be_returned) + strlen((char *)(object_str_item->data)) + 2);
2101         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
2102         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_str_item->data));
2103       }
2104     }
2105     rpsl_object_delete(object);
2106         free(key);
2107   }
2108 
2109   if(tracing) 
2110   {
2111       printf("TRACING: up_filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned : "(NULL)");
2112   }
2113   
2114   return objects_to_be_returned; 
2115 }
2116 
2117 
2118 
2119 /* gets one or more person/role objects filters out the ones which don't have the same
2120    nic_hdl as 'char * nic_hdl' argument */
2121 char * up_filter_out_diff_nichdls(char * objects_str, char * nic_hdl)
     /* [<][>][^][v][top][bottom][index][help] */
2122 {
2123   GList * object_str_list = NULL, * object_str_item =NULL;
2124   char * objects_to_be_returned = NULL;
2125   char * key = NULL;
2126   rpsl_object_t *object;
2127   
2128   if (tracing)
2129   {
2130     printf("TRACING: up_filter_out_diff_nichdls\n");
2131   }
2132 
2133   /* strip the lines beginning with '%' off */
2134   objects_str = strip_lines(objects_str);
2135   
2136   /* separate the objects strings, store them in a linked list */
2137   object_str_list = take_objects(objects_str);
2138 
2139   for (object_str_item = object_str_list; object_str_item != NULL; object_str_item = g_list_next(object_str_item))
2140   {
2141     object = rpsl_object_init((char *)(object_str_item->data));
2142     key = get_search_key(object, "nic-hdl");
2143     if (key != NULL && strcasecmp(g_strstrip(nic_hdl), key) == 0)
2144         {
2145       if (objects_to_be_returned == NULL)
2146           {
2147         objects_to_be_returned = strdup((char *)(object_str_item->data));
2148       }
2149           else
2150           {
2151         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
2152                       strlen(objects_to_be_returned) + strlen((char *)(object_str_item->data)) + 2);
2153         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
2154         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_str_item->data));
2155       }
2156     }
2157     rpsl_object_delete(object);
2158   }
2159 
2160   if(tracing)
2161   {
2162       printf("TRACING: up_filter_out_diff_nichdls: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned :"(NULL)");
2163   }
2164 
2165   return objects_to_be_returned; 
2166 }
2167 
2168 
2169 
2170 /* gets one or more route objects, filters out the ones which have the same
2171    origin as 'char * origin' argument */
2172 char * UP_filter_out_same_origins(char * objects_str, rpsl_object_t * object)
     /* [<][>][^][v][top][bottom][index][help] */
2173 {
2174   GList * object_list = NULL, * object_item =NULL;
2175   const GList *error_list = NULL; 
2176   char * objects_to_be_returned = NULL;
2177   char * key = NULL;
2178   rpsl_object_t  *obj;
2179   char * origin;
2180     
2181   if (tracing)
2182   {
2183     printf("TRACING: UP_filter_out_same_origins\n");
2184   }
2185 
2186   origin = get_search_key(object, "origin");
2187 
2188   /* strip the lines beginning with '%' off */
2189   objects_str = strip_lines(objects_str);
2190   
2191   /* separate the objects, store them in a linked list */
2192   object_list = take_objects(objects_str);
2193 
2194   for (object_item = object_list; object_item != NULL; object_item = g_list_next(object_item))
2195   {
2196     obj = rpsl_object_init((char *)(object_item->data));
2197         error_list = rpsl_object_errors(obj);
2198 
2199     key = get_search_key(obj, "origin");
2200     if (key != NULL && strcasecmp(g_strstrip(origin), key) != 0)
2201         {
2202       if (objects_to_be_returned == NULL)
2203           {
2204         objects_to_be_returned = strdup((char *)(object_item->data));
2205       }
2206           else
2207           {
2208         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
2209                       strlen(objects_to_be_returned) + strlen((char *)(object_item->data)) + 2);
2210         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
2211         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_item->data));
2212       }
2213     }
2214         rpsl_object_delete(obj);
2215   }
2216 
2217   if (tracing)
2218   {
2219       printf("TRACING: up_filter_out_same_origins: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned : "(NULL)");
2220   }
2221 
2222   return objects_to_be_returned; 
2223 }
2224 
2225 
2226 
2227 /* If the status is ALLOCATED PI or ALLOCATED PA (inetnum) 
2228    or ALLOCATED-BY-RIR (inet6num)
2229    only valid if the maintainers in the mnt-by attributes contain 
2230    at least one of the names mentioned in ALLOCMNT config variable. 
2231    Receives an object as a parsed object
2232             the type (inetnum or inet6num)
2233             the new status value
2234    Returns UP_AUTH_OK if the status/mnt-by combination is valid
2235            UP_AUF     if the status/mnt-by combination is not valid
2236 */
2237 int up_check_reserved_status(rpsl_object_t *object, const char *type, char *new_status)
     /* [<][>][^][v][top][bottom][index][help] */
2238 {
2239   GList * mnt_by_list = NULL;
2240   GList *item;
2241 
2242   char *status;
2243   char *mnt_by;
2244   char **allocmnt_list;
2245   int i;
2246 
2247   /* Gather a list of mnt-by attributes */
2248   mnt_by_list = rpsl_object_get_attr(object, "mnt-by");
2249   rpsl_attr_split_multiple(&mnt_by_list);
2250 
2251   status = strdup(new_status);
2252   g_strdown(status);
2253  
2254   /* construct a list of mntners that are in allocmnt */
2255   allocmnt_list = g_strsplit(allocmnt, " ", 0); /* delimited by " " */
2256    
2257   if ( (! strcmp(type, "inetnum") && strstr(status, "allocated") != NULL)
2258       || (! strcmp(type, "inet6num") && strstr(status, "allocated-by-rir") != NULL) )
2259   { 
2260     free(status);
2261     
2262     for ( item = mnt_by_list; item != NULL ; item = g_list_next(item) )
2263         {
2264       mnt_by = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
2265       for (i=0; allocmnt_list[i] != NULL; i++)
2266           { 
2267         /* loop thru the list of allocmnt maintainers */
2268         if ((strlen(allocmnt_list[i]) != 0) && strcasecmp(mnt_by, allocmnt_list[i]) == 0)
2269                 {
2270           /* this mnt-by is in the allocmnt list */
2271           free(mnt_by);
2272           g_strfreev(allocmnt_list);
2273           rpsl_attr_delete_list(mnt_by_list);
2274           return UP_AUTH_OK; 
2275         }
2276       }  
2277       free(mnt_by);
2278     }
2279     
2280     g_strfreev(allocmnt_list);
2281     rpsl_attr_delete_list(mnt_by_list);
2282     
2283     /* none of the mnt-by are in the allocmnt list */
2284     return UP_AUF;
2285   }
2286   else
2287   {  /* the status attribute is not a reserved category */
2288     free(status);
2289     g_strfreev(allocmnt_list);
2290     rpsl_attr_delete_list(mnt_by_list);
2291 
2292     return UP_AUTH_OK;
2293   }
2294 }
2295 
2296 
2297 
2298 
2299 /*  Get the value of the status of an inet(6)num object 
2300     Receives an object as a parsed object
2301     Returns the status value or NULL if none found
2302 */
2303 
2304 char * up_get_status(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
2305 {
2306    GList *status_attrs;
2307    char *status;
2308 
2309    status_attrs = rpsl_object_get_attr(object, "status");
2310    if ( status_attrs != NULL )
2311    {
2312      status = rpsl_attr_get_clean_value((rpsl_attr_t *)(status_attrs->data));
2313      rpsl_attr_delete_list(status_attrs);
2314      return status;
2315    }
2316    else
2317      return NULL;
2318 }
2319 
2320 
2321 
2322 /*  Get the value of the status of the more/less specific object for an inet(6)num object 
2323     Receives an object as a parsed object
2324              the type (inetnum or inet6num)
2325              address of the status value pointer
2326              flag (-m or -l)
2327     Returns NULL   if there is no more/less specific inet(6)num object
2328             1 if there is a more/less specific inet(6)num object
2329             status value (or NULL if none found) set in the address
2330 */
2331 
2332 int up_get_specific_status(rpsl_object_t *object, const char *type, char **status, char *flag)
     /* [<][>][^][v][top][bottom][index][help] */
2333 {
2334    const GList *error_list = NULL;
2335    char *specific_object_str = NULL;
2336 
2337    rpsl_object_t *specific_obj = NULL;
2338 
2339    /* get the one more/less specific inet(6)num object */
2340    specific_object_str = get_specific(object, type, flag);
2341    if (specific_object_str == NULL)
2342    {
2343      /* there is no more/less specific inet(6)num object */
2344      if (tracing)
2345      {
2346        printf("TRACING: up_get_specific_status: no %s inet(6)num object found\n", flag);
2347      }
2348    
2349      *status = NULL;
2350      return NULL;
2351    }
2352    
2353    /* don't try to parse the object if the -K flag was used */
2354    if ( ! strstr(flag, "K") )
2355    {
2356      specific_obj = rpsl_object_init(specific_object_str);
2357      error_list = rpsl_object_errors(specific_obj);
2358      free (specific_object_str);
2359 
2360      /* get the status of the more/less specific object */
2361      *status = up_get_status(specific_obj);
2362      rpsl_object_delete(specific_obj);
2363    }
2364 
2365    if (tracing)
2366    {
2367      printf("TRACING: up_get_specific_status: %s specific_status [%s] \n",
2368                   flag, *status ? *status : "NONE");
2369    }
2370    
2371    return 1;
2372 }
2373 
2374 /*  Find if the inet(6)num object has any more specific objects 
2375     Receives an object as a parsed object
2376              the type (inetnum or inet6num)
2377     Returns NULL   if there is no more specific inet(6)num object
2378             1 if there is a more specific inet(6)num object
2379 */
2380 
2381 int up_find_more_specific(rpsl_object_t *object, const char *type)
     /* [<][>][^][v][top][bottom][index][help] */
2382 {
2383    char *more_specific_object_str = NULL;
2384 
2385    /* get the one more specific inet(6)num object */
2386    more_specific_object_str = get_specific(object, type, "-m -K");
2387    if (more_specific_object_str == NULL)
2388      return NULL;
2389    else
2390    {
2391      /* there is a more specific inet(6)num object */
2392      if (tracing)
2393      {
2394        printf("TRACING: up_get_more_specific_status: more specific inet(6)num object found\n");
2395      }
2396    
2397      return 1;
2398    }
2399 }
2400 
2401 
2402 /* check the new status and less specific status according to the defined rules for inetnum
2403    Receives an object as a parsed object
2404             the new status
2405             the less specific status
2406             flag for existance of less specific object 
2407                 (NULL - does not exist, not NULL - does exist)
2408             the override value
2409    Returns standard auth return codes:
2410            UP_AUTH_OK         if all the status checks are OK
2411            UP_HOF or UP_AUF   if any of the status checks fail
2412 */
2413 
2414 int up_check_inetnum_status_rules(rpsl_object_t *object, char *new_status, char *less_specific_status, int ls_obj_exists, int overriden)
     /* [<][>][^][v][top][bottom][index][help] */
2415 {
2416   int result;
2417 
2418   if ( ! ls_obj_exists )
2419   {
2420      /* there is no less specific inetnum object */
2421      if (overriden)
2422      {
2423        /* override the status check when no less specific object found */
2424        return UP_AUTH_OK; 
2425      }
2426      else
2427      {
2428        return UP_HOF; /* hierarchical authorisation failed */
2429      }
2430   }
2431 
2432   if ( ! less_specific_status )
2433   {
2434     /* the less specific object exists but has no status value */
2435     return UP_HOF; /* hierarchical authorisation failed */
2436   }
2437   
2438   /* check if the status/mnt-by combination is valid */
2439   result = up_check_reserved_status(object, "inetnum", new_status);
2440   if ( result != UP_AUTH_OK)
2441     return result;
2442 
2443   /* now check the relative status values */
2444   if ( ! strcmp(new_status, "LIR-PARTITIONED PA") || ! strcmp(new_status, "LIR-PARTITIONED PI") )
2445   {
2446     if ( 
2447              ( (! strcmp(new_status, "LIR-PARTITIONED PA")) && strcmp(less_specific_status, "ALLOCATED PA") && strcmp(less_specific_status, "LIR-PARTITIONED PA") && strcmp(less_specific_status, "ALLOCATED UNSPECIFIED") )
2448            || 
2449              ( (! strcmp(new_status, "LIR-PARTITIONED PI")) && strcmp(less_specific_status, "ALLOCATED PI") && strcmp(less_specific_status, "LIR-PARTITIONED PI") && strcmp(less_specific_status, "ALLOCATED UNSPECIFIED") ) 
2450            )
2451     {
2452           return UP_HOF; /* hierarchical authorisation failed */
2453     }
2454   }
2455   
2456   /* all check passed */
2457   return UP_AUTH_OK;
2458 }
2459 
2460 
2461 /* check the new status and less specific status according to the defined rules for inet6num
2462    Receives an object as a parsed object
2463             the new status
2464             the less specific status
2465             flag for existance of less specific object 
2466                 (NULL - does not exist, not NULL - does exist)
2467             flag for existance of more specific object 
2468             the override value
2469    Returns standard auth return codes:
2470            UP_AUTH_OK         if all the status checks are OK
2471            UP_HOF or UP_AUF   if the any of status checks fail
2472 */
2473 
2474 int up_check_inet6num_status_rules(rpsl_object_t *object, char *new_status, char *less_specific_status, int ls_obj_exists, int ms_obj_exists, int overriden)
     /* [<][>][^][v][top][bottom][index][help] */
2475 {
2476   int result;
2477 
2478   if (tracing)
2479   {
2480     printf("TRACING: up_check_inet6num_status_rules:\n");
2481     printf("    new_status [%s] less_specific_status [%s]\n", 
2482                    new_status, less_specific_status ? less_specific_status : "NONE");
2483     printf("    ls_obj_exists [%d] ms_obj_exists [%d] overriden [%d]\n", 
2484                    ls_obj_exists, ms_obj_exists, overriden);
2485   }
2486 
2487   if ( ! ls_obj_exists )
2488   {
2489      /* there is no less specific inet6num object */
2490      if (overriden)
2491      {
2492        /* override the status check when no less specific object found */
2493        return UP_AUTH_OK; 
2494      }
2495      else
2496      {
2497        return UP_HOF; /* hierarchical authorisation failed */
2498      }
2499   }
2500 
2501   if ( ! less_specific_status )
2502   {
2503     /* the less specific object has no status value */
2504     return UP_HOF; /* hierarchical authorisation failed */
2505   }
2506 
2507   if ( strcasecmp(less_specific_status, "ALLOCATED-BY-RIR") 
2508     && strcasecmp(less_specific_status, "ALLOCATED-BY-LIR") 
2509     && strcasecmp(less_specific_status, "ASSIGNED") )
2510   {
2511     /* the less specific inet6num status is not recognised */
2512         return UP_HOF; /* hierarchical authorisation failed */
2513   }
2514   
2515   /* check if the status/mnt-by combination is valid */
2516   result = up_check_reserved_status(object, "inet6num", new_status);
2517   if ( result != UP_AUTH_OK)
2518     return result;
2519 
2520   /* check the relative status rules */
2521   if ( ! strcasecmp(new_status, "ASSIGNED") || ! strcasecmp(new_status, "ALLOCATED-BY-LIR") )
2522   {
2523     /* less specific status must be ALLOCATED-BY-LIR or ALLOCATED-BY-RIR */
2524     if ( strcasecmp(less_specific_status, "ALLOCATED-BY-RIR")
2525       && strcasecmp(less_specific_status, "ALLOCATED-BY-LIR") )
2526     {
2527       /* invalid status */
2528           return UP_HOF; /* hierarchical authorisation failed */
2529     }
2530   }
2531 
2532   if ( ! strcasecmp(new_status, "ASSIGNED") && ms_obj_exists )
2533   {
2534     /* invalid status */
2535         return UP_HOF; /* hierarchical authorisation failed */
2536   }
2537   
2538   return UP_AUTH_OK;
2539 }
2540 
2541 
2542 /*  Check the status value of an inet(6)num object against the hierarchical rules.
2543     Receives the new object and old (or NULL if creation) object as parsed objects.
2544              the type (inetnum or inet6num)
2545              the override value
2546     Returns standard auth return codes:
2547             UP_AUTH_OK if the status checks are OK
2548             UP_HOF     if the status checks fail
2549 */
2550 
2551 int up_check_status(rpsl_object_t *new_object, rpsl_object_t *old_object, const char *type, int overriden)
     /* [<][>][^][v][top][bottom][index][help] */
2552 {
2553   rpsl_object_t *object;
2554   const GList *error_list = NULL;
2555   char *old_status = NULL;
2556   char *new_status = NULL;
2557   char *less_specific_status = NULL;
2558   char *more_specific_status = NULL;
2559   int result = NULL;
2560   int ls_obj_exists = NULL;
2561   int ms_obj_exists = NULL;
2562   int update = NULL;
2563 
2564   if (tracing)
2565   {
2566     printf("TRACING: up_check_status running\n");
2567   }
2568 
2569   if ( new_object != NULL && old_object == NULL )
2570   {
2571     /* this is a creation */
2572     update = NULL;
2573     object = new_object;
2574   }
2575   else if ( new_object != NULL && old_object != NULL )
2576   {
2577     /* this is an update */
2578     update = 1;
2579     object = old_object;
2580   }
2581   else
2582   {
2583     /* this is a deletion, no status checks required */
2584     return UP_AUTH_OK;
2585   }
2586 
2587   /* get the status of the new inetnum object */
2588   new_status = up_get_status(new_object);
2589   if ( ! new_status )
2590   {
2591     die;  /* should not happen, syntax error should already have been trapped */
2592   }
2593 
2594   if ( update )
2595   {
2596     /* get the status of the old inetnum object */
2597     old_status = up_get_status(old_object);
2598     if ( ! old_status )
2599     {
2600           old_status = strdup("");  /* to allow for legacy objects with no status */
2601     }
2602   }
2603 
2604   if (tracing)
2605   {
2606     printf("TRACING: check_status: old_status [%s] new status [%s]\n",
2607                   update ? old_status : "N/A", new_status );
2608   }
2609 
2610   if ( ! update || strcmp(new_status, old_status) )
2611   {
2612     /* this is a creation or
2613        it is an update and the status has changed, 
2614        make sure the new value is allowed */
2615 
2616     /* get the status of the less specific and more specific objects */
2617     ls_obj_exists = up_get_specific_status(object, type, &less_specific_status, "-l");
2618     if ( ! strcmp(type, "inet6num") )
2619       ms_obj_exists = up_get_specific_status(object, type, &more_specific_status, "-m -K");
2620 
2621     if ( ! strcmp(type, "inetnum") )
2622       result = up_check_inetnum_status_rules(object, new_status, less_specific_status, ls_obj_exists, overriden);
2623     else
2624       result = up_check_inet6num_status_rules(object, new_status, less_specific_status, ls_obj_exists, ms_obj_exists, overriden);
2625 
2626     if ( less_specific_status )
2627       free(less_specific_status);
2628     if ( old_status )
2629           free (old_status);
2630     free (new_status);
2631 
2632     return result;
2633   }
2634   else
2635   {
2636     /* update with no change in status, so no checks required */
2637     return UP_AUTH_OK;
2638   }
2639 }
2640 
2641 
2642 /* Check authorisation
2643    Applies authorisation rules according to the object type 
2644    
2645    Arguments:
2646       char *new_object: the new object,
2647       char *old_object: the old object, as found in the database,
2648       char *type: type of the object
2649       credentials_struct credentials: a struct which
2650         contains credentials of the update, such as 'From:' field of
2651         the e-mail header and passwords in the update   */
2652 
2653 int check_auth(rpsl_object_t *new_object, rpsl_object_t *old_object, const char *type, credentials_struct credentials)
     /* [<][>][^][v][top][bottom][index][help] */
2654 {
2655    GList *old_mntners = NULL, *new_mntners = NULL;
2656    GList *old_irts = NULL, *new_irts = NULL;
2657    GList *changed_irts = NULL; 
2658    GList *as_block_mnt_lowers = NULL;
2659    GSList *old_auth_vector = NULL, *new_auth_vector = NULL;
2660    GSList *changed_auth_vector = NULL;
2661    GSList *as_block_auth_vector = NULL;
2662    GSList *less_specific_auth_vector = NULL;
2663    GList *less_specific_mnt_lowers = NULL;
2664    GList *less_specific_mntners = NULL;
2665    GList *aut_num_maintainers = NULL;
2666    GSList *aut_num_auth_vector = NULL;
2667    GList *exact_match_routes_str = NULL;  
2668    GList *exact_match_routes_maintainers = NULL;
2669    GSList *exact_match_routes_auth_vector = NULL;
2670    GList *exact_match_maintainers = NULL;
2671    GSList *exact_match_auth_vector = NULL;
2672    GList *less_spec_routes_str = NULL;
2673    GList *less_spec_routes_mntners = NULL;
2674    GSList *less_spec_routes_auth_vector = NULL;
2675    GList *exact_match_inetnum_mnt_routes = NULL;
2676    GSList *exact_match_inetnum_auth_vector = NULL;
2677    GList *less_spec_inetnum_mntners = NULL;
2678    GSList *less_spec_inetnum_auth_vector = NULL;
2679    GList *less_spec_inetnum_mnt_bys = NULL;
2680    GList *exact_match_inetnum_mnt_bys;
2681 
2682    GList *old_name = NULL;
2683    GList *new_name = NULL;
2684    GList *attr;
2685    const GList *error_list = NULL;
2686    GList *status_attrs;
2687 
2688    char *less_specific_status;
2689    char *old_status;
2690    char *new_status;
2691    int status_result;
2692    char *as_block_object_str = NULL;
2693    char *less_specific_object_str = NULL;
2694    char *less_specific_domain_str = NULL;
2695    char *less_spec_inetnum_str = NULL;
2696    char *exact_match_inetnum_str = NULL;
2697    const char *less_specific_object_type = NULL;
2698    char *override_string = NULL;
2699    char *set_name = NULL;
2700    char * aut_num_object_str = NULL;
2701    char * name_old = NULL;
2702    char * name_new = NULL;
2703    const char *name;
2704    int aut_num_auth_OK = FALSE;
2705 
2706    int auth_return, saved_auth_return;
2707    char *value;
2708 
2709    rpsl_object_t *as_block_obj = NULL;
2710    rpsl_object_t *less_specific_obj = NULL;
2711    rpsl_object_t *less_specific_domain_obj = NULL;
2712    rpsl_object_t *aut_num_obj = NULL;
2713    rpsl_object_t *exact_match_inetnum_obj = NULL;
2714    rpsl_object_t *less_spec_inetnum_obj = NULL;
2715 
2716    int overriden = 0;
2717    
2718    if (tracing)
2719    {                                
2720          printf("TRACING: check_auth is running with object type [%s]\n", type);
2721    }
2722 
2723    /* first check if it is overriden or not. if overriden, check the override
2724       password. If it is correct, continue, setting "overriden" to 1. If not,   
2725       immediately exit returning ERR_UP_OVF                                   */
2726    override_string = get_override((new_object == NULL) ? old_object : new_object );
2727    if(override_string == NULL)
2728    { 
2729          if (tracing)
2730          {                                
2731            printf("TRACING: overriden not set\n");
2732          }
2733      overriden = 0;
2734    }
2735    else if ( check_override(override_string) == OVR_OK )
2736    {
2737          if (tracing)
2738          {                                
2739            printf("TRACING: overriden set\n");
2740          }
2741      overriden = 1; /* authorisation is overriden */
2742      free(override_string);
2743          override_string = NULL;
2744    }
2745    else
2746    {
2747          if (tracing)
2748          {                                
2749            printf("TRACING: override failed\n");
2750          }
2751      free(override_string);
2752          override_string = NULL;
2753      return UP_OVF; /* override failed! */
2754    }
2755 
2756 
2757    /*  
2758     *  Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types 
2759     */
2760    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
2761       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
2762       strcmp(type,"key-cert") == 0 )
2763    {
2764      if( new_object == NULL && old_object != NULL )
2765          { /* the object is to be deleted */
2766        old_mntners = get_mntners(old_object);
2767        old_auth_vector = get_auth_vector(old_mntners);
2768        if (old_mntners != NULL && old_auth_vector == NULL)
2769            {
2770          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2771                  rpsl_attr_delete_list(old_mntners);
2772          return UP_AUF; /* auth failed */
2773        }
2774        auth_return = authorise(old_auth_vector, credentials, overriden);
2775        if (old_auth_vector)
2776              g_slist_free(old_auth_vector);
2777            return auth_return;
2778      }
2779          else if ( new_object != NULL && old_object == NULL )
2780          { /* the object is to be created */
2781        new_mntners = get_mntners(new_object);
2782        new_auth_vector = get_auth_vector(new_mntners);
2783        if(new_mntners != NULL && new_auth_vector == NULL)
2784            {
2785          /* then, the mntners in 'new_mntners' do not exist. Problem. */
2786                  rpsl_attr_delete_list(new_mntners);
2787          return UP_AUF; /* auth failed */
2788        }
2789        auth_return = authorise(new_auth_vector, credentials, overriden);
2790            if (new_auth_vector)
2791              g_slist_free(new_auth_vector);
2792            return auth_return;
2793      }
2794          else if ( new_object != NULL && old_object != NULL )
2795          { /* this is an update */
2796        /* check name change of person/role */
2797        if ( strcmp(type,"person") == 0 || strcmp(type,"role") == 0 )
2798            {
2799          old_name = get_attr_list(old_object, type);
2800          new_name = get_attr_list(new_object, type);
2801 
2802          if(old_name != NULL && new_name != NULL
2803              && g_list_nth(old_name, 0) != NULL && g_list_nth(new_name, 0) != NULL
2804              && (g_list_nth(old_name, 0)->data) != NULL
2805              && (g_list_nth(new_name, 0)->data) != NULL)
2806          {
2807 
2808            name_old = rpsl_attr_get_clean_value((rpsl_attr_t *)(g_list_nth(old_name, 0)->data));
2809            name_new = rpsl_attr_get_clean_value((rpsl_attr_t *)(g_list_nth(new_name, 0)->data));
2810                    rpsl_attr_delete_list(old_name);
2811                    rpsl_attr_delete_list(new_name);
2812 
2813            if ( strcmp(name_old, name_new) )
2814                    {
2815              free(name_old); free(name_new);
2816              return UP_NAM; /* name of a person/role object can't be changed */
2817            }
2818            free(name_old);free(name_new);
2819          }
2820                  else
2821                  {
2822                    rpsl_attr_delete_list(old_name);
2823                    rpsl_attr_delete_list(new_name);
2824            return UP_INT; /* there was a problem with obtaining the name of person obj */
2825          }
2826        }
2827       
2828        old_mntners = get_mntners(old_object);
2829        old_auth_vector = get_auth_vector(old_mntners);
2830        if (old_mntners != NULL && old_auth_vector == NULL)
2831            {
2832          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2833                  rpsl_attr_delete_list(old_mntners);
2834          return UP_AUF; /* auth failed */
2835        }
2836        if (old_auth_vector)
2837            { /* if we have mntners in the old object, use them */
2838          auth_return = authorise(old_auth_vector, credentials, overriden);
2839              g_slist_free(old_auth_vector);
2840              return auth_return;
2841        }
2842            else
2843            {
2844          new_mntners = get_mntners(new_object);
2845          new_auth_vector = get_auth_vector(new_mntners);
2846          if (new_mntners != NULL && new_auth_vector == NULL)
2847                  {
2848            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2849                    rpsl_attr_delete_list(new_mntners);
2850            return UP_AUF; /* auth failed */
2851          }
2852          auth_return = authorise(new_auth_vector, credentials, overriden);
2853                  if (new_auth_vector)
2854                g_slist_free(new_auth_vector);
2855              return auth_return;
2856        }
2857      }
2858          else
2859          { /* both are NULL, mustn't happen */
2860          if (tracing)
2861                  {
2862            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
2863          }
2864          return UP_INT; /* internal error */
2865      }
2866    }
2867 
2868    /*  
2869     *  Handle the "aut-num" type 
2870     */
2871    else if (strcmp(type,"aut-num")  == 0 )
2872    {
2873      if ( new_object == NULL && old_object != NULL )
2874          { /* the object is to be deleted */
2875        old_mntners = get_mntners(old_object);
2876        old_auth_vector = get_auth_vector(old_mntners);
2877        if (old_mntners != NULL && old_auth_vector == NULL)
2878            {
2879          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2880                  rpsl_attr_delete_list(old_mntners);
2881          return UP_AUF; /* auth failed */
2882        }
2883        auth_return = authorise(old_auth_vector, credentials, overriden);
2884            g_slist_free(old_auth_vector);
2885            return auth_return;
2886      }
2887          else if ( new_object != NULL && old_object == NULL )
2888          { /* the object is to be created */
2889        as_block_object_str = get_as_block(new_object);
2890        if (as_block_object_str == NULL )
2891            {
2892          return UP_ABN; /* As-block does not exist */
2893        } 
2894            else
2895            {
2896              as_block_obj = rpsl_object_init(as_block_object_str);
2897                  if (tracing)
2898                  {
2899            if ( rpsl_object_has_error(as_block_obj, RPSL_ERRLVL_ERROR) )
2900                    {
2901                          /* thre was an error during the parsing */
2902                          name = rpsl_object_get_class(as_block_obj);
2903                          if ( name )
2904                          {
2905                            attr = rpsl_object_get_attr(as_block_obj, name);
2906                            if ( attr )
2907                            {
2908                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
2909                                  if ( value )
2910                                  {
2911                            printf("TRACING: get_mnt_routes_from_list: error parsing as_block object %s\n", value );
2912                                    free(value);
2913                                  }
2914                                  else
2915                            printf("TRACING: get_mnt_routes_from_list: error parsing as_block object\n");
2916 
2917                                  rpsl_attr_delete_list(attr);
2918                            }
2919                          }
2920                    }
2921                  }
2922 
2923          as_block_mnt_lowers = get_mnt_lowers(as_block_obj);
2924          as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
2925                  rpsl_object_delete(as_block_obj);
2926          if (as_block_mnt_lowers != NULL && as_block_auth_vector == NULL)
2927                  {
2928            /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
2929                    rpsl_attr_delete_list(as_block_mnt_lowers);
2930            return UP_AUF; /* auth failed */
2931          }
2932          auth_return = authorise(as_block_auth_vector, credentials, overriden);
2933          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
2934                  {
2935            saved_auth_return = auth_return;
2936            new_mntners = get_mntners(new_object);
2937            new_auth_vector = get_auth_vector(new_mntners);
2938            if(new_mntners != NULL && new_auth_vector == NULL)
2939                    {
2940              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2941                      rpsl_attr_delete_list(new_mntners);
2942              return UP_AUF; /* auth failed */
2943            }
2944            auth_return = authorise(new_auth_vector, credentials, overriden);
2945                    if (new_auth_vector)
2946                  g_slist_free(new_auth_vector);
2947            if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
2948              return UP_OKM;
2949            else
2950              return auth_return;
2951          }
2952                  else
2953                  {
2954            return UP_HOF; /* hierarchical auth failed */
2955          }
2956        }
2957      }
2958          else if( new_object != NULL && old_object != NULL )
2959          { /* this is an update */
2960        old_mntners = get_mntners(old_object);
2961        old_auth_vector = get_auth_vector(old_mntners);
2962        if (old_mntners != NULL && old_auth_vector == NULL)
2963            {
2964          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2965                  rpsl_attr_delete_list(old_mntners);
2966          return UP_AUF; /* auth failed */
2967        }
2968        if (old_auth_vector)
2969            { /* if we have mntners in the old object, use them */
2970          auth_return = authorise(old_auth_vector, credentials, overriden);
2971              g_slist_free(old_auth_vector);
2972              return auth_return;
2973        }
2974            else
2975            {
2976          new_mntners = get_mntners(new_object);
2977          new_auth_vector = get_auth_vector(new_mntners);
2978          if (new_mntners != NULL && new_auth_vector == NULL)
2979                  {
2980            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2981                    rpsl_attr_delete_list(new_mntners);
2982            return UP_AUF; /* auth failed */
2983          }
2984          auth_return = authorise(new_auth_vector, credentials, overriden);
2985                  if (new_auth_vector)
2986            g_slist_free(new_auth_vector);
2987              return auth_return;
2988        }
2989      }
2990          else
2991          { /* both are NULL, mustn't happen */
2992          if(tracing) 
2993                  {
2994            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
2995          } 
2996          return UP_INT; /* internal error */
2997      }
2998    } 
2999 
3000    /*  
3001     *  Handle the "mntner/as-block/irt" types 
3002     */
3003    else if (strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 || strcmp(type,"irt")  == 0 )
3004    {
3005      if ( new_object == NULL && old_object != NULL )
3006          { /* the object is to be deleted */
3007        old_mntners = get_mntners(old_object);
3008        old_auth_vector = get_auth_vector(old_mntners);
3009        if (old_mntners != NULL && old_auth_vector == NULL)
3010            {
3011          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3012                  rpsl_attr_delete_list(old_mntners);
3013          return UP_AUF; /* auth failed */
3014        }
3015        auth_return = authorise(old_auth_vector, credentials, overriden);
3016            g_slist_free(old_auth_vector);
3017            return auth_return;
3018      }
3019          else if ( new_object != NULL && old_object == NULL )
3020          { /* the object is to be created */
3021        if (overriden || test_mode)
3022            {
3023          return UP_AUTH_OK; 
3024        }
3025            else
3026            { /* If not overriden, must be forwarded to <HUMAILBOX> */
3027          if (tracing) 
3028                  {
3029            printf("TRACING: check_auth: '%s' creation requested\n", type);
3030          }
3031          return UP_FWD; /* must be forwarded to <HUMAILBOX> */
3032        }
3033      }
3034          else if ( new_object != NULL && old_object != NULL )
3035          { /* this is an update */
3036        old_mntners = get_mntners(old_object);
3037        old_auth_vector = get_auth_vector(old_mntners);
3038        if (old_mntners != NULL && old_auth_vector == NULL)
3039            {
3040          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3041                  rpsl_attr_delete_list(old_mntners);
3042          return UP_AUF; /* auth failed */
3043        }
3044        if (old_auth_vector)
3045            { /* if we have mntners in the old object, use them */
3046          auth_return = authorise(old_auth_vector, credentials, overriden);
3047              g_slist_free(old_auth_vector);
3048              return auth_return;
3049        }
3050            else
3051            {
3052          new_mntners = get_mntners(new_object);
3053          new_auth_vector = get_auth_vector(new_mntners);
3054          if (new_mntners != NULL && new_auth_vector == NULL)
3055                  {
3056            /* then, the mntners in 'new_mntners' do not exist. Problem. */
3057                    rpsl_attr_delete_list(new_mntners);
3058            return UP_AUF; /* auth failed */
3059          }
3060          auth_return = authorise(new_auth_vector, credentials, overriden);
3061                  if (new_auth_vector)
3062                g_slist_free(new_auth_vector);
3063              return auth_return;
3064        }
3065      }
3066          else
3067          { /* both are NULL, mustn't happen */
3068          if (tracing)
3069                  {
3070            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3071          }
3072          return UP_INT; /* internal error */
3073      }
3074    }
3075 
3076    /*  
3077     *  Handle the "inetnum/inet6num" types 
3078     */
3079    else if (strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 )
3080    {
3081      if ( new_object == NULL && old_object != NULL )
3082          { 
3083        /* the object is to be deleted */
3084        /* dont check for mnt-irt on deletion */
3085 
3086        /******* status check **********/
3087        status_result = up_check_status(new_object, old_object, type, overriden);
3088        if ( status_result != UP_AUTH_OK )
3089          return status_result;
3090        
3091        /******* mntner check **********/
3092        old_mntners = get_mntners(old_object);
3093        old_auth_vector = get_auth_vector(old_mntners);
3094        if (old_mntners != NULL && old_auth_vector == NULL)
3095            {
3096          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3097                  rpsl_attr_delete_list(old_mntners);
3098          return UP_AUF; /* auth failed */
3099        }
3100        auth_return = authorise(old_auth_vector, credentials, overriden);
3101            g_slist_free(old_auth_vector);
3102            return auth_return;
3103      }
3104          else if ( new_object != NULL && old_object == NULL )
3105          { 
3106        /* the object is to be created */
3107        /******* irt check **********/
3108            /* if an object is created with an mnt-irt attribute, then it must 
3109           pass the authorisation for the mnt-irt */
3110        new_irts = get_irts(new_object);
3111        new_auth_vector = get_irt_auth_vector(new_irts);
3112        if (new_irts != NULL && new_auth_vector == NULL)
3113            {
3114          /* then, the irts in 'new_irts' do not exist. Problem. */
3115                  rpsl_attr_delete_list(new_irts);
3116          return UP_AUF; /* auth failed */
3117        }
3118        auth_return = authorise(new_auth_vector, credentials, overriden);
3119            if (new_auth_vector)
3120              g_slist_free(new_auth_vector);
3121        rpsl_attr_delete_list(new_irts);
3122            if ( auth_return == UP_AUF || auth_return == UP_MFF || auth_return == UP_MIX )
3123            {
3124              return UP_HOF; /* hierarchical authorisation failed */
3125            }
3126 
3127        /* get the one less specific inet(6)num object */
3128        less_specific_object_str = get_specific(new_object, type, "-l");
3129        if (less_specific_object_str == NULL)
3130            {
3131          /* there is no less specific object, fail if not overriden */
3132          if ( ! overriden )
3133                  {
3134            return UP_HOF; /* hierarchical authorisation failed */
3135          }
3136        }
3137            else
3138            { /* we got a less specific inet(6)num object */
3139              less_specific_obj = rpsl_object_init(less_specific_object_str);
3140              error_list = rpsl_object_errors(less_specific_obj);
3141                  if (tracing)
3142                  {
3143            if ( rpsl_object_has_error(less_specific_obj, RPSL_ERRLVL_ERROR) )
3144                    {
3145                          /* thre was an error during the parsing */
3146                          name = rpsl_object_get_class(less_specific_obj);
3147                          if ( name )
3148                          {
3149                            attr = rpsl_object_get_attr(less_specific_obj, name);
3150                            if ( attr )
3151                            {
3152                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3153                                  if ( value )
3154                                  {
3155                            printf("TRACING: check_auth: error parsing object %s\n", value );
3156                                    free(value);
3157                                  }
3158                                  else
3159                            printf("TRACING: check_auth: error parsing object\n");
3160 
3161                                  rpsl_attr_delete_list(attr);
3162                            }
3163                          }
3164                    }
3165                  }
3166 
3167          /******* status check **********/
3168          status_result = up_check_status(new_object, old_object, type, overriden);
3169          if ( status_result != UP_AUTH_OK )
3170          {
3171                    rpsl_object_delete(less_specific_obj);
3172            return status_result;
3173          }
3174 
3175          /******* less_specific check **********/
3176          less_specific_mnt_lowers = get_mnt_lowers(less_specific_obj);
3177          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
3178                  rpsl_object_delete(less_specific_obj);
3179 
3180          if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
3181                  {
3182            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
3183                    rpsl_attr_delete_list(less_specific_mnt_lowers);
3184            return UP_AUF; /* auth failed */
3185          }
3186          auth_return = authorise(less_specific_auth_vector, credentials, overriden);
3187          if (less_specific_auth_vector != NULL)
3188          {
3189                    g_slist_free(less_specific_auth_vector);
3190          }
3191          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3192                  {
3193            /******* mntner check **********/
3194            new_mntners = get_mntners(new_object);
3195            new_auth_vector = get_auth_vector(new_mntners);
3196            if (new_mntners != NULL && new_auth_vector == NULL)
3197                    {
3198              /* then, the mntners in 'new_mntners' do not exist. Problem. */
3199                      rpsl_attr_delete_list(new_mntners);
3200              return UP_AUF; /* auth failed */
3201            }
3202            auth_return = authorise(new_auth_vector, credentials, overriden);
3203                    if (new_auth_vector)
3204                  g_slist_free(new_auth_vector);
3205                return auth_return;
3206          }
3207                  else
3208                  {
3209            return UP_HOF; /* hierarchical authorisation failed */
3210          }
3211        }
3212      }
3213          else if ( new_object != NULL && old_object != NULL )
3214          { 
3215        /* this is an update */
3216        /******* status check **********/
3217        status_result = up_check_status(new_object, old_object, type, overriden);
3218        if ( status_result != UP_AUTH_OK )
3219          return status_result;
3220 
3221        /******* irt check **********/
3222            /* check for mnt-irt in both old and new object */
3223        /* it only needs to pass the authorisation of an mnt-irt when the
3224           mnt-irt is first added to the object */
3225        old_irts = get_irts(old_object);
3226        new_irts = get_irts(new_object);
3227        /* find irts that have just been added to this object */
3228        changed_irts = NT_compare_lists(old_irts, new_irts, 2);  /* 2 means 'just added' */
3229        
3230        changed_auth_vector = get_irt_auth_vector(changed_irts);
3231        if (changed_irts != NULL && changed_auth_vector == NULL)
3232            {
3233          /* then, the irts in 'changed_irts' do not exist. Problem. */
3234          rpsl_attr_delete_list(old_irts);
3235          rpsl_attr_delete_list(new_irts);
3236          return UP_AUF; /* auth failed */
3237        }
3238        auth_return = authorise(changed_auth_vector, credentials, overriden);
3239            g_slist_free(changed_auth_vector);
3240        rpsl_attr_delete_list(old_irts);
3241        rpsl_attr_delete_list(new_irts);
3242            if ( auth_return == UP_AUF || auth_return == UP_MFF || auth_return == UP_MIX)
3243            {
3244              return UP_HOF; /* hierarchical authorisation failed */
3245            }
3246 
3247        /******* mntner check **********/
3248        old_mntners = get_mntners(old_object);
3249        old_auth_vector = get_auth_vector(old_mntners);
3250        if (old_mntners != NULL && old_auth_vector == NULL)
3251            {
3252          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3253                  rpsl_attr_delete_list(old_mntners);
3254          return UP_AUF; /* auth failed */
3255        }
3256        if (old_auth_vector)
3257            { /* if we have mntners in the old object, use them */
3258          auth_return = authorise(old_auth_vector, credentials, overriden);
3259              g_slist_free(old_auth_vector);
3260              return auth_return;
3261        }
3262            else
3263            {
3264          new_mntners = get_mntners(new_object);
3265          new_auth_vector = get_auth_vector(new_mntners);
3266          if (new_mntners != NULL && new_auth_vector == NULL)
3267                  {
3268            /* then, the mntners in 'new_mntners' do not exist. Problem. */
3269                    rpsl_attr_delete_list(new_mntners);
3270            return UP_AUF; /* auth failed */
3271          }
3272          auth_return = authorise(new_auth_vector, credentials, overriden);
3273                  if (new_auth_vector)
3274                g_slist_free(new_auth_vector);
3275              return auth_return;
3276        }
3277      }
3278          else
3279          { /* both are NULL, mustn't happen */
3280          if (tracing)
3281                  {
3282            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3283          }
3284          return UP_INT; /* internal error */
3285      }
3286    }
3287    
3288    /*  
3289     *  Handle the "domain" type 
3290     */
3291    else if (strcmp(type,"domain")  == 0)
3292    {
3293      if ( new_object == NULL && old_object != NULL )
3294          { /* the object is to be deleted */
3295        old_mntners = get_mntners(old_object);
3296        old_auth_vector = get_auth_vector(old_mntners);
3297        if (old_mntners != NULL && old_auth_vector == NULL)
3298            {
3299          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3300                  rpsl_attr_delete_list(old_mntners);
3301          return UP_AUF; /* auth failed */
3302        }
3303        auth_return = authorise(old_auth_vector, credentials, overriden);
3304            g_slist_free(old_auth_vector);
3305            return auth_return;
3306      }
3307          else if ( new_object != NULL && old_object == NULL )
3308          { /* the object is to be created */
3309        /* now, we have to find a 'less specific domain object' for this. 
3310           If there is no less specific object, then creation is possible
3311           only with overriding. */
3312       less_specific_domain_str = get_less_specific_domain(new_object);
3313       if (less_specific_domain_str == NULL)
3314           {
3315         if (overriden)
3316                 {/* we didn't get a 'less specific' domain object */
3317            return UP_AUTH_OK; 
3318          }
3319                  else
3320                  {
3321            return UP_HOF; /* hierarchical authorisation failed */
3322          }
3323       }
3324           else
3325           { /* we get a 'less specific' domain object */
3326              less_specific_domain_obj = rpsl_object_init(less_specific_domain_str);
3327                  if (tracing)
3328                  {
3329            if ( rpsl_object_has_error(less_specific_domain_obj, RPSL_ERRLVL_ERROR) )
3330                    {
3331                          /* thre was an error during the parsing */
3332                          name = rpsl_object_get_class(less_specific_domain_obj);
3333                          if ( name )
3334                          {
3335                            attr = rpsl_object_get_attr(less_specific_domain_obj, name);
3336                            if ( attr )
3337                            {
3338                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3339                                  if ( value )
3340                                  {
3341                            printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3342                                    free(value);
3343                                  }
3344                                  else
3345                            printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3346 
3347                                  rpsl_attr_delete_list(attr);
3348                            }
3349                          }
3350                    }
3351                  }
3352 
3353          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain_obj);
3354          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
3355          rpsl_object_delete(less_specific_domain_obj);
3356 
3357          if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
3358                  {
3359            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
3360                    rpsl_attr_delete_list(less_specific_mnt_lowers);
3361            return UP_AUF; /* auth failed */
3362          }
3363          auth_return = authorise(less_specific_auth_vector, credentials, overriden);
3364          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3365                  {
3366            saved_auth_return = auth_return;
3367            new_mntners = get_mntners(new_object);
3368            new_auth_vector = get_auth_vector(new_mntners);
3369            if (new_mntners != NULL && new_auth_vector == NULL)
3370                    {
3371              /* then, the mntners in 'new_mntners' do not exist. Problem. */
3372                      rpsl_attr_delete_list(new_mntners);
3373              return UP_AUF; /* auth failed */
3374            }
3375            auth_return = authorise(new_auth_vector, credentials, overriden);
3376                    if (new_auth_vector)
3377                  g_slist_free(new_auth_vector);
3378            if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM )
3379              return UP_OKM;
3380            else
3381                  return auth_return;
3382          }
3383                  else
3384                  {
3385            return UP_HOF; /* hierarchical authorisation failed */
3386          }
3387       }
3388      }
3389          else if ( new_object != NULL && old_object != NULL )
3390          { /* this is an update */
3391        old_mntners = get_mntners(old_object);
3392        old_auth_vector = get_auth_vector(old_mntners);
3393        if (old_mntners != NULL && old_auth_vector == NULL)
3394            {
3395          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3396                  rpsl_attr_delete_list(old_mntners);
3397          return UP_AUF; /* auth failed */
3398        }
3399        if (old_auth_vector)
3400            { /* if we have mntners in the old object, use them */
3401          auth_return = authorise(old_auth_vector, credentials, overriden);
3402              g_slist_free(old_auth_vector);
3403              return auth_return;
3404        }
3405            else
3406            {
3407          new_mntners = get_mntners(new_object);
3408          new_auth_vector = get_auth_vector(new_mntners);
3409          if (new_mntners != NULL && new_auth_vector == NULL)
3410                  {
3411            /* then, the mntners in 'new_mntners' do not exist. Problem. */
3412                    rpsl_attr_delete_list(new_mntners);
3413            return UP_AUF; /* auth failed */
3414          }
3415          auth_return = authorise(new_auth_vector, credentials, overriden);
3416                  if (new_auth_vector)
3417                g_slist_free(new_auth_vector);
3418              return auth_return;
3419        }
3420      }
3421          else
3422          { /* both are NULL, mustn't happen */
3423          if (tracing)
3424                  {
3425            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3426          }
3427          return UP_INT; /* internal error */
3428      }
3429    }
3430    
3431 
3432    /*  
3433     *  Handle the "route" type 
3434     */
3435    else if (strcmp(type,"route")  == 0)
3436    {
3437      if ( new_object == NULL && old_object != NULL )
3438          { /* the object is to be deleted */
3439        old_mntners = get_mntners(old_object);
3440        old_auth_vector = get_auth_vector(old_mntners);
3441        if (old_mntners != NULL && old_auth_vector == NULL)
3442            {
3443          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3444                  rpsl_attr_delete_list(old_mntners);
3445          return UP_AUF; /* auth failed */
3446        }
3447        auth_return = authorise(old_auth_vector, credentials, overriden);
3448            g_slist_free(old_auth_vector);
3449            return auth_return;
3450      } 
3451          else if ( new_object != NULL && old_object == NULL )
3452          { /* the object is to be created */
3453        /* first we have to find the aut-num object mentioned in the 
3454           origin attribute */
3455 
3456        aut_num_object_str = get_aut_num_object(new_object); 
3457        if (aut_num_object_str == NULL)
3458            {
3459          if (overriden)
3460                  {
3461            return UP_AUTH_OK; 
3462          }
3463                  else
3464                  {
3465            return UP_HOF; /* hierarchical authorisation failed */
3466          }
3467        }
3468            else
3469            { /* there is a corresponding aut-num in the db */
3470          if (tracing)
3471                  {
3472            printf("TRACING: check_auth: will try to authorise the route using aut-num\n");
3473          }
3474              aut_num_obj = rpsl_object_init(aut_num_object_str);
3475                  if (tracing)
3476                  {
3477            if ( rpsl_object_has_error(aut_num_obj, RPSL_ERRLVL_ERROR) )
3478                    {
3479                          /* thre was an error during the parsing */
3480                          name = rpsl_object_get_class(aut_num_obj);
3481                          if ( name )
3482                          {
3483                            attr = rpsl_object_get_attr(aut_num_obj, name);
3484                            if ( attr )
3485                            {
3486                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3487                                  if ( value )
3488                                  {
3489                            printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3490                                    free(value);
3491                                  }
3492                                  else
3493                            printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3494 
3495                                  rpsl_attr_delete_list(attr);
3496                            }
3497                          }
3498                    }
3499                  }
3500 
3501          aut_num_maintainers = get_mnt_routes(aut_num_obj);
3502          if (aut_num_maintainers != NULL)
3503                  {
3504            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
3505            auth_return = authorise(aut_num_auth_vector, credentials, overriden);
3506            if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3507                    {
3508              aut_num_auth_OK = TRUE;
3509            }
3510                    else
3511                    {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
3512                      rpsl_attr_delete_list(aut_num_maintainers);
3513              return UP_HOF;
3514            }
3515          }
3516                  else
3517                  {/* aut_num_maintainers is NULL */
3518             aut_num_maintainers = get_mnt_lowers(aut_num_obj);
3519             if (aut_num_maintainers != NULL)
3520                         {
3521               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
3522               auth_return = authorise(aut_num_auth_vector, credentials, overriden);
3523               if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3524                           {
3525                 aut_num_auth_OK = TRUE;
3526               }
3527                           else
3528                           {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
3529                         rpsl_attr_delete_list(aut_num_maintainers);
3530                 return UP_HOF; /* hierarchical authorisation failed */
3531               }
3532             }
3533                         else
3534                         {/* aut_num_maintainers is NULL */
3535               aut_num_maintainers = get_mntners(aut_num_obj);
3536               if (aut_num_maintainers != NULL)
3537                           {
3538                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
3539                 auth_return = authorise(aut_num_auth_vector, credentials, overriden);
3540                 if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3541                                 {
3542                   aut_num_auth_OK = TRUE;
3543                 }
3544                                 else
3545                                 {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
3546                           rpsl_attr_delete_list(aut_num_maintainers);
3547                   return UP_HOF; /* hierarchical authorisation failed */
3548                 }
3549               }
3550                           else
3551                           {/* aut_num_maintainers is NULL */
3552                 aut_num_auth_OK = TRUE;
3553               }
3554               
3555             }
3556          }
3557          rpsl_object_delete(aut_num_obj);
3558 
3559          if (aut_num_auth_OK)
3560                  {
3561            /* now, we have to find an exact match for this route object. 
3562               If there is no exact match object, then we will go on to find
3563               less specific. */
3564            exact_match_routes_str = get_exact_match_routes(new_object);
3565            if (exact_match_routes_str != NULL)
3566                    {
3567              /* there are one or more exact match routes */
3568              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes_str);
3569              if ( exact_match_routes_maintainers )
3570              {
3571                /* the exact match(s) has some mnt-routes */
3572                exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
3573                if (exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL)
3574                            {
3575                  /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
3576                          rpsl_attr_delete_list(exact_match_routes_maintainers);
3577                  return UP_AUF; /* auth failed */
3578                }
3579                auth_return = authorise(exact_match_routes_auth_vector, credentials, overriden);
3580              }
3581              else
3582              {
3583                /* no mnt-routes so check the mnt-by of the exact match */
3584                exact_match_maintainers = get_mntners_from_list(exact_match_routes_str);
3585                exact_match_auth_vector = get_auth_vector(exact_match_maintainers);
3586                if (exact_match_maintainers != NULL && exact_match_auth_vector == NULL)
3587                            {
3588                  /* then, the mntners in 'exact_match_maintainers' do not exist. Problem. */
3589                          rpsl_attr_delete_list(exact_match_maintainers);
3590                  return UP_AUF; /* auth failed */
3591                }
3592                auth_return = authorise(exact_match_auth_vector, credentials, overriden);
3593              }
3594              if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3595                          {
3596                saved_auth_return = auth_return;
3597                /* then, check mnt_bys of the route itself */
3598                new_mntners = get_mntners(new_object);
3599                new_auth_vector = get_auth_vector(new_mntners);
3600                if (new_mntners != NULL && new_auth_vector == NULL)
3601                            {
3602                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
3603                          rpsl_attr_delete_list(new_mntners);
3604                  return UP_AUF; /* auth failed */
3605                }
3606                auth_return = authorise(new_auth_vector, credentials, overriden);
3607                        if (new_auth_vector)
3608                      g_slist_free(new_auth_vector);
3609                if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3610                  return UP_OKM;
3611                else
3612                      return auth_return;
3613              }
3614                          else
3615                          { /*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
3616                return UP_HOF; /* hierarchical authorisation failed */
3617              }
3618            }
3619                    else
3620                    { /* exact_match_routes == NULL */
3621              /* then we have to look for less specific route objs */
3622              less_spec_routes_str = get_less_spec_routes(new_object);
3623              if (less_spec_routes_str != NULL)
3624                          {
3625                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes_str);
3626                less_spec_routes_mntners = g_list_concat(less_spec_routes_mntners, 
3627                                              get_mnt_lowers_from_list(less_spec_routes_str));
3628                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
3629                if (less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL)
3630                            {
3631                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
3632                          rpsl_attr_delete_list(less_spec_routes_mntners);
3633                  return UP_AUF; /* auth failed */
3634                }
3635                if ( less_spec_routes_mntners != NULL )
3636                {
3637                  auth_return = authorise(less_spec_routes_auth_vector, credentials, overriden);
3638                  if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3639                              {
3640                    saved_auth_return = auth_return;
3641                    /* then, check mnt_bys of the route itself */
3642                    new_mntners = get_mntners(new_object);
3643                    new_auth_vector = get_auth_vector(new_mntners);
3644                    if (new_mntners != NULL && new_auth_vector == NULL)
3645                                    {
3646                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3647                              rpsl_attr_delete_list(new_mntners);
3648                      return UP_AUF; /* auth failed */
3649                    }
3650                    auth_return = authorise(new_auth_vector, credentials, overriden);
3651                            if (new_auth_vector)
3652                          g_slist_free(new_auth_vector);
3653                    if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM )
3654                      return UP_OKM;
3655                    else
3656                          return auth_return;
3657                  }
3658                              else
3659                              { /*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
3660                    return UP_HOF; /* hierarchical authorisation failed */
3661                  }
3662                }
3663                else
3664                {
3665                  /* there are no mnt-routes or mnt-lower in less specific route objs */
3666                  /* check mnt-by of less specific route objs */
3667                  less_spec_routes_mntners = get_mntners_from_list(less_spec_routes_str);
3668                  less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
3669                  if (less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL)
3670                              {
3671                    /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
3672                            rpsl_attr_delete_list(less_spec_routes_mntners);
3673                    return UP_AUF; /* auth failed */
3674                  }
3675                  auth_return = authorise(less_spec_routes_auth_vector, credentials, overriden);
3676                  if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3677                              {
3678                    saved_auth_return = auth_return;
3679                    /* then, check mnt_bys of the route itself */
3680                    new_mntners = get_mntners(new_object);
3681                    new_auth_vector = get_auth_vector(new_mntners);
3682                    if (new_mntners != NULL && new_auth_vector == NULL)
3683                                    {
3684                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3685                              rpsl_attr_delete_list(new_mntners);
3686                      return UP_AUF; /* auth failed */
3687                    }
3688                    auth_return = authorise(new_auth_vector, credentials, overriden);
3689                            if (new_auth_vector)
3690                          g_slist_free(new_auth_vector);
3691                    if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3692                      return UP_OKM;
3693                    else
3694                          return auth_return;
3695                  }
3696                              else
3697                              { /*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
3698                    return UP_HOF; /* hierarchical authorisation failed */
3699                  }
3700                }
3701              }
3702                          else
3703                          {  /* less_spec_routes == NULL */
3704                /* so, we have to get the exact match inetnum */
3705                exact_match_inetnum_str = get_exact_match_inetnum(new_object);
3706                if (exact_match_inetnum_str != NULL)
3707                            {
3708                                  exact_match_inetnum_obj = rpsl_object_init(exact_match_inetnum_str);
3709                                  if (tracing)
3710                                  {
3711                            if ( rpsl_object_has_error(exact_match_inetnum_obj, RPSL_ERRLVL_ERROR) )
3712                                    {
3713                                          /* thre was an error during the parsing */
3714                                          name = rpsl_object_get_class(exact_match_inetnum_obj);
3715                                          if ( name )
3716                                          {
3717                                            attr = rpsl_object_get_attr(exact_match_inetnum_obj, name);
3718                                            if ( attr )
3719                                            {
3720                                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3721                                                  if ( value )
3722                                                  {
3723                                            printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3724                                                    free(value);
3725                                                  }
3726                                                  else
3727                                            printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3728 
3729                                                  rpsl_attr_delete_list(attr);
3730                                            }
3731                                          }
3732                                    }
3733                                  }
3734 
3735                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum_obj);
3736                                  exact_match_inetnum_mnt_bys = get_mntners(exact_match_inetnum_obj);
3737                                  rpsl_object_delete(exact_match_inetnum_obj);
3738 
3739                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
3740                  if (exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL)
3741                                  {
3742                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
3743                            rpsl_attr_delete_list(exact_match_inetnum_mnt_routes);
3744                    return UP_AUF; /* auth failed */
3745                  }
3746 
3747                                  /* if there are mnt_routes in the exact match inetnum */
3748                                  if (exact_match_inetnum_mnt_routes != NULL)
3749                                  {
3750                                    auth_return = authorise(exact_match_inetnum_auth_vector, credentials, overriden);
3751                                    if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3752                                    {
3753                      saved_auth_return = auth_return;
3754                                          /* then, check mnt_bys of the route itself */
3755                                          new_mntners = get_mntners(new_object);
3756                                          new_auth_vector = get_auth_vector(new_mntners);
3757                                          if (new_mntners != NULL && new_auth_vector == NULL)
3758                                          {
3759                                            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3760                                rpsl_attr_delete_list(new_mntners);
3761                                            return UP_AUF; /* auth failed */
3762                                          }
3763                      auth_return = authorise(new_auth_vector, credentials, overriden);
3764                              if (new_auth_vector)
3765                            g_slist_free(new_auth_vector);
3766                      if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3767                        return UP_OKM;
3768                      else
3769                            return auth_return;
3770                                    }
3771                                    else
3772                                    {
3773                                          return UP_HOF; /* hierarchical authorisation failed */
3774                                    }
3775                                  }
3776                                  else
3777                                  { /* if there was no mnt_routes in the exact match inetnum, then use mnt-by of it */
3778                                    exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_bys);
3779                                    if (exact_match_inetnum_mnt_bys != NULL && exact_match_inetnum_auth_vector == NULL)
3780                                    {
3781                                          /* then, the mntners in 'exact_match_inetnum_mnt_bys' do not exist. Problem. */
3782                              rpsl_attr_delete_list(exact_match_inetnum_mnt_bys);
3783                      return UP_AUF; /* auth failed */
3784                    }
3785                    
3786                    /* check mnt-by of exact match inetnum */
3787                    auth_return = authorise(exact_match_inetnum_auth_vector, credentials, overriden);
3788                    if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3789                                    {
3790                      saved_auth_return = auth_return;
3791                      /* then, check mnt_bys of the route itself */
3792                      new_mntners = get_mntners(new_object);
3793                      new_auth_vector = get_auth_vector(new_mntners);
3794                      if (new_mntners != NULL && new_auth_vector == NULL)
3795                                      {
3796                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3797                                rpsl_attr_delete_list(new_mntners);
3798                        return UP_AUF; /* auth failed */
3799                      }
3800                      auth_return = authorise(new_auth_vector, credentials, overriden);
3801                              if (new_auth_vector)
3802                            g_slist_free(new_auth_vector);
3803                      if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3804                        return UP_OKM;
3805                      else
3806                            return auth_return;
3807                    }
3808                                    else
3809                                    {
3810                      return UP_HOF; /* hierarchical authorisation failed */
3811                    }
3812                  }
3813                }
3814                            else
3815                            {/* exact_match_inetnum == NULL */
3816                  /* then, we will try to find less spec inetnums */
3817                  less_spec_inetnum_str = get_less_spec_inetnum(new_object);
3818                  if (less_spec_inetnum_str != NULL)
3819                                  {
3820                                    less_spec_inetnum_obj = rpsl_object_init(less_spec_inetnum_str);
3821                                    if (tracing)
3822                                    {
3823                                  if ( rpsl_object_has_error(less_spec_inetnum_obj, RPSL_ERRLVL_ERROR) )
3824                                          {
3825                                            /* thre was an error during the parsing */
3826                                            name = rpsl_object_get_class(less_spec_inetnum_obj);
3827                                            if ( name )
3828                                            {
3829                                                  attr = rpsl_object_get_attr(less_spec_inetnum_obj, name);
3830                                                  if ( attr )
3831                                                  {
3832                                            value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3833                                                    if ( value )
3834                                                    {
3835                                                  printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3836                                                          free(value);
3837                                                    }
3838                                                    else
3839                                                  printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3840 
3841                                                    rpsl_attr_delete_list(attr);
3842                                                  }
3843                                            }
3844                                          }
3845                                    }
3846 
3847                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum_obj);
3848                    less_spec_inetnum_mntners = g_list_concat(less_spec_inetnum_mntners, 
3849                                   get_mnt_lowers(less_spec_inetnum_obj));
3850                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
3851 
3852                                    less_spec_inetnum_mnt_bys = get_mntners(less_spec_inetnum_obj);
3853 
3854                                    rpsl_object_delete(less_spec_inetnum_obj);
3855 
3856                    if (less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL)
3857                                    {
3858                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
3859                              rpsl_attr_delete_list(less_spec_inetnum_mntners);
3860                      return UP_AUF; /* auth failed */
3861                    }
3862                                    if (less_spec_inetnum_mntners != NULL)
3863                                    { /* if there are mntners in mnt-lower and/or mnt-routes */
3864                                          auth_return = authorise(less_spec_inetnum_auth_vector, credentials, overriden);
3865                                          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3866                                          {
3867                        saved_auth_return = auth_return;
3868                                            /* then, check mnt_bys of the route itself */
3869                                            new_mntners = get_mntners(new_object);
3870                                            new_auth_vector = get_auth_vector(new_mntners);
3871                                            if (new_mntners != NULL && new_auth_vector == NULL)
3872                                            {
3873                                                  /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3874                                  rpsl_attr_delete_list(new_mntners);
3875                                                  return UP_AUF; /* auth failed */
3876                                            }
3877                        auth_return = authorise(new_auth_vector, credentials, overriden);
3878                                if (new_auth_vector)
3879                              g_slist_free(new_auth_vector);
3880                        if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3881                          return UP_OKM;
3882                        else
3883                              return auth_return;
3884                                          }
3885                                          else
3886                                          { /* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
3887                                            return UP_HOF; /* hierarchical authorisation failed */
3888                                          }
3889                                    }
3890                                    else
3891                                    { /* there isn't any mnt-lower or mnt-routes in the less spec inetnum */
3892                                                  /* so we must use mnt-by of less spec inetum */
3893                                          less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mnt_bys);
3894                                          if (less_spec_inetnum_mnt_bys != NULL && less_spec_inetnum_auth_vector == NULL)
3895                                          {
3896                                            /* then, the mntners in 'less_spec_inetnum_mnt_bys' do not exist. Problem. */
3897 
3898                                rpsl_attr_delete_list(less_spec_inetnum_mnt_bys);
3899                        return UP_AUF; /* auth failed */
3900                      }
3901                                          auth_return = authorise(less_spec_inetnum_auth_vector, credentials, overriden);
3902                                          if (auth_return == UP_AUTH_OK  ||  auth_return == UP_OKM)
3903                                          {
3904                        saved_auth_return = auth_return;
3905                                            /* then, check mnt_bys of the route itself */
3906                                            new_mntners = get_mntners(new_object);
3907                                            new_auth_vector = get_auth_vector(new_mntners);
3908                                            if (new_mntners != NULL && new_auth_vector == NULL)
3909                                            {
3910                                                  /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3911                                  rpsl_attr_delete_list(new_mntners);
3912                                                  return UP_AUF; /* auth failed */
3913                                            }
3914                        auth_return = authorise(new_auth_vector, credentials, overriden);
3915                                if (new_auth_vector)
3916                              g_slist_free(new_auth_vector);
3917                        if (auth_return == UP_AUTH_OK  && saved_auth_return == UP_OKM)
3918                          return UP_OKM;
3919                        else
3920                              return auth_return;
3921                                          }
3922                                          else
3923                                          {
3924                                            return UP_HOF; /* hierarchical authorisation failed */
3925                                          }
3926                    }
3927                  }
3928                                  else
3929                                  {/* less_spec_inetnum == NULL */
3930                    /* now that we couldn't find any route or inetnum object
3931                       to be used in authentication. So, only if the auth is
3932                       overriden the object will be created. */
3933                    if (overriden)
3934                                    {
3935                      return UP_AUTH_OK; 
3936                    }
3937                                    else
3938                                    {
3939                      return UP_HOF; /* hierarchical authorisation failed */
3940                    }
3941                  }
3942                }
3943              }
3944            }
3945          }
3946                  else
3947                  {/* ! aut_num_auth_OK */
3948            return UP_HOF; /* hierarchical auth failed */
3949          }
3950        }
3951           
3952      }
3953          else if ( new_object != NULL && old_object != NULL )
3954          { /* this is an update */
3955        old_mntners = get_mntners(old_object);
3956        old_auth_vector = get_auth_vector(old_mntners);
3957        if (old_mntners != NULL && old_auth_vector == NULL)
3958            {
3959          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
3960                  rpsl_attr_delete_list(old_mntners);
3961          return UP_AUF; /* auth failed */
3962        }
3963        if (old_auth_vector)
3964            { /* if we have mntners in the old object, use them */
3965          auth_return = authorise(old_auth_vector, credentials, overriden);
3966              g_slist_free(old_auth_vector);
3967              return auth_return;
3968        }
3969            else
3970            {
3971          new_mntners = get_mntners(new_object);
3972          new_auth_vector = get_auth_vector(new_mntners);
3973          if (new_mntners != NULL && new_auth_vector == NULL)
3974                  {
3975            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3976                    rpsl_attr_delete_list(new_mntners);
3977            return UP_AUF; /* auth failed */
3978          }
3979          auth_return = authorise(new_auth_vector, credentials, overriden);
3980                  if (new_auth_vector)
3981                g_slist_free(new_auth_vector);
3982              return auth_return;
3983        }
3984      }
3985          else
3986          { /* both are NULL, mustn't happen */
3987          if (tracing)
3988                  {
3989            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3990          }
3991          return UP_INT; /* internal error */
3992      }
3993    }
3994 
3995 
3996    /*  
3997     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types 
3998     */
3999    else if (strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
4000            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
4001            strcmp(type,"route-set")    == 0 )
4002    {
4003      if ( new_object == NULL && old_object != NULL )
4004          { /* the object is to be deleted */
4005        old_mntners = get_mntners(old_object);
4006        old_auth_vector = get_auth_vector(old_mntners);
4007        if (old_mntners != NULL && old_auth_vector == NULL)
4008            {
4009          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
4010                  rpsl_attr_delete_list(old_mntners);
4011          return UP_AUF; /* auth failed */
4012        }
4013        auth_return = authorise(old_auth_vector, credentials, overriden);
4014            g_slist_free(old_auth_vector);
4015            return auth_return;
4016      }
4017          else if ( new_object != NULL && old_object == NULL )
4018          { /* the object is to be created */
4019         set_name = get_search_key(new_object, type);
4020        if (strstr(set_name,":") == NULL )
4021            { /* if the name is _not_ hierarchical */
4022          new_mntners = get_mntners(new_object);
4023          new_auth_vector = get_auth_vector(new_mntners);
4024          if (new_mntners != NULL && new_auth_vector == NULL)
4025                  {
4026            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
4027                    rpsl_attr_delete_list(new_mntners);
4028            return UP_AUF; /* auth failed */
4029          }
4030          auth_return = authorise(new_auth_vector, credentials, overriden);
4031                  if (new_auth_vector)
4032                g_slist_free(new_auth_vector);
4033              return auth_return;
4034        }
4035            else
4036            { /* the name is hierarchical */
4037          less_specific_object_str = get_less_specific_set(new_object, type);
4038          if (less_specific_object_str != NULL)
4039                  { /* such an object exists */
4040                    less_specific_obj = rpsl_object_init(less_specific_object_str);
4041                    if (tracing)
4042                    {
4043                  if ( rpsl_object_has_error(less_specific_obj, RPSL_ERRLVL_ERROR) )
4044                          {
4045                            /* thre was an error during the parsing */
4046                            name = rpsl_object_get_class(less_specific_obj);
4047                            if ( name )
4048                            {
4049                                  attr = rpsl_object_get_attr(less_specific_obj, name);
4050                                  if ( attr )
4051                                  {
4052                            value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
4053                                    if ( value )
4054                                    {
4055                                  printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
4056                                          free(value);
4057                                    }
4058                                    else
4059                                  printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
4060 
4061                                    rpsl_attr_delete_list(attr);
4062                                  }
4063                            }
4064                          }
4065                    }
4066 
4067            less_specific_object_type = rpsl_object_get_class(less_specific_obj);
4068 
4069            if (strcmp(less_specific_object_type, "aut-num") == 0)
4070                    { /* if this is an aut-num object */
4071              less_specific_mnt_lowers = get_mnt_lowers(less_specific_obj);
4072              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
4073              if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
4074                          {
4075                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
4076                       rpsl_attr_delete_list(less_specific_mnt_lowers);
4077               rpsl_object_delete(less_specific_obj);
4078               return UP_AUF; /* auth failed */
4079              }
4080              if (less_specific_auth_vector != NULL)
4081                          {
4082                auth_return = authorise(less_specific_auth_vector, credentials, overriden);
4083                    g_slist_free(less_specific_auth_vector);
4084                rpsl_object_delete(less_specific_obj);
4085                    return auth_return;
4086              }
4087                          else
4088                          { /* the less specific object doesn't contain any mnt-lower */
4089                less_specific_mntners = get_mntners(less_specific_obj);
4090                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
4091                if (less_specific_mntners != NULL && less_specific_auth_vector == NULL)
4092                            {
4093                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
4094                          rpsl_attr_delete_list(less_specific_mntners);
4095                  rpsl_object_delete(less_specific_obj);
4096                  return UP_AUF; /* auth failed */
4097                }
4098                if (less_specific_auth_vector != NULL)
4099                            {  /* less spec object has some mnt-by attribs, 
4100                                                         use them  */
4101                    auth_return = authorise(less_specific_auth_vector, credentials, overriden);
4102                        g_slist_free(less_specific_auth_vector);
4103                    rpsl_object_delete(less_specific_obj);
4104                        return auth_return;
4105                }
4106                            else
4107                            { /* the less specific object doesn't contain any mnt-by either */
4108                  if (overriden)
4109                                  {
4110                    rpsl_object_delete(less_specific_obj);
4111                    return UP_AUTH_OK; 
4112                  }
4113                                  else
4114                                  {
4115                    rpsl_object_delete(less_specific_obj);
4116                    return UP_HOF; /* hierarchical authorisation failed */
4117                  }
4118                }
4119              }
4120            }
4121                    else
4122                    { /* this is _not_ an aut-num object*/
4123              less_specific_mntners = get_mntners(less_specific_obj);
4124              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
4125              if (less_specific_mntners != NULL && less_specific_auth_vector == NULL)
4126                          {
4127                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
4128                        rpsl_attr_delete_list(less_specific_mntners);
4129                rpsl_object_delete(less_specific_obj);
4130                return UP_AUF; /* auth failed */
4131              }
4132              if (less_specific_auth_vector != NULL )
4133                          { /* the set obj has some mnt-by attribs */
4134                auth_return = authorise(less_specific_auth_vector, credentials, overriden);
4135                    g_slist_free(less_specific_auth_vector);
4136                rpsl_object_delete(less_specific_obj);
4137                    return auth_return;
4138              }
4139                          else
4140                          {
4141                if (overriden)
4142                            {
4143                  rpsl_object_delete(less_specific_obj);
4144                  return UP_AUTH_OK; 
4145                }
4146                            else
4147                            {
4148                  rpsl_object_delete(less_specific_obj);
4149                  return UP_HOF; /* hierarchical authorisation failed */
4150                }
4151              }
4152            }
4153          }
4154                  else
4155                  { /* we don't have a less specific of this set object in the DB  */
4156            return UP_HOF; /* hierarchical authorisation failed */
4157          }
4158        }
4159      }
4160          else if ( new_object != NULL && old_object != NULL )
4161          { /* this is an update */
4162        old_mntners = get_mntners(old_object);
4163        old_auth_vector = get_auth_vector(old_mntners);
4164        if (old_mntners != NULL && old_auth_vector == NULL)
4165            {
4166          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
4167                  rpsl_attr_delete_list(old_mntners);
4168          return UP_AUF; /* auth failed */
4169        }
4170        if (old_auth_vector)
4171            { /* if we have mntners in the old object, use them */
4172          auth_return = authorise(old_auth_vector, credentials, overriden);
4173              g_slist_free(old_auth_vector);
4174              return auth_return;
4175        }
4176            else
4177            {
4178          new_mntners = get_mntners(new_object);
4179          new_auth_vector = get_auth_vector(new_mntners);
4180          if (new_mntners != NULL && new_auth_vector == NULL)
4181                  {
4182            /* then, the mntners in 'new_mntners' do not exist. Problem. */
4183                    rpsl_attr_delete_list(new_mntners);
4184            return UP_AUF; /* auth failed */
4185          }
4186          auth_return = authorise(new_auth_vector, credentials, overriden);
4187                  if (new_auth_vector)
4188                g_slist_free(new_auth_vector);
4189              return auth_return;
4190        }
4191      }
4192          else
4193          { /* both are NULL, mustn't happen */
4194          if (tracing)
4195                  {
4196            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
4197          }
4198          return UP_INT; /* internal error */
4199      }
4200 
4201    }
4202    else
4203    { /* We exhausted all object classes. If we are here, then there is a problem */
4204      printf("check_auth: This type '%s' is unknown\n", type);
4205      return UP_NIY; /* not implemented yet */
4206    }
4207    return UP_AUF; /* if we come to this point, then auth failed */ 
4208 }
4209 
4210 
4211 
4212 /* Gets the old version of the given "arg" object, which is in char * format
4213    and returns the old version again in char * format */
4214 
4215 char * get_old_version(rpsl_object_t *object, char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
4216 {
4217     const char *type=NULL;
4218         char *lctype = NULL;
4219         char *primary_search_key = NULL, *search_string = NULL;
4220     char *result = NULL, *origin = NULL, *nic_hdl = NULL;
4221     
4222     type = rpsl_object_get_class(object);
4223         lctype = strdup(type);
4224         g_strdown(lctype);
4225 
4226     primary_search_key = get_search_key(object, lctype);
4227     if ( primary_search_key == NULL )
4228     {
4229       if(tracing)
4230       {
4231         printf("type=%s\n", type);
4232         printf("primary_search_key is NULL\n");
4233       }
4234           return NULL;
4235         }
4236 
4237     if(tracing) 
4238         {
4239       printf("TRACING: type= %s\n", type);
4240       printf("TRACING: primary_search_key= %s\n", primary_search_key);
4241     }
4242 
4243     /* if the object is a pn or a ro object, then get all pn/ro's with the same NIC hdl */
4244     if ( strcmp(lctype,"person") == 0 || strcmp(lctype,"role") == 0 )
4245         {
4246       /* prepare the search string */
4247       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T -s ")
4248                                           +strlen(current_source)+ strlen("person,role") + 2);
4249       sprintf(search_string, "-x -R -r -Tperson,role -s %s %s", current_source, primary_search_key);
4250     }
4251         else
4252         {
4253       /* prepare the search string */
4254       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T -s ")
4255                                           +strlen(current_source)+ strlen(lctype) + 2);
4256       sprintf(search_string, "-x -R -r -T%s -s %s %s",lctype, current_source, primary_search_key);
4257     }
4258         
4259     result = send_and_get(query_host, query_port, search_string);
4260     if(tracing) 
4261         {
4262       printf("TRACING: send_and_get returned with search %s result %s\n", search_string, result);
4263     }
4264         free(search_string);
4265         free(primary_search_key);
4266         if ( result == NULL )
4267           return NULL;
4268 
4269     /* and here, we must filter the 'result' with NIC handle */
4270     if ( strcmp(lctype,"person") == 0 )
4271         {
4272       if(tracing) 
4273           {
4274         printf("TRACING: This is a person\n");
4275       }
4276       /* if this is a person, then we must filter out the persons with different
4277          nic-hdl attributes (since it is possible to have this NIC hdl in the name
4278          of a person object, and whois will return that object too) */
4279       nic_hdl = get_search_key(object, "nic-hdl");
4280       if(tracing) 
4281           {
4282         printf("TRACING: Got nic-hdl of person: %s\n", nic_hdl);
4283       }
4284       result = up_filter_out_diff_nichdls(result, nic_hdl);  
4285       if(tracing) 
4286           {
4287         printf("TRACING: Filtered person\n");
4288       }
4289           free(nic_hdl);
4290     }
4291 
4292     /* also, we must filter the 'result' with NIC handle for roles */
4293     if(strcmp(type,"role") == 0)
4294         {
4295       if(tracing) 
4296           {
4297         printf("TRACING: This is a role\n");
4298       }
4299       /* if this is a role, then we must filter out the roles with different
4300          nic-hdl attributes (since it is possible to have this NIC hdl in the name
4301          of a role object, and whois will return that object too) */
4302       nic_hdl = get_search_key(object, "nic-hdl");
4303       if(tracing) 
4304           {
4305         printf("TRACING: Got nic-hdl of role: %s\n", nic_hdl);
4306       }
4307       result = up_filter_out_diff_nichdls(result, nic_hdl);  
4308       if(tracing) 
4309           {
4310         printf("TRACING: Filtered role\n");
4311       }
4312           free(nic_hdl);
4313     }
4314 
4315     if(strcmp(type,"route") == 0)
4316         {
4317       if(tracing) 
4318           {
4319         printf("TRACING: This is a route\n");
4320       }
4321       /* if this is a route, then we must filter out the routes with different
4322          origin attributes */
4323       origin = get_search_key(object, "origin");
4324       if(tracing) 
4325           {
4326         printf("TRACING: Got origin of route: %s\n", origin);
4327       }
4328       result = up_filter_out_diff_origins(result, origin);  
4329       if(tracing) 
4330           {
4331         printf("TRACING: Filtered routes\n");
4332       }
4333           free(origin);
4334     }
4335     
4336     /* count the objects */
4337     if(count_objects(result) == 0)
4338         {
4339       result = NULL; /* we don't have such an object */
4340     }
4341         else if(count_objects(result) == 1)
4342         {
4343       result = take_object(result);
4344       if(tracing) 
4345           {
4346       printf("TRACING: Take_object returned ***%s\n", result);
4347       }
4348     }
4349         else
4350         { /* we have more than one objects, error! */
4351       result = NULL;
4352     }
4353         
4354     return result;
4355 }
4356 
4357 
4358 
4359 
4360 /* Gets a credentials_struct whose 'from' field will be filled in and
4361    the mail header. Finds the 'From:' line in the header and sets
4362    the 'from' field to this line (all line, including the 'From:' string,
4363    since some users have put regexps which match the whole line in their
4364    'auth' attributes.) */
4365 void process_mail_header(credentials_struct * credentials_ptr, char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
4366 {
4367   char * header = strdup(arg);
4368   char * temp = (char *)malloc(strlen(header));
4369 
4370   while (index(header, '\n') != NULL)
4371   {
4372     temp = strdup(header);
4373     temp[index(temp, '\n') - temp] = '\0';
4374     if (strstr(temp, "From:") == temp)
4375         {
4376       if (tracing)
4377           {
4378         printf("TRACING: process_mail_header: Assigning %s\n", temp);
4379       }
4380       credentials_ptr->from = strdup(temp);
4381       free(temp);
4382       return;
4383     }
4384     header = header + (index(header, '\n') - header + 1);
4385   }
4386   free(temp);
4387 }
4388 
4389 
4390 
4391 void up_string_pack(char *dest, const char *source)
     /* [<][>][^][v][top][bottom][index][help] */
4392 {
4393   if(tracing) 
4394   {
4395     printf("TRACING: up_string_pack running\n");
4396   }
4397 
4398 /*----------------------------------------------------------------------*\
4399 
4400 *  Function to rewrite a line of text with only one blankspace between  *
4401 *  each word.
4402 *
4403 \*----------------------------------------------------------------------*/
4404 /*
4405  * This while loop continues until the NULL character is copied into
4406  * the destination string.  If a tab character is copied into the
4407  * destination string, it is replaced with a blank-space character.
4408  *
4409  * Multiple blank-space and/or tab characters are skipped in the source
4410  * string until any other character is found.
4411  */
4412 
4413   while (1)
4414   {
4415     *dest = *source;
4416 
4417     if (*dest == '\t')
4418             (*dest = ' ');
4419 
4420     /* Exit if have copied the end of the string. */
4421     if (*dest == '\0')
4422             return;
4423 
4424 /*
4425 * If the source character was a blank-space or a tab, move to the next
4426 * source character.  While the source character is a blank-space or a
4427 * tab, move to the next character (i.e. ignore these characters).  When
4428 * any other character is found in the source string, move to the next
4429 * element of the destination string.
4430 *
4431 * Otherwise, simultaneously, move to the next elements of the destination
4432 * and the source strings.
4433 */
4434 
4435     if ( (*source == ' ') || (*source == '\t') )
4436     {
4437         ++source;
4438         while ( (*source == ' ') || (*source == '\t') )
4439                 {
4440                 ++source;
4441                 }
4442 
4443         ++dest;
4444     }
4445     else
4446     {
4447         ++dest;
4448         ++source;
4449     }
4450   }
4451 }
4452 
4453 
4454 /* replaces the erase_str occurences with insert_str in str (which is a ptr to GString) */
4455 char * UP_replace_strings(char * str, const char * erase_str, const char * insert_str)
     /* [<][>][^][v][top][bottom][index][help] */
4456 {
4457   GString * g_str;  
4458   int pos;
4459   char * result_str;
4460   
4461   /* erase_str mustn't be NULL */
4462   assert(erase_str != NULL);
4463   
4464   /* if insert str is NULL, make it empty string */
4465   if(insert_str == NULL)
4466   {
4467     insert_str = strdup(""); 
4468   }
4469   
4470   g_str = g_string_new(str);
4471   
4472   /* replace erase_str with insert_str */
4473   while(strstr(g_str->str, erase_str) != NULL)
4474   {
4475     pos = strstr(g_str->str, erase_str) - g_str->str;
4476     g_str = g_string_erase(g_str, pos, strlen(erase_str));
4477     if(insert_str != NULL)
4478         {
4479       g_str = g_string_insert(g_str, pos, insert_str);
4480     }
4481   }
4482 
4483   /* save the result string */
4484   result_str = strdup(g_str->str);
4485 
4486   /* free the GString structure (TRUE means 'also free the char string') */
4487   g_string_free(g_str, TRUE);
4488 
4489   return result_str;
4490 }
4491 
4492 
4493 
4494 /* replaces the erase_str occurences with insert_str in g_str (which is a ptr to GString) */
4495 GString * UP_replace_GStrings(GString * g_str, const char * erase_str, const char * insert_str)
     /* [<][>][^][v][top][bottom][index][help] */
4496 {
4497   int pos;
4498   
4499   if (insert_str == NULL)
4500   { /* then don't do anything */
4501     return g_str;
4502   }
4503    
4504   /* replace erase_str with insert_str */
4505   while (strstr(g_str->str, erase_str) != NULL)
4506   {
4507     pos = strstr(g_str->str, erase_str) - g_str->str;
4508     g_str = g_string_erase(g_str, pos, strlen(erase_str));
4509     g_str = g_string_insert(g_str, pos, insert_str);
4510   }
4511   return g_str;
4512 }
4513 
4514 
4515 
4516 /* looks if two objects are identical or not.
4517     Takes two objects, one as char *, the other as
4518         a parsed object, and returns 1 if
4519     they are identical, returns 0 if not.
4520 
4521     Algorithm is very simple: All strings of tabs and 
4522     white spaces are collapsed into a single white space,
4523     and then the strings are compared (strcmp) */
4524 int identical(const char * old_version, rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
4525 {
4526   char * arg1 = strdup(old_version);
4527   char * arg2 = NULL;
4528   rpsl_object_t *object2;
4529   rpsl_error_t error;
4530   int result = 0;
4531   char *temp1, *temp2; 
4532   char *temp;
4533   
4534   object2 = rpsl_object_copy(object);
4535   rpsl_object_remove_attr_name(object2, "delete", &error);
4536   rpsl_object_remove_attr_name(object2, "override", &error);
4537   arg2 = rpsl_object_get_text(object2,RPSL_STD_COLUMN);
4538 
4539   arg1 = g_strstrip(arg1);
4540   arg2 = g_strstrip(arg2);
4541 
4542   /* convert tabs to white spaces */
4543   arg1 = g_strdelimit(arg1, "\t", ' ');
4544   arg2 = g_strdelimit(arg2, "\t", ' ');
4545   
4546   temp1 = (char *)malloc(strlen(arg1) + 1); 
4547   temp2 = (char *)malloc(strlen(arg2) + 1);
4548   up_string_pack(temp1, arg1);
4549   up_string_pack(temp2, arg2);
4550 
4551   /* if there are still \r's at the end of strings, remove them */
4552   if((temp1[strlen(temp1) - 1]) == '\r')
4553   {
4554     temp1[strlen(temp1) - 1] = '\0';
4555   }
4556   if((temp2[strlen(temp2) - 1]) == '\r')
4557   {
4558     temp2[strlen(temp2) - 1] = '\0';
4559   }
4560 
4561   /* there may be white spaces at the end of the strings now, remove them */
4562   if((temp1[strlen(temp1) - 1]) == ' ')
4563   {
4564     temp1[strlen(temp1) - 1] = '\0';
4565   }
4566   if((temp2[strlen(temp2) - 1]) == ' ')
4567   {
4568     temp2[strlen(temp2) - 1] = '\0';
4569   }
4570 
4571   /* remove the white spaces just before the EOLs (since this is not taken care of by
4572      the up_string_pack func) */
4573   temp = UP_replace_strings(temp1, " \n", "\n");
4574   free(temp1);
4575   temp1 = temp;
4576 
4577   temp = UP_replace_strings(temp2, " \n", "\n");
4578   free(temp2);
4579   temp2 = temp;
4580 
4581   result = strcmp(temp1, temp2);
4582   if(tracing){
4583     printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
4584     printf("TRACING: identical: the lengths are:\n[%i]\n[%i]\n", strlen(temp1), strlen(temp2));
4585   }
4586   free(arg1);
4587   free(arg2);
4588   free(temp1);
4589   free(temp2);
4590   if(result  == 0)
4591   {
4592     if(tracing) 
4593         {
4594       printf("TRACING: identical returning 1\n");
4595     }
4596     return 1;
4597   }
4598   else
4599   {
4600     if(tracing) 
4601         {
4602       printf("TRACING: identical returning 0\n");
4603     }
4604     return 0;
4605   }
4606 }
4607 
4608 
4609 /* constructs an initials string from a given name (for NIC hdl generation) */
4610 char * find_initials(const char * person_role_name)
     /* [<][>][^][v][top][bottom][index][help] */
4611 {
4612    char * temp, *pos;
4613    char * initials = NULL;
4614    int len, i;
4615    char ** vector;
4616 
4617    temp = strdup(person_role_name);
4618    if ((pos = index(temp, '#')) != NULL)
4619    { /* delete the EOL comment */
4620      pos[0] = '\0';
4621    }
4622 
4623    vector = g_strsplit(temp, " ", 0);
4624    for (i = 0; vector[i] != NULL && i < 4; i++)
4625    {
4626      if ( (strlen(vector[i]) > 0 ) && isalpha( (int)(vector[i][0]) ) )
4627          {
4628        if (initials == NULL)
4629            {
4630          initials = (char *)malloc(2);
4631          initials[0] = vector[i][0]; 
4632                  initials[1] = '\0';
4633        }
4634            else
4635            {
4636          len = strlen(initials);
4637          initials = (char *)realloc(initials, len + 2 );
4638          initials[len] = vector[i][0];
4639          initials[len + 1] = '\0';
4640        }
4641      }
4642    }
4643    free(temp);
4644    g_strfreev(vector);
4645    return initials;
4646 }
4647 
4648 
4649 
4650 
4651 /*  Gets the letter combination to be used in the automatically
4652     generated NIc handle. It the letter combination is specified
4653     in the AUTO NIC handle, return that. If not, return NULL
4654     (in which case the initials of the name must be used) */
4655 char * get_combination_from_autonic(const char * autonic)
     /* [<][>][^][v][top][bottom][index][help] */
4656 {
4657   GString * temp;
4658   char * str = NULL;
4659   char * pos;
4660 
4661   temp = g_string_new(autonic);
4662   temp = g_string_up(temp);
4663   if ((pos = index(temp->str, '#')) != NULL)
4664   { 
4665     /* delete the EOL comment */
4666     pos[0] = '\0';
4667   }
4668   g_strstrip(temp->str);
4669   temp->len = strlen(temp->str);/* we directly played with temp->str, so adjust temp->len accordingly */
4670  
4671   temp = g_string_erase(temp, 0, strlen("AUTO-"));
4672   /* delete all digits from the beginning of the string */
4673   while (temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9'))
4674   {
4675     temp = g_string_erase(temp, 0, 1);
4676   }
4677 
4678   if (temp->len < 2 )
4679   {
4680     g_string_free(temp, TRUE);
4681     return NULL;
4682   }
4683   else
4684   {
4685     str = temp->str;
4686     g_string_free(temp, FALSE);
4687     g_strup(str);
4688     if(strlen(str) > 4)
4689         {
4690       str[4] = '\0'; 
4691     }
4692     return str;
4693   }
4694 }
4695 
4696 
4697 
4698 
4699 /* Gets an object whose NIC hdl is an auto NIC handle and to be modified (to be sent to RIPupdate)
4700    and  modifies the nic-hdl: attribute.
4701    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
4702    auto_nic is set to "AUTO-1"
4703    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
4704 rpsl_object_t * replace_AUTO_NIC_hdl(rpsl_object_t *object, char * auto_nic_hdl)
     /* [<][>][^][v][top][bottom][index][help] */
4705 {
4706   GList *nichdl_item;
4707   rpsl_object_t *object2 = NULL;
4708   rpsl_attr_t *attr;
4709   GList *class_attr;
4710   char * person_role_name = NULL;
4711   char * initials = NULL;
4712   char *value, *new_value = NULL;
4713   const char *type;
4714   int pos;
4715 
4716   if (tracing)
4717   {                                
4718       printf("TRACING: replace_AUTO_NIC_hdl running\n");
4719   }
4720 
4721   nichdl_item = rpsl_object_get_attr(object, "nic-hdl"); /* list with one item only */
4722 
4723   value = rpsl_attr_get_clean_value((rpsl_attr_t *)(nichdl_item->data));
4724   g_strdown(value);
4725   if (tracing)
4726   {                                
4727       printf("TRACING: auto nic-hdl value is [%s]\n", value);
4728   }
4729 
4730   if (strstr(value, "auto-") != NULL)
4731   {
4732     /* this attribute must be replaced with a new attribute containing a nic-hdl */
4733     strcpy(auto_nic_hdl, value);
4734     pos = rpsl_attr_get_ofs((rpsl_attr_t *)(nichdl_item->data));
4735 
4736         if (tracing)
4737         {                                
4738         printf("TRACING: pos [%d]\n", pos);
4739         }
4740 
4741      /* if the letter combination is already specified, get it */
4742     initials = get_combination_from_autonic(auto_nic_hdl);
4743     /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
4744     if(initials == NULL)
4745         {
4746           type = rpsl_object_get_class(object);
4747           class_attr = rpsl_object_get_attr(object, type);
4748           person_role_name = rpsl_attr_get_clean_value((rpsl_attr_t *)(class_attr->data));
4749           rpsl_attr_delete_list(class_attr);
4750       initials = find_initials(person_role_name);
4751           free(person_role_name);
4752     }
4753         if (tracing)
4754         {                                
4755         printf("TRACING: initials [%s]\n", initials ? initials : "NULL");
4756         }
4757 
4758         object2 = rpsl_object_copy(object);
4759     new_value = (char *)malloc(strlen(initials) + strlen(current_source) + 3);
4760         strcpy(new_value, initials);
4761         strcat(new_value, "*-");
4762         strcat(new_value, current_source);
4763         if (tracing)
4764         {                                
4765         printf("TRACING: new_value [%s]\n", new_value);
4766         }
4767 
4768         /* now copy original attribute, replace value, remove old attr and add replacement */
4769         attr = rpsl_attr_copy((rpsl_attr_t *)(nichdl_item->data));
4770         rpsl_attr_replace_value(attr, new_value);
4771         free(initials);
4772         free(new_value);
4773         free(value);
4774 
4775         /* remove the attribute with the auto- */
4776         rpsl_object_remove_attr(object2, pos, NULL);
4777                 
4778         /* insert new attribute with nic-hdl */
4779         rpsl_object_add_attr(object2, attr, pos, NULL);
4780   }
4781   rpsl_attr_delete_list(nichdl_item);
4782   
4783   return(object2);
4784 }
4785 
4786 
4787 
4788 
4789 /* replaces the refs to AUTO NIC hdls with the assigned one */
4790 
4791 char * replace_refs_to_AUTO_NIC_hdl(rpsl_object_t *object, GHashTable * auto_nic_hash, char *arg)
     /* [<][>][^][v][top][bottom][index][help] */
4792 {
4793   char * nic_hdl = NULL;
4794   char *name;
4795   char *value;
4796   char *return_str;
4797   char *tempstr;
4798   rpsl_attr_t *attr;
4799   const GList * attr_list = NULL;
4800   const GList * list_item = NULL;
4801   int pos;
4802 
4803   if(tracing)
4804   {
4805     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is running: arg:[%s]\n", arg ? arg : "NULL");
4806   }
4807 
4808   attr_list = rpsl_object_get_all_attr(object);
4809   
4810 //  for (list_item = attr_list; list_item != NULL; list_item = g_list_next(list_item ))
4811 //  {
4812   list_item = attr_list;
4813   while (list_item != NULL)
4814   {
4815         name = strdup(rpsl_attr_get_name((rpsl_attr_t *)(list_item->data)));
4816         g_strdown(name);
4817         value = rpsl_attr_get_clean_value((rpsl_attr_t *)(list_item->data));
4818         g_strdown(value);
4819         pos = rpsl_attr_get_ofs((rpsl_attr_t *)(list_item->data));
4820         if (    strstr(name, "admin-c") == name
4821              || strstr(name, "tech-c")  == name
4822              || strstr(name, "zone-c")  == name
4823              || strstr(name, "author")  == name )
4824         {
4825           /* attr starts with admin-c, tech-c, zone-c or author */
4826           if ( strstr(value, "auto-") != NULL)
4827           {
4828         if(tracing)
4829                 {
4830                         printf("TRACING: replace_refs_to_AUTO_NIC_hdl: auto_nic is [%s]\n", value);
4831         }
4832         
4833         /* if we have this AUTO NIC hdl in the hash, put it in. */
4834         if( (nic_hdl = (char *)g_hash_table_lookup(auto_nic_hash, value)) )
4835                 {
4836                 if(tracing)
4837                         {
4838                                 printf("TRACING: replace_refs_to_AUTO_NIC_hdl: nic_hdl is [%s]\n", nic_hdl);
4839                 }
4840                         /* create a new attribute with the auto nic handle */
4841                         attr = rpsl_attr_copy((rpsl_attr_t *)(list_item->data));
4842             rpsl_attr_replace_value(attr, nic_hdl);
4843 
4844                         /* remove the attribute with the auto- */
4845                         rpsl_object_remove_attr(object, pos, NULL);
4846                         
4847                         /* insert new attribute with nic-hdl */
4848                         rpsl_object_add_attr(object, attr, pos, NULL);
4849 
4850             /* replacing the attr destroys the list, so start the list again */
4851             attr_list = rpsl_object_get_all_attr(object);
4852             list_item = attr_list; 
4853         }
4854                 else
4855                 { /* else, return 0 immediately */
4856                         free(name);
4857                         free (value);
4858                         return NULL;
4859         }
4860           }
4861         }
4862 
4863         free(name);
4864         free (value);
4865         
4866         list_item = g_list_next(list_item);
4867   }
4868         
4869   return_str =  rpsl_object_get_text(object,RPSL_STD_COLUMN);
4870 
4871   /* now, if we don't have a '\n' at the end of the return_str  string, we will
4872      add one, since RAToolSet parser cannot deal with objects without a '\n' at the end */
4873   if(return_str[strlen(return_str) - 1] != '\n')
4874   {
4875     /* so, add a '\n' */
4876     tempstr = (char *)malloc(strlen(return_str) + 2);
4877     sprintf(tempstr, "%s\n", return_str);
4878     free(return_str);
4879     return_str = tempstr;
4880   }
4881    
4882   if (tracing)
4883   {
4884     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is returning,\nreturn_str=[%s]\n", return_str);
4885   }
4886 
4887   return return_str;
4888 }
4889 
4890 
4891 
4892 
4893 /* UP_put_assigned_NIC will replace the auto NIC handle of the object with its
4894    assigned NIC handle and return an amended copy of the object */
4895 rpsl_object_t * UP_put_assigned_NIC(rpsl_object_t *object, char * assigned_NIC)
     /* [<][>][^][v][top][bottom][index][help] */
4896 {
4897   rpsl_object_t *object2;
4898   rpsl_attr_t *attr;
4899   GList * nichdl_item;
4900   char *value;
4901   int pos;
4902 
4903   nichdl_item = rpsl_object_get_attr(object, "nic-hdl");  /* a list with only one item */
4904 
4905   value = rpsl_attr_get_clean_value((rpsl_attr_t *)(nichdl_item->data));
4906   g_strdown(value);
4907   if (strstr(value, "auto-") != NULL)
4908   {
4909     /* replace the AUTO-NIC hdl with the assigned one  */
4910 
4911     if (tracing)
4912     {
4913       printf("TRACING: UP_put_assigned_NIC: auto_nic is [%s]\n", value);
4914     }
4915 
4916         object2 = rpsl_object_copy(object);
4917         /* now copy original attribute, replace value, remove old attr and add replacement */
4918         attr = rpsl_attr_copy((rpsl_attr_t *)(nichdl_item->data));
4919         rpsl_attr_replace_value(attr, assigned_NIC);
4920     pos = rpsl_attr_get_ofs((rpsl_attr_t *)(nichdl_item->data));
4921 
4922         /* remove the attribute with the auto- */
4923         rpsl_object_remove_attr(object2, pos, NULL);
4924                 
4925         /* insert new attribute with nic-hdl */
4926         rpsl_object_add_attr(object2, attr, pos, NULL);
4927   }
4928   rpsl_attr_delete_list(nichdl_item);
4929 
4930   return object2;
4931 }
4932 
4933 
4934 
4935 
4936 /* Takes a parsed object, and returns 1 if this object has 
4937    an AUTO NIC handle. Otherwise, returns 0 */
4938 int has_AUTO_NIC_hdl(const rpsl_object_t * object)
     /* [<][>][^][v][top][bottom][index][help] */
4939 {
4940   GList *attributes = NULL;
4941 
4942   if ( !rpsl_object_is_deleted(object) )
4943   {
4944     attributes = rpsl_object_get_attr(object, "nic-hdl");
4945     if (attributes != NULL)
4946         {
4947       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
4948           { /* if it contains a ref to AUTO nic */
4949         rpsl_attr_delete_list(attributes);
4950         return 1;
4951       }
4952     }
4953     /* if control reaches here, then we will return 0 */
4954     rpsl_attr_delete_list(attributes);
4955     return 0; 
4956   }
4957   else
4958   { /* it doesn't pass syntax check. So, it doesn't matter if 
4959            it contains refs to AUTO NIC hdls. */
4960     return 0;        
4961   }
4962 }
4963 
4964 
4965 /* Takes an rpsl_object_t structure , and returns 1 if this object contains
4966    a reference to an AUTO NIC handle. Otherwise, returns 0 */
4967 int has_ref_to_AUTO_nic_hdl(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
4968 {
4969   GList * attributes = NULL;
4970 
4971   if (! rpsl_object_is_deleted(object) )
4972   {
4973     attributes = rpsl_object_get_attr(object, "admin-c");
4974     rpsl_attr_split_multiple(&attributes);
4975     if (attributes != NULL)
4976         {
4977       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
4978           { /* if it contains a ref to AUTO nic */
4979         rpsl_attr_delete_list(attributes);
4980         return 1;
4981       }
4982     }
4983     rpsl_attr_delete_list(attributes);
4984     attributes = rpsl_object_get_attr(object, "tech-c");
4985     rpsl_attr_split_multiple(&attributes);
4986     if (attributes != NULL)
4987         {
4988       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
4989           { /* if it contains a ref to AUTO nic */
4990         rpsl_attr_delete_list(attributes);
4991         return 1;
4992       }
4993     }
4994 
4995     rpsl_attr_delete_list(attributes);
4996     attributes = rpsl_object_get_attr(object, "zone-c");
4997     rpsl_attr_split_multiple(&attributes);
4998     if (attributes != NULL)
4999         {
5000       if(strstr_in_attr_list(attributes, "AUTO-") == 1)
5001           { /* if it contains a ref to AUTO nic */
5002         rpsl_attr_delete_list(attributes);
5003         return 1;
5004       }
5005     }
5006     rpsl_attr_delete_list(attributes);
5007     attributes = rpsl_object_get_attr(object, "author");
5008     rpsl_attr_split_multiple(&attributes);
5009     if (attributes != NULL)
5010         {
5011       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
5012           { /* if it contains a ref to AUTO nic */
5013         rpsl_attr_delete_list(attributes);
5014         return 1;
5015       }
5016     }
5017     rpsl_attr_delete_list(attributes);
5018     /* if control reaches here, then we will return 0 */
5019     return 0; 
5020   }
5021   else
5022   {  /* it doesn't pass syntax check. So, it doesn't matter if 
5023            it contains refs to AUTO NIC hdls. */
5024     return 0;        
5025   }
5026 }
5027 
5028 
5029 
5030 /* Gets the "From" line of the incoming mail message and finds out an 
5031    address to send the acknowledgement */
5032 char * find_email_address(const char * from_line)
     /* [<][>][^][v][top][bottom][index][help] */
5033 {
5034   char * pos1 = NULL, * pos2 = NULL, * pos = NULL;
5035   char * temp = NULL;
5036   char * part1 = NULL, * part2 = NULL;
5037   
5038   if (from_line == NULL)
5039   {
5040     return NULL;
5041   }
5042   if (strstr(from_line, "From:") != from_line)
5043   {
5044     temp = strdup(from_line);
5045   }
5046   else
5047   {
5048     temp = strdup(from_line + strlen("From:"));
5049   }
5050   g_strstrip(temp);
5051   if (index(temp, '<'))
5052   { /* then the line is something like '"John White" <john@inter.net>' */
5053     pos1 = index(temp, '<');
5054     pos2 = index(temp, '>');
5055     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
5056     temp[pos2 - pos1 - 1] = '\0';
5057     if (tracing)
5058         {
5059      printf("TRACING: find_email_address temp=[%s]\n", temp);
5060     }
5061   }
5062 
5063   /* and now, we have to remove the parts in parantheses */ 
5064   while (   index(temp, '(') != NULL && index(temp, ')') != NULL
5065           && index(temp, '(') < index(temp, ')') )
5066   {
5067     part1 = strdup(temp);
5068     /* terminate the string */
5069     pos = index(part1, '(');
5070     *pos = '\0';
5071 
5072     part2 = strdup(index(temp, ')') + 1);
5073     strcat(part1, part2);
5074     free(temp);
5075     temp = strdup(part1);
5076     free(part1);
5077     free(part2);
5078   }
5079   
5080   g_strstrip(temp); 
5081   return temp;
5082 }  
5083 
5084 
5085 
5086 /* removes the '\n's and '\r's at the end of the arg, and returns it  */
5087 char * UP_remove_EOLs(char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
5088 {
5089   while ( strlen(arg) > 0 &&
5090           (arg[strlen(arg) - 1] == '\n' || 
5091            arg[strlen(arg) - 1] == '\r') )
5092   {
5093     arg[strlen(arg) - 1] = '\0';
5094   }
5095  
5096   return arg;
5097 }
5098 
5099 
5100 
5101 /* Duplicates the given arg, and replaces 
5102     $FROM,
5103     $SUBJECT,
5104     $MDATE,
5105     $MSGID,
5106     $CC,
5107     $HUMAILBOX
5108     $AUTOBOX
5109     $FROMHOST
5110 
5111     and $TIME & $DATE
5112     
5113     strings with the corresponding variables.
5114     
5115 */
5116 char * UP_replace_globals(const char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
5117 {
5118   GString * g_str;
5119   char * to_be_returned;
5120   time_t cur_time;
5121   char * temp, * time_str, * date_str;
5122 
5123   /* get time */
5124   cur_time = time(NULL);
5125   temp = strdup(ctime(&cur_time));
5126   /* temp is now something like "Fri Sep 13 00:00:00 1986\n\0", fields are const width */ 
5127   
5128   time_str = (char *)malloc(9);  
5129   time_str = strncpy(time_str, temp + 11, 8);
5130   time_str[8] = '\0';  
5131             
5132   date_str = (char *)malloc(16);
5133   date_str = strncpy(date_str, temp, 11);
5134   date_str[11] = '\0';
5135   date_str = strncat(date_str, temp + 20, 4);
5136   
5137    
5138   free(temp);
5139                                          
5140   g_str = g_string_new(arg);
5141 
5142   g_str = UP_replace_GStrings(g_str, "$FROMHOST", netupdclientIP); 
5143 
5144   g_str = UP_replace_GStrings(g_str, "$TIME", time_str);
5145 
5146   g_str = UP_replace_GStrings(g_str, "$DATE", date_str);
5147 
5148   g_str = UP_replace_GStrings(g_str, "$SUBJECT", update_mail_subject);
5149 
5150   g_str = UP_replace_GStrings(g_str, "$FROM", update_mail_sender);
5151 
5152   g_str = UP_replace_GStrings(g_str, "$MDATE", update_mail_date); 
5153 
5154   g_str = UP_replace_GStrings(g_str, "$MSGID", update_mail_ID);
5155 
5156   if (update_mail_cc == NULL)
5157     g_str = UP_replace_GStrings(g_str, "$CC", ""); 
5158   else
5159     g_str = UP_replace_GStrings(g_str, "$CC", update_mail_cc);
5160   
5161   g_str = UP_replace_GStrings(g_str, "$HUMAILBOX", humailbox);
5162 
5163   g_str = UP_replace_GStrings(g_str, "$AUTOBOX", autobox);
5164 
5165   g_str = UP_replace_GStrings(g_str, "$HEADERTYPE", header_type); 
5166 
5167   g_str = UP_replace_GStrings(g_str, "$TEXTTYPE", text_type); 
5168 
5169   free(time_str);
5170   free(date_str);
5171 
5172   to_be_returned = strdup(g_str->str); 
5173   g_string_free(g_str, 1); 
5174   return to_be_returned;
5175 }
5176 
5177 
5178 
5179 
5180 /* Adds the given file to the update log */
5181 void UP_add_to_upd_log(const char * filename)
     /* [<][>][^][v][top][bottom][index][help] */
5182 {
5183   time_t now;
5184   struct tm * tmstr;
5185   time_t cur_time;
5186   char * time_str;
5187   char datestr[10]; 
5188   char * updlogfile;
5189   FILE * infile, * log_file;
5190   char   buf[1024];
5191 
5192 
5193   if (( infile = fopen(filename, "r")) == NULL)
5194   {
5195     fprintf(stderr, "UP_add_to_upd_log: Can't open upd file, %s\n", filename);
5196     return;
5197   }
5198   
5199   /* We need to get the a date string to construct the updlog file name */
5200   time(&now);
5201   tmstr = localtime(&now);
5202   strftime(datestr, 10, "%Y%m%d", tmstr);
5203 
5204   /* now that we have the date string, we can construct updlog file name */
5205   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
5206   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
5207            "%s.%s", updlog, datestr);
5208   
5209  
5210   if (( log_file = fopen(updlogfile, "a")) == NULL)
5211   {
5212     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", updlogfile);
5213         free(updlogfile);
5214     return;
5215   }
5216    
5217   /* get time */
5218   cur_time = time(NULL);
5219   time_str = strdup(ctime(&cur_time));
5220   /* cut the '\n' at the end */
5221   time_str[strlen(time_str) - 1] = '\0';
5222 
5223   if (reading_from_mail)
5224   {
5225     fprintf(log_file, ">>> time: %s MAIL UPDATE <<<\n\n", time_str);
5226   }
5227   else if (networkupdate)
5228   {
5229     fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n", 
5230                       time_str, netupdclientIP ? netupdclientIP : "NULL");
5231   }
5232   else if (webupdate)
5233   {
5234     fprintf(log_file, ">>> time: %s WEB UPDATE (%s) <<<\n\n", 
5235                        time_str, netupdclientIP ? netupdclientIP : "NULL");
5236   }
5237   else
5238   {
5239     fprintf(log_file, ">>> time: %s UPDATE <<<\n\n", time_str);
5240   }
5241 
5242   free(time_str);
5243   while ( fgets(buf, 1023, infile) != NULL ) 
5244   {
5245     fprintf(log_file, "%s", buf);
5246   }
5247   free(updlogfile);
5248 
5249   fclose(infile);
5250   fclose(log_file);
5251 }
5252 
5253 
5254 
5255 /* Logs the object to the update log */
5256 void UP_log_networkupdate(const char * object_str, const char * host)
     /* [<][>][^][v][top][bottom][index][help] */
5257 {
5258   time_t now;
5259   struct tm * tmstr;
5260   time_t cur_time;
5261   char * time_str;
5262   char datestr[10]; 
5263   char * updlogfile;
5264   FILE * log_file;
5265 
5266   /* We need to get the a date string to construct the updlog file name */
5267   time(&now);
5268   tmstr = localtime(&now);
5269   strftime(datestr, 10, "%Y%m%d", tmstr);
5270 
5271   /* now that we have the date string, we can construct updlog file name */
5272   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
5273   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
5274            "%s.%s", updlog, datestr);
5275   
5276   if (( log_file = fopen(updlogfile, "a")) == NULL)
5277   {
5278     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", updlogfile);
5279         free(updlogfile);
5280     return;
5281   }
5282   free(updlogfile);
5283    
5284   /* get time */
5285   cur_time = time(NULL);
5286   time_str = strdup(ctime(&cur_time));
5287   /* cut the '\n' at the end */
5288   time_str[strlen(time_str) - 1] = '\0';
5289 
5290   fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n", time_str, host);
5291 
5292   free(time_str);
5293 
5294   fprintf(log_file, "%s\n", object_str);
5295 
5296   fclose(log_file);
5297 }
5298 
5299 
5300 
5301 
5302 /* Performs a preliminary check on a string: Tries to guess if the arg is an object or not.
5303    The criteria is: If we have a colon (":") in the first line of the string, then it is
5304    probably an object */
5305 int UP_is_object(const char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
5306 {
5307    if (arg == NULL)
5308    {
5309      return 0; /* not an object */
5310    }
5311 
5312    if (index(arg ,'\n'))
5313    { /* does it consist of multiple lines? */
5314      if (index(arg ,':') != NULL  && (index(arg ,':') < index(arg ,'\n')))
5315          {
5316        return 1;
5317      }
5318          else
5319          { /* it doesn't have any ":" or, first ":" is not in the first line */
5320        return 0;
5321      }
5322    }
5323    else
5324    { /* it has a single line, possibly not an object */
5325      return 0;
5326    }
5327 }
5328 
5329 
5330 int UP_remove_override_attr( rpsl_object_t *object )
     /* [<][>][^][v][top][bottom][index][help] */
5331 {
5332   rpsl_error_t return_error;
5333   rpsl_attr_t *removed_attr;
5334 
5335   return_error.code = (gint)NULL;
5336   removed_attr = rpsl_object_remove_attr_name(object,"override",&return_error);
5337   if ( (removed_attr == NULL) && return_error.level >= RPSL_ERRLVL_ERROR )
5338   {
5339          /* error returned */
5340          /* could be that there was no override attribute in this object */
5341      if ( return_error.code == RPSL_ERR_NOSUCHATTR )
5342            return 1;  /* This is OK, object has no override attribute */
5343          else
5344            /* there was an override attr in this object and it has not been removed */
5345            return 0;
5346   }
5347   else
5348     /* no errors, override attribute has been removed */
5349          return 1; 
5350 }
5351 
5352 
5353 /****************************************************************************************************/
5354 
5355 /*******************  Redundant Functions ***********************************************************/
5356 
5357 
5358 
5359 /* strips lines beginning with "override:" off  */
5360 char * delete_override(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
5361 
5362     char ** temp = NULL;
5363     char * string = NULL;
5364     int i;
5365 
5366     if(arg == NULL){
5367        return NULL;
5368     }
5369 
5370     /* split the string into lines */
5371     temp = g_strsplit (arg, "\n", 0);
5372 
5373     for(i=0; temp[i] != NULL; i++){
5374       /* if the line begins with "override:", then do not copy it */
5375       if(strstr(temp[i], "override:") != temp[i]){
5376         if(string == NULL){
5377           string = strdup(temp[i]);
5378         }else{
5379           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
5380           string = strcat(string, "\n");
5381           string = strcat(string, temp[i]);
5382         }
5383       }
5384     }
5385     g_strfreev(temp);
5386     return string;
5387 }
5388 
5389 
5390 /* takes a pre-parsed object, and returns its type */
5391 /* char * get_class_type(Object *arg){
5392     
5393     char * be_returned = NULL;
5394     if(arg == NULL) return NULL;
5395     be_returned = strdup(arg->type->getName());  
5396     return g_strstrip(be_returned);
5397 }
5398 */
5399 
5400 
5401 
5402 
5403 
5404 
5405 
5406 /*************** still used in nt module **************/
5407 /* strips lines beginning with "delete:" off  */
5408 char * delete_delete_attrib(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
5409 
5410     char ** temp = NULL;
5411     char * string = NULL;
5412     int i;
5413 
5414     if(arg == NULL){
5415        return NULL;
5416     }
5417 
5418     /* split the string into lines */
5419     temp = g_strsplit (arg, "\n", 0);
5420 
5421     for(i=0; temp[i] != NULL; i++){
5422       /* if the line begins with "delete:", then do not copy it */
5423       if(strstr(temp[i], "delete:") != temp[i]){
5424         if(string == NULL){
5425           string = strdup(temp[i]);
5426         }else{
5427           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
5428           string = strcat(string, "\n");
5429           string = strcat(string, temp[i]);
5430         }
5431       }
5432     }
5433     g_strfreev(temp);
5434     return string;
5435 }

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