modules/up/UP_util.cc

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

FUNCTIONS

This source file includes following functions.
  1. authorise
  2. error_msg_cat
  3. interpret_ripdb_result
  4. get_assigned_nic
  5. send_object_db
  6. get_type
  7. get_search_key
  8. send_and_get
  9. count_objects
  10. strip_lines
  11. take_objects
  12. take_object
  13. get_as_block
  14. get_aut_num_object
  15. get_less_specific_domain
  16. get_less_specific_set
  17. get_less_specific
  18. get_less_spec_inetnum
  19. get_exact_match_inetnum
  20. get_exact_match_routes
  21. get_less_spec_routes
  22. get_mntners
  23. get_attributes
  24. get_attribute
  25. strstr_in_list
  26. get_auths
  27. get_mnt_lowers
  28. get_mnt_routes
  29. get_mnt_routes_from_list
  30. get_mnt_lowers_from_list
  31. get_override
  32. check_override
  33. add_to_auth_vector
  34. get_auth_vector
  35. filter_out_diff_origins
  36. check_auth
  37. get_old_version
  38. process_mail_header
  39. stringPack
  40. delete_delete_attrib
  41. identical
  42. find_initials
  43. replace_AUTO_NIC_hdl
  44. replace_refs_to_AUTO_NIC_hdl
  45. has_AUTO_NIC_hdl
  46. has_ref_to_AUTO_nic_hdl
  47. add_to_ack
  48. add_to_ack_string
  49. process_object
  50. find_to_address

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

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