modules/up/src/rpslcheck/separateobjects.cc

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

FUNCTIONS

This source file includes following functions.
  1. start_tracing
  2. start_debugging
  3. init_and_set_options
  4. send_object_db
  5. get_type
  6. get_search_key
  7. send_and_get
  8. count_objects
  9. take_object
  10. get_as_block
  11. get_less_specific_domain
  12. get_less_specific_set
  13. get_less_specific
  14. get_mntners
  15. get_auths
  16. get_mnt_lowers
  17. get_override
  18. check_override
  19. add_to_auth_vector
  20. get_auth_vector
  21. check_auth
  22. get_old_version
  23. process_object
  24. main

   1 #include <stdio.h>
   2 #include <stdlib.h> 
   3 #include <string.h> 
   4 #include <glib.h>
   5 #include <iostream.h>
   6 
   7     #include <netdb.h> 
   8     #include <sys/types.h> 
   9     #include <netinet/in.h> 
  10     #include <sys/socket.h> 
  11     #include <errno.h> 
  12 
  13 #include <config.h>
  14 #include <istream.h>
  15 #include "rpsl/object.hh"
  16 #include "util/rusage.hh"
  17 #include "util/debug.hh"
  18 #include "util/trace.hh"
  19 #include "util/Argv.hh"
  20 #include "util/version.hh"
  21 #ifdef IRR_NEEDED
  22 #include "irr/irr.hh"
  23 #include "irr/rawhoisc.hh"
  24 #endif // IRR_NEEDED
  25 #include "rpsl/schema.hh"
  26 
  27 Rusage ru;
  28 bool opt_stats                   = false;
  29 bool opt_rusage                  = false;
  30 char *opt_prompt                 = "RtConfig> ";
  31 bool opt_echo                    = false;
  32 #ifdef DEBUG
  33 bool opt_debug_rpsl              = false;
  34 #endif // DEBUG
  35 
  36 int start_tracing(char *dst, char *key, char *nextArg) {
     /* [<][>][^][v][top][bottom][index][help] */
  37    if (nextArg) {
  38       trace.enable(nextArg);
  39       return 1; // return 1 to signify nextArg is used by us
  40    }
  41    return 0; 
  42 }
  43 
  44 int start_debugging(char *dst, char *key, char *nextArg) {
     /* [<][>][^][v][top][bottom][index][help] */
  45    if (nextArg) {
  46       Debug(dbg.enable(atoi(nextArg)));
  47       return 1; // return 1 to signify nextArg is used by us
  48    }
  49    return 0;
  50 }
  51 
  52 void init_and_set_options (int argc, char **argv, char **envp) {
     /* [<][>][^][v][top][bottom][index][help] */
  53    ArgvInfo argTable[] = {
  54      // RAToolSet common arguments
  55      // key, type, src, dst, help
  56      {"-T", ARGV_FUNC, (char *) &start_tracing,      (char *) NULL, 
  57       "Start tracing the next argument"},
  58      {"-D", ARGV_FUNC, (char *) &start_debugging,    (char *) NULL, 
  59       "Start debugging the next argument"},
  60      {"-version", ARGV_FUNC, (char *) &version,      (char *) NULL,
  61       "Show version"},
  62 #ifdef IRR_NEEDED
  63      {"-h", ARGV_FUNC, (char *) &IRR::ArgvHost,      (char *) NULL,
  64       "Host name of the RAWhoisd server"},
  65      {"-p", ARGV_FUNC, (char *) &IRR::ArgvPort,      (char *) NULL,
  66       "Port number of the RAWhoisd server"},
  67      {"-s", ARGV_FUNC, (char *) &IRR::ArgvSources,   (char *) NULL,
  68       "Order of databases"},
  69      {"-ignore_errors", ARGV_FUNC, (char *)&IRR::IgnoreErrors, (char *)NULL,
  70       "Ignore IRR error and warning messages"},
  71      {"-report_errors", ARGV_FUNC, (char *)&IRR::ReportErrors, (char *)NULL,
  72       "Print IRR error and warning messages"},
  73 #endif // IRR_NEEDED
  74      {"-rusage", ARGV_BOOL, (char *) NULL,           (char *) &opt_rusage,
  75       "On termination print resource usage"},
  76      {"-stats", ARGV_BOOL, (char *) NULL,            (char *) &opt_stats,
  77       "On termination print class statistics"},
  78      {"-prompt", ARGV_STRING,  (char *) NULL,        (char *) &opt_prompt,
  79       "Prompt"},
  80      
  81      {"-echo", ARGV_BOOL, (char *) NULL,           (char *) &opt_echo,
  82       "Echo each object parsed"},
  83 #ifdef DEBUG
  84      {"-debug_rpsl", ARGV_BOOL, (char *) NULL,     (char *) &opt_debug_rpsl,
  85       "Turn on bison debugging. Intended for developers."},
  86 #endif // DEBUG
  87      {(char *) NULL, ARGV_END, (char *) NULL, (char *) NULL,
  88       (char *) NULL}
  89    };
  90   
  91 #ifdef IRR_NEEDED
  92    IRR::handleEnvironmentVariables(envp);
  93 #endif // IRR_NEEDED
  94 
  95    if (ParseArgv(&argc, argv, argTable, ARGV_NO_LEFTOVERS) != ARGV_OK) {
  96       cerr << endl;
  97       exit(1);
  98    }
  99 
 100 #ifdef IRR_NEEDED
 101    irr = IRR::newClient();
 102 #endif // IRR_NEEDED
 103 
 104    // have a prompt only if the input is coming from a tty
 105    if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))
 106       opt_prompt = NULL;
 107 }
 108 
 109 #define MAXDATASIZE 100 /* max number of bytes we can get at once */
 110 #define PORT 11111
 111 
 112 #define UP_AUTH_OK 0    /* Authorisation succeeded */
 113 #define ERROR_UP_MOR 1  /* Got more than one objects from the db, error */
 114 #define ERROR_UP_NSO 2  /* so such object */
 115 #define ERROR_UP_AUF 3  /* auth failed */
 116 #define ERROR_UP_NIY 4  /* not implemented yet */
 117 #define ERROR_UP_ABN 5  /* As-block does not exist */
 118 #define ERROR_UP_HOF 6  /* Hierarchical authorisation failed */
 119 #define ERROR_UP_OVF 7  /* override failed */
 120 #define ERROR_UP_OVS 8  /* override syntax error */
 121 #define ERROR_UP_INT 9  /* internal error */
 122 
 123 #define OVR_OK 0 /* override succeded */
 124 
 125 
 126 #define AU_MAIL_FROM 1
 127 #define AU_CRYPT_PW 2
 128 #define AU_PGP 3
 129 #define AU_NONE 4
 130 
 131 struct credentials{
 132    char * password;
 133    char * from;
 134    char * pgp_struct;
 135 };
 136 
 137 
 138 typedef struct _auth_struct{
 139   int type;
 140   char * auth;
 141   char * mntner_name;
 142   int index;
 143   char * pgp_struct;
 144 } auth_struct;
 145 
 146 int error = 0; // a global variable to store the errors
 147 char * error_msg = NULL; // a global variable to store the error messages
 148 
 149 
 150 /* sends the object to the database. char * operation is either 'ADD' or 'DEL' */
 151 void send_object_db(char * arg, char * operation){
     /* [<][>][^][v][top][bottom][index][help] */
 152 
 153         int sockfd, numbytes;  
 154         char buf[MAXDATASIZE];
 155         struct hostent *he;
 156         struct sockaddr_in their_addr; /* connector's address information */
 157 
 158         if ((he=gethostbyname("rowan")) == NULL) {  /* get the host info */
 159             perror("gethostbyname");
 160             exit(1);
 161         }
 162 
 163         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 164             perror("socket");
 165             exit(1);
 166         }
 167 
 168         their_addr.sin_family = AF_INET;      /* host byte order */
 169         their_addr.sin_port = htons(PORT);    /* short, network byte order */
 170         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 171         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 172 
 173 
 174         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 175                                               sizeof(struct sockaddr)) == -1) {
 176             perror("connect");
 177             exit(1);
 178         }
 179                 if (send(sockfd, operation , strlen(operation), 0) == -1)
 180                     perror("send");
 181                 if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
 182                     perror("send");
 183                 if (send(sockfd, arg , strlen(arg), 0) == -1)
 184                     perror("send");
 185                 if (send(sockfd, "\n",1,0)  == -1)
 186                     perror("send");
 187 
 188 
 189         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
 190             buf[numbytes] = '\0';
 191             printf("%s",buf);
 192             /*perror("recv");
 193             exit(1);*/
 194         }
 195 
 196         /*buf[numbytes] = '\0';
 197         printf("Received: %s",buf);*/
 198 
 199         close(sockfd);
 200 }
 201 
 202 
 203 
 204 
 205 
 206 
 207 /* takes a pre-parsed object, and returns its type */
 208 char * get_type(Object *arg){
     /* [<][>][^][v][top][bottom][index][help] */
 209     
 210     char * be_returned = NULL;
 211     if(arg == NULL) return NULL;
 212     be_returned = strdup(arg->type->getName());  
 213     return g_strstrip(be_returned);
 214 }
 215 
 216 
 217 
 218 
 219 
 220 
 221 /* takes an object (pre-parsed) and returns its first attrib if it is not
 222    a person, and returns the nic-hdl if it is a person object */
 223 char * get_search_key(Object *arg, char * type, char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 224 
 225     
 226     Attr *attr;    
 227     char *primary_key = NULL, *value = NULL;
 228 
 229     if(arg == NULL) return NULL;
 230 
 231           for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
 232             value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 233             strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 234                 attr->len - strlen(attr->type->name()) -2 );
 235             value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 236             //cout << "value: #" << value << "#" << endl;
 237             if(strcmp(attr->type->name(),type) == 0 &&
 238                strcmp(type,"person") != 0){
 239               primary_key = strdup(value);
 240             }
 241             if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
 242                strcmp(type,"person") == 0){
 243               primary_key = strdup(value);
 244             }
 245           }
 246    
 247     return g_strstrip(primary_key);
 248 }
 249 
 250 
 251 
 252 
 253 /* sends char * arg to the specified host's specified port, and
 254    returns the reply as a string */
 255 char * send_and_get(char * host, int port, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 256 
 257         int sockfd, numbytes; 
 258         char * result = NULL; 
 259         char buf[MAXDATASIZE];
 260         struct hostent *he;
 261         struct sockaddr_in their_addr; /* connector's address information */
 262 
 263         if ((he=gethostbyname(host)) == NULL) {  /* get the host info */
 264             perror("gethostbyname");
 265             exit(1);
 266         }
 267 
 268         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 269             perror("socket");
 270             exit(1);
 271         }
 272 
 273         their_addr.sin_family = AF_INET;      /* host byte order */
 274         their_addr.sin_port = htons(port);    /* short, network byte order */
 275         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 276         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 277 
 278 
 279         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 280                                               sizeof(struct sockaddr)) == -1) {
 281             perror("connect");
 282             exit(1);
 283         }
 284                 if (send(sockfd, arg , strlen(arg), 0) == -1)
 285                     perror("send");
 286                 if (send(sockfd, "\n",1,0)  == -1)
 287                     perror("send");
 288 
 289 
 290         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
 291             buf[numbytes] = '\0';
 292             if(result == NULL){
 293               result = strdup(buf);
 294             }else{
 295               result = (char *)realloc(result, strlen(result) + strlen(buf));
 296               result = strcat(result, buf);
 297             }
 298         }
 299 
 300         close(sockfd);
 301         return result;
 302 
 303 
 304 }
 305 
 306 /* counts the number of objects in a string */
 307 int count_objects(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 308     int count = 0;
 309     char *pos = NULL;
 310     char *temp = strdup(arg);
 311     
 312     if(isalpha(arg[0])){
 313       count++;
 314     }else if(arg[0] == '\n' && isalpha(arg[1])){
 315       count++;
 316     }
 317     while(pos = strstr(temp,"\n\n")){
 318       pos[0] = 'a'; // something non-EOL so that it won't be caught in the next loop
 319       if(isalpha(pos[2])){
 320         count++;
 321       }
 322     }
 323     cout << "DEBUG: count_objects returning " << count << endl;
 324     return count;
 325 }
 326 
 327 
 328 
 329 
 330 /*  */
 331 char * take_object(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 332     char * returned;
 333     char * object = NULL, * pos = NULL;
 334     char * temp = strdup(arg);
 335     
 336     if(isalpha(temp[0])){
 337       if(strstr(temp,"\n\n") == NULL){
 338         return temp;
 339       }else{
 340         pos = strstr(temp,"\n\n");
 341         pos[0] = '\0';
 342         return temp;
 343       }
 344     }else if(temp[0] == '\n' && isalpha(temp[1])){
 345       if(strstr(temp,"\n\n") == NULL){
 346         return (char *)temp[1];
 347       }else{
 348         pos = strstr(temp,"\n\n");
 349         pos[0] = '\0';
 350         return (char *)temp[1];
 351       }
 352     }else{
 353       temp = strstr(temp,"\n\n");
 354       temp = temp + 2;
 355       if(strstr(temp,"\n\n") == NULL){
 356         return temp;
 357       }else{
 358         pos = strstr(temp,"\n\n");
 359         pos[0] = '\0';
 360         return temp;
 361       }
 362     }
 363 }
 364 
 365 
 366 
 367 
 368 
 369 /* Takes an autnum_object, and returns the as-block containing this aut-num */
 370 char * get_as_block(char *autnum_object){
     /* [<][>][^][v][top][bottom][index][help] */
 371   bool code;
 372   char * search_key = NULL, * query_string = NULL;
 373   char * result = NULL;
 374   Object * o = new Object();
 375   
 376   code = o->scan(autnum_object, strlen(autnum_object));
 377   search_key = get_search_key(o,"aut-num",autnum_object);
 378   
 379   query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
 380   sprintf(query_string, "-Tas-block -r %s",search_key);
 381   result = send_and_get("reimp", 43, query_string);
 382   if(count_objects(result) == 0){
 383     cout << "No such as-block" << endl;
 384     return NULL;
 385   }else if(count_objects(result) > 1){
 386     cout << "More than one as-block returned" << endl;
 387     return NULL;
 388   }else{ // count_objects(result) == 1
 389     return take_object(result);
 390   }
 391   
 392 }
 393 
 394 
 395 
 396 
 397 
 398 /* Takes a domain_object, and returns the less specific domain of it */
 399 char * get_less_specific_domain(char *domain_object){
     /* [<][>][^][v][top][bottom][index][help] */
 400   bool code;
 401   char * search_key = NULL, * query_string = NULL;
 402   char * result = NULL, * domain = NULL;
 403   Object * o = new Object();
 404   int i,j, length;
 405   char * temp = NULL;
 406   char ** splitted;
 407 
 408   code = o->scan(domain_object, strlen(domain_object));
 409   domain = get_search_key(o,"domain",domain_object);
 410 
 411   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
 412   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
 413 
 414   for(i=1; splitted[i] != NULL; i++){
 415     /* in the following for loop, we will construct the 'less spec' domains
 416        to be looked up in the DB */ 
 417     for(j=i; splitted[j] !=NULL; j++){
 418       length = 0;
 419       if(temp!=NULL){
 420         length = strlen(temp); 
 421       }
 422       temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2); 
 423       if(j==i){
 424         temp = (char *)strdup(splitted[j]);
 425       }else{
 426         sprintf(temp, "%s.%s", temp, splitted[j]);
 427       }
 428     }
 429     query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
 430     sprintf(query_string, "-Tdomain -r -R %s", temp);
 431     result = send_and_get("reimp", 43, query_string);
 432     if(count_objects(result) == 0){
 433     }else if(count_objects(result) > 1){
 434       cout << "DEBUG: get_less_specific_domain: More than one domains returned" << endl;
 435       return NULL; /* error condition */
 436     }else{ /* count_objects(result) == 1 */
 437       return take_object(result);
 438     }
 439     
 440   }
 441   /* release the memory allocated to **splitted */
 442   for(i=0; splitted[i] != NULL; i++){ 
 443     free(splitted[i]);
 444   }  
 445   /* so, we couldn't  find any 'less specific' domain */
 446   return NULL;
 447 }
 448 
 449 
 450 
 451 
 452 
 453 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
 454    by striping down the object's name ( eg, for as35:rs-trial:rs-myset, 
 455    as35:rs-trial is tried ) */
 456 char * get_less_specific_set(char *set_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 457   bool code;
 458   char * search_key = NULL, * query_string = NULL;
 459   char * result = NULL;
 460   Object * o = new Object();
 461   int i;
 462   
 463   code = o->scan(set_object, strlen(set_object));
 464   search_key = get_search_key(o, type, set_object);
 465   delete(o);
 466 
 467   for(i = strlen(search_key) -1; i > -1; i--){
 468     if(search_key[i] == ':'){
 469       search_key[i] = '\0'; /* truncate the string */
 470       break;
 471     }
 472     if(i == 0){/* if we've reached the beginning of the string 
 473                 (this means there wasn't any ';' in the string) */
 474       free(search_key);
 475       search_key = NULL;
 476     }
 477   }
 478   if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since 
 479                                                         we make sure that the name of the 
 480                                                         set_object contains a ':' in a proper place */
 481     return NULL;
 482   }
 483 
 484    
 485   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
 486   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r  %s", search_key);
 487   result = send_and_get("reimp", 43, query_string);
 488   if(count_objects(result) == 0){
 489     cout << "No such object"  << endl;
 490     return NULL;
 491   }else if(count_objects(result) > 1){
 492     cout << "More than one objects returned" << endl;
 493     return NULL;
 494   }else{ // count_objects(result) == 1
 495     return take_object(result);
 496   }
 497   
 498 }
 499 
 500 
 501 
 502 
 503 
 504 
 505 
 506 /* Takes an inetnum or inet6num object and returnes one less specific of it */
 507 char * get_less_specific(char *inetnum_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 508   bool code;
 509   char * search_key = NULL, * query_string = NULL;
 510   char * result = NULL;
 511   Object * o = new Object();
 512   
 513   code = o->scan(inetnum_object, strlen(inetnum_object));
 514   search_key = get_search_key(o, type, inetnum_object);
 515   
 516   query_string = (char *)malloc(strlen("-Tinet6num -r -l")+strlen(search_key)+1);
 517   sprintf(query_string, "-T%s -r -l %s",type, search_key);
 518   result = send_and_get("reimp", 43, query_string);
 519   if(count_objects(result) == 0){
 520     cout << "No such " << type << endl;
 521     return NULL;
 522   }else if(count_objects(result) > 1){
 523     cout << "More than one " << type << " returned" << endl;
 524     return NULL;
 525   }else{ // count_objects(result) == 1
 526     return take_object(result);
 527   }
 528   
 529 }
 530 
 531 
 532 
 533 
 534 /* Gets an object as a string and returns its 'mnt-by' attributes as a 
 535    GSList (linked list)   */
 536 
 537 GSList *get_mntners(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
 538   bool code;
 539   Object * o;
 540   Attr *attr;
 541   char *value  = NULL;
 542   GSList *list_of_mntners = NULL;
 543 
 544 
 545   cout << "DEBUG: get_mntners is running" << endl;
 546   o = new Object;
 547   code = o->scan(object,strlen(object));
 548   
 549   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 550     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 551     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 552         attr->len - strlen(attr->type->name()) -2 );
 553     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 554     //cout << "value: #" << value << "#" << endl;
 555     if(strcmp(attr->type->name(),"mnt-by") == 0){
 556       cout << "DEBUG: get_mntners: adding " << g_strstrip(value) << endl;
 557       list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
 558     }
 559   }
 560 
 561 
 562   return list_of_mntners; 
 563 }
 564 
 565 
 566 
 567 
 568 
 569 /* Gets a (maintainer) object as a string and returns its 'auth' attributes 
 570    as a GSList (linked list) */
 571 
 572 GSList *get_auths(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
 573   bool code;
 574   Object * o;
 575   Attr *attr;
 576   char *value  = NULL;
 577   GSList *list_of_auths = NULL;
 578 
 579 
 580   cout << "DEBUG: get_auths is running" << endl;
 581   o = new Object;
 582   code = o->scan(object,strlen(object));
 583   
 584   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 585     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 586     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 587         attr->len - strlen(attr->type->name()) -2 );
 588     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 589     //cout << "value: #" << value << "#" << endl;
 590     if(strcmp(attr->type->name(),"auth") == 0){
 591       cout << "DEBUG: get_auths: adding " << g_strstrip(value) << endl;
 592       list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
 593       cout << "DEBUG: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
 594     }
 595   }
 596 
 597   cout << "DEBUG: get_auths: returning" << endl;
 598   return list_of_auths; 
 599 }
 600 
 601 
 602 
 603 
 604 
 605 /* Gets an object as a string an returns its mnt_lower attributes as a 
 606    GSList (linked list) */
 607 
 608 GSList *get_mnt_lowers(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
 609   bool code;
 610   Object * o;
 611   Attr *attr;
 612   char *value  = NULL;
 613   GSList *list_of_mnt_lowers = NULL;
 614 
 615 
 616   cout << "DEBUG: get_mnt_lowers is running" << endl;
 617   o = new Object;
 618   code = o->scan(object,strlen(object));
 619   
 620   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 621     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 622     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 623         attr->len - strlen(attr->type->name()) -2 );
 624     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 625     //cout << "value: #" << value << "#" << endl;
 626     if(strcmp(attr->type->name(),"mnt-lower") == 0){
 627       cout << "DEBUG: get_mnt_lowers: adding " << g_strstrip(value) << endl;
 628       list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
 629     }
 630   }
 631 
 632 
 633   return list_of_mnt_lowers; 
 634 }
 635 
 636 
 637 
 638 
 639 
 640 /* retrieves the override password from the 'override' attribute  
 641    of the object. If none, it returns NULL   */
 642 char *get_override(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
 643   bool code;
 644   Object * o;
 645   Attr *attr;
 646   char *value  = NULL;
 647 
 648 
 649   cout << "DEBUG: get_override is running" << endl;
 650   o = new Object;
 651   code = o->scan(object,strlen(object));
 652   
 653   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 654     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 655     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 656         attr->len - strlen(attr->type->name()) -2 );
 657     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 658     //cout << "value: #" << value << "#" << endl;
 659     if(strcmp(attr->type->name(),"override") == 0){
 660       cout << "DEBUG: get_override: returning " << g_strstrip(value) << endl;
 661       return  strdup(g_strstrip(value));
 662     }
 663   }
 664   /* there was no 'override' attrib, so return NULL */
 665   return NULL; 
 666 }
 667 
 668 
 669 
 670 
 671 
 672 
 673 /* checks override string (password) 
 674    returns OVR_OK if it is correct password */
 675 int check_override(char * string){
     /* [<][>][^][v][top][bottom][index][help] */
 676    return OVR_OK; // for now
 677 }
 678 
 679 
 680 
 681 
 682 
 683 
 684 
 685 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
 686    add new elements to GSList of struct auth_struct and  returns the new
 687    GSList of struct auth_struct  */
 688 
 689 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
     /* [<][>][^][v][top][bottom][index][help] */
 690    //GSList * to_be_returned = NULL;
 691    GSList * next;
 692    char * auth_attrib = NULL;
 693    char * auth_attrib_uppercase = NULL, * argument = NULL;
 694    struct auth_struct * temp = NULL;
 695    int index = 1;
 696       
 697    for(next = auths; next != NULL; next = g_slist_next(next)){
 698      auth_attrib = strdup((char *)next->data);
 699      auth_attrib = g_strstrip(auth_attrib);
 700      cout << "DEBUG: add_to_auth_vector: " << auth_attrib << endl;
 701      /* Take the auth attribute and convert it into uppercase for comparisons */
 702      auth_attrib_uppercase = strdup(auth_attrib);
 703      g_strup(auth_attrib_uppercase);
 704      
 705      if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
 706        /* take the argument of the auth attribute */
 707        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
 708        g_strstrip(argument);
 709        cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
 710        temp = (struct auth_struct *)malloc(sizeof(auth_struct));
 711        temp->type = AU_CRYPT_PW;
 712        temp->auth = argument;
 713        temp->mntner_name = mntner_name;
 714        temp->index = index++;
 715        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
 716      }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
 717        /* take the argument of the auth attribute */
 718        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
 719        g_strstrip(argument);
 720        cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
 721        temp = (struct auth_struct *)malloc(sizeof(auth_struct));
 722        temp->type = AU_MAIL_FROM;
 723        temp->auth = argument;
 724        temp->mntner_name = mntner_name;
 725        temp->index = index++;
 726        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
 727     }else if(strstr(auth_attrib_uppercase,"PGP-") == auth_attrib_uppercase){
 728        temp = (struct auth_struct *)malloc(sizeof(auth_struct));
 729        temp->type = AU_PGP;
 730        temp->mntner_name = mntner_name;
 731        temp->index = index++;
 732        /* temp->pgp_struct must be assigned, not yet implemented */
 733        cout << "Not implemented totally (PGP)" << endl;
 734      }else{
 735        cout << "Error: invalid auth attrib: " << auth_attrib << endl;
 736        return NULL;
 737      }
 738    }
 739    free(auth_attrib_uppercase);
 740    free(auth_attrib); 
 741    return list_of_auth_struct;
 742 
 743 }
 744 
 745 
 746 
 747 
 748 
 749 
 750 
 751 
 752 
 753 
 754 /* constructs the authorisation vector, which is a GSList of
 755    struct auth_struct */
 756 
 757 GSList * get_auth_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
 758   GSList * list_of_auths = NULL;
 759   GSList * next = NULL;
 760   GSList * to_be_returned = NULL;
 761   char * query_string = NULL, * result = NULL, * object = NULL;
 762   GSList * temp;
 763 
 764   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
 765     cout << "=====" << endl << "Got a mntner" << endl;
 766     cout << (char *)next->data << endl;
 767     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
 768     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
 769     result = send_and_get("reimp", 43, query_string);
 770     if(count_objects(result) == 0){
 771       cout << "No such maintainer, exiting" << endl;
 772       exit(1);
 773     }else if(count_objects(result) > 1){
 774       cout << "More than one objects returned" << endl;
 775     }else{ /* count_objects(result) == 1 */
 776       object = take_object(result);
 777       cout << "DEBUG: get_auth_vector: Calling get_auths(char *)" << endl;
 778       temp = get_auths(object);
 779       cout << "DEBUG: get_auth_vector: get_auths(char *) returned" << endl;
 780       list_of_auths = g_slist_concat(list_of_auths, temp);
 781       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
 782     }
 783   }
 784   
 785   return to_be_returned; 
 786 }
 787 
 788 
 789 
 790 
 791 
 792 
 793 
 794 
 795 /* Check authorisation
 796    Applies authorisation rules according to the object type */
 797 
 798 int check_auth(char *new_object, char *old_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 799    
 800    GSList *old_mntners = NULL, *new_mntners = NULL;
 801    GSList *old_auths = NULL, *new_auths = NULL;
 802    GSList *as_block_mnt_lowers = NULL;
 803    GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
 804    GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
 805    GSList *less_specific_mntners = NULL;
 806    
 807    char *as_block_object = NULL, *less_specific_object = NULL;
 808    char *less_specific_domain = NULL;
 809    char *less_specific_object_type = NULL;
 810    int overriden = 0;
 811    char *override_string = NULL;
 812    char *set_name = NULL;
 813    Object *set_object = new Object();
 814    Object *temp_obj;
 815    bool code;
 816    
 817    /* first check if it is overriden or not. if overriden, check the override
 818       password. If it is correct, continue, setting "overriden" to 1. If not,   
 819       immediately exit returning ERR_UP_OVF                                   */
 820    override_string = get_override((new_object == NULL) ? old_object : new_object );
 821    if(override_string == NULL){ 
 822      overriden = 0;
 823    }else if(check_override(override_string) == OVR_OK){
 824      overriden = 1; // authorisation is overriden
 825    }else if(check_override(override_string) == ERROR_UP_OVS){
 826      return ERROR_UP_OVS; // override syntax error --it must have at least two words
 827    }else{
 828      return ERROR_UP_OVF; // override failed!
 829    }
 830 
 831 
 832    /*  
 833     *  Handle the "person", "role", "limerick", "inet-rtr" types 
 834     */
 835    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
 836       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ){
 837      if( new_object == NULL && old_object != NULL ){ // the object is to be deleted
 838        old_mntners = get_mntners(old_object);
 839        old_auth_vector = get_auth_vector(old_mntners);
 840        //return authorise(old_auth_vector, overriden, ...);
 841      }else if( new_object != NULL && old_object == NULL ){ // the object is to be created
 842        new_mntners = get_mntners(new_object);
 843        new_auth_vector = get_auth_vector(new_mntners);
 844        //return authorise(new_auth_vector, overriden, ...);
 845      }else if( new_object != NULL && old_object != NULL ){ // this is an update
 846        old_mntners = get_mntners(old_object);
 847        old_auth_vector = get_auth_vector(old_mntners);
 848        if(old_auth_vector){ // if we have mntners in the old object, use them
 849          //return authorise(old_auths_vector, overriden, ...);
 850        }else{
 851          new_mntners = get_mntners(new_object);
 852          new_auth_vector = get_auth_vector(new_mntners);
 853          //return authorise(new_auth_vector, overriden, ...);
 854        }
 855      }else{ // both are NULL, mustn't happen
 856          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
 857          return ERROR_UP_INT; /* internal error */
 858      }
 859    }
 860 
 861    /*  
 862     *  Handle the "auth-num" type 
 863     */
 864    else if(strcmp(type,"aut-num")  == 0 ){
 865      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
 866        old_mntners = get_mntners(old_object);
 867        old_auth_vector = get_auth_vector(old_mntners);
 868        //return authorise(old_auth_vector, overriden, ...);
 869      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
 870        as_block_object = get_as_block(new_object);
 871        if(as_block_object == NULL ){
 872          return ERROR_UP_ABN; /* As-block does not exist */
 873        }else{
 874          as_block_mnt_lowers = get_mnt_lowers(as_block_object);
 875          as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
 876          if(1/* authorise(as_block_auth_vector, overriden, ...) == UP_AUTH_OK */){
 877            new_mntners = get_mntners(new_object);
 878            new_auth_vector = get_auth_vector(new_mntners);
 879            //return authorise(new_auth_vector, overriden, ...);
 880          }else{
 881            return ERROR_UP_HOF; /* hierarchical auth failed */
 882          }
 883        }
 884      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
 885        old_mntners = get_mntners(old_object);
 886        old_auth_vector = get_auth_vector(old_mntners);
 887        if(old_auth_vector){ /* if we have mntners in the old object, use them */
 888          //return authorise(old_auth_vector, overriden, ...);
 889        }else{
 890          new_mntners = get_mntners(new_object);
 891          new_auth_vector = get_auth_vector(new_mntners);
 892          //return authorise(new_auth_vector, overriden, ...);
 893        }
 894      }else{ /* both are NULL, mustn't happen */
 895          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
 896          return ERROR_UP_INT; /* internal error */
 897      }
 898    } 
 899 
 900    /*  
 901     *  Handle the "mntner/as-block" types 
 902     */
 903    else if(strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 ){
 904      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
 905        old_mntners = get_mntners(old_object);
 906        old_auth_vector = get_auth_vector(old_mntners);
 907        //return authorise(old_auth_vector, overriden, ...);
 908      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
 909        if(overriden){
 910          return UP_AUTH_OK; 
 911        }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
 912          cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
 913        }
 914      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
 915        old_mntners = get_mntners(old_object);
 916        old_auth_vector = get_auth_vector(old_mntners);
 917        if(old_auth_vector){ /* if we have mntners in the old object, use them */
 918          //return authorise(old_auth_vector, overriden, ...);
 919        }else{
 920          new_mntners = get_mntners(new_object);
 921          new_auth_vector = get_auth_vector(new_mntners);
 922          //return authorise(new_auth_vector, overriden, ...);
 923        }
 924      }else{ // both are NULL, mustn't happen
 925          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
 926          return ERROR_UP_INT; /* internal error */
 927      }
 928    }
 929 
 930    /*  
 931     *  Handle the "inetnum/inet6num" types 
 932     */
 933    else if(strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 ){
 934      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
 935        old_mntners = get_mntners(old_object);
 936        old_auth_vector = get_auth_vector(old_mntners);
 937        //return authorise(old_auth_vector, overriden, ...);
 938      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
 939        less_specific_object = get_less_specific(new_object, type);
 940        if(less_specific_object == NULL){
 941          if(overriden){
 942            return UP_AUTH_OK; 
 943          }else{
 944            return ERROR_UP_HOF; /* hierarchical authorisation failed */
 945          }
 946        }else{ /* if we got an inet(6)num object */
 947          less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
 948          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
 949          if(1/* authorise(less_specific_auth_vector, overriden, ...) == UP_AUTH_OK */){
 950            new_mntners = get_mntners(new_object);
 951            new_auth_vector = get_auth_vector(new_mntners);
 952            //return authorise(new_auth_vector, overriden, ...);
 953          }else{
 954            return ERROR_UP_HOF; /* hierarchical authorisation failed */
 955          }
 956        }
 957      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
 958        old_mntners = get_mntners(old_object);
 959        old_auth_vector = get_auth_vector(old_mntners);
 960        if(old_auth_vector){ // if we have mntners in the old object, use them
 961          //return authorise(old_auth_vector, overriden, ...);
 962        }else{
 963          new_mntners = get_mntners(new_object);
 964          new_auth_vector = get_auth_vector(new_mntners);
 965          //return authorise(new_auth_vector, overriden, ...);
 966        }
 967      }else{ // both are NULL, mustn't happen
 968          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
 969          return ERROR_UP_INT; /* internal error */
 970      }
 971    }
 972 
 973 
 974    
 975    /*  
 976     *  Handle the "domain" type 
 977     */
 978    else if(strcmp(type,"domain")  == 0){
 979      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
 980        old_mntners = get_mntners(old_object);
 981        old_auth_vector = get_auth_vector(old_mntners);
 982        //return authorise(old_auth_vector, overriden, ...);
 983      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
 984        /* now, we have to find a 'less specific domain object' for this. 
 985           If there is no less specific object, then creation is possible
 986           only with overriding. */
 987       less_specific_domain = get_less_specific_domain(new_object);
 988       if(less_specific_domain == NULL){
 989         if(overriden){/* we didn't get a 'less specific' domain object */
 990            return UP_AUTH_OK; 
 991          }else{
 992            return ERROR_UP_HOF; /* hierarchical authorisation failed */
 993          }
 994       }else{ /* we get a 'less specific' domain object */
 995          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
 996          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
 997          if(1/* authorise(less_specific_auth_vector, overriden, ...) == UP_AUTH_OK */){
 998            new_mntners = get_mntners(new_object);
 999            new_auth_vector = get_auth_vector(new_mntners);
1000            //return authorise(new_auth_vector, overriden, ...);
1001          }else{
1002            return ERROR_UP_HOF; /* hierarchical authorisation failed */
1003          }
1004         
1005       }
1006      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1007        old_mntners = get_mntners(old_object);
1008        old_auth_vector = get_auth_vector(old_mntners);
1009        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1010          //return authorise(old_auth_vector, overriden, ...);
1011        }else{
1012          new_mntners = get_mntners(new_object);
1013          new_auth_vector = get_auth_vector(new_mntners);
1014          //return authorise(new_auth_vector, overriden, ...);
1015        }
1016      }else{ // both are NULL, mustn't happen
1017          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1018          return ERROR_UP_INT; /* internal error */
1019      }
1020    }
1021    
1022 
1023    /*  
1024     *  Handle the set objects ("as-set","rtr-set","peering-set" and "filter-set" types 
1025     */
1026    else if(strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
1027            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ){
1028      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1029        old_mntners = get_mntners(old_object);
1030        old_auth_vector = get_auth_vector(old_mntners);
1031        //return authorise(old_auth_vector, overriden, ...);
1032      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1033         code = set_object->scan(new_object, strlen(new_object));
1034         set_name = get_search_key(set_object, type, new_object);
1035        if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
1036          new_mntners = get_mntners(new_object);
1037          new_auth_vector = get_auth_vector(new_mntners);
1038          //return authorise(new_auth_vector, overriden, ...);
1039        }else{/* the name is hierarchical */
1040          less_specific_object = get_less_specific_set(new_object, type);
1041          if(less_specific_object != NULL){/* such an object exists */
1042            temp_obj = new Object();
1043            code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
1044            less_specific_object_type = get_type(temp_obj);
1045            delete(temp_obj);
1046            if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
1047              less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1048              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1049              if(less_specific_auth_vector != NULL){
1050                //return authorise((less_specific_auth_vector, overriden, ...);
1051              }else{/* the less specific object doesn't contain any mnt-lower */
1052                less_specific_mntners = get_mntners(less_specific_object);
1053                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
1054                if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs, 
1055                                                         use them  */
1056                    //return authorise((less_specific_auth_vector, overriden, ...);
1057                }else{/* the less specific object doesn't contain any mnt-by either */
1058                  if(overriden){
1059                    return UP_AUTH_OK; 
1060                  }else{
1061                    return ERROR_UP_HOF; /* hierarchical authorisation failed */
1062                  }
1063                }
1064              }
1065            }else{ /* this is _not_ an aut-num object*/
1066              less_specific_mntners = get_mntners(less_specific_object);
1067              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
1068              if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
1069                //return authorise((less_specific_auth_vector, overriden, ...);
1070              }else{
1071                if(overriden){
1072                  return UP_AUTH_OK; 
1073                }else{
1074                  return ERROR_UP_HOF; /* hierarchical authorisation failed */
1075                }
1076              }
1077            }
1078 
1079          }else{/* we don't have a less specific of this set object in the DB  */
1080            return ERROR_UP_HOF; /* hierarchical authorisation failed */
1081          }
1082        }
1083      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1084        old_mntners = get_mntners(old_object);
1085        old_auth_vector = get_auth_vector(old_mntners);
1086        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1087          //return authorise(old_auth_vector, overriden, ...);
1088        }else{
1089          new_mntners = get_mntners(new_object);
1090          new_auth_vector = get_auth_vector(new_mntners);
1091          //return authorise(new_auth_vector, overriden, ...);
1092        }
1093      }else{ /* both are NULL, mustn't happen */
1094          cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1095          return ERROR_UP_INT; /* internal error */
1096      }
1097    
1098 
1099 
1100 
1101 
1102    }else{ /* other types are not implemented yet */
1103      cout << "check_auth: This type '" << type << "' is not implemented yet" << endl;
1104      return ERROR_UP_NIY; /* not implemented yet */
1105    }
1106    return UP_AUTH_OK; // for now
1107 }
1108 
1109 
1110 
1111 
1112 
1113 
1114 /* Gets the old version of the given "arg" object, which is in char * format
1115    and returns the old version again in char * format */
1116 
1117 char * get_old_version(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
1118 
1119     bool code = true;
1120     char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
1121     Object *o;
1122     o = new Object;
1123     char *result = NULL;
1124     
1125      
1126     code = o->scan(arg,strlen(arg));
1127     type = get_type(o);
1128     primary_search_key = get_search_key(o,type, arg);
1129     cout << "type=" << type << endl;
1130     cout << "primary_search_key=" << primary_search_key << endl;
1131     // prepare the search string
1132     search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
1133                                           + strlen(type) + 1);
1134     sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
1135     result = send_and_get("reimp", 43, search_string);
1136     cout << "send_and_get returned (with search '"<< search_string <<"'): " << endl 
1137          << result << endl;
1138     // count the objects
1139     if(count_objects(result) == 0){
1140       result = NULL; // we don't have any object
1141     }else if(count_objects(result) == 1){
1142       result = take_object(result);
1143       cout << "DEBUG: Take_object returned ***\n" << result << "***" << endl;
1144     }else{ // we have more than one objects, error!
1145       error = ERROR_UP_MOR;
1146       return NULL;
1147     }
1148     return result;
1149 }
1150 
1151 
1152 
1153 
1154 
1155 
1156 int process_object(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
1157     bool code = true;
1158     Object *o;
1159     char * old_version = NULL;
1160     o = new Object;
1161     code = o->scan(arg,strlen(arg));
1162     if(code){
1163       if(o->isDeleted){ 
1164         old_version = get_old_version(arg);
1165         if(old_version == NULL){ // the object doesn't exist in the db!
1166           return ERROR_UP_NSO; /* no such object */
1167         }else
1168         if(check_auth(NULL, old_version, o->type->getName()) == UP_AUTH_OK){ // check_auth will know that this is a deletion
1169           cout << "DEBUG: Will send the obj to be deleted" << endl;
1170           //send_object_db(arg,"DEL");
1171         }else{
1172           //auth failed !
1173           cout << error_msg << endl;
1174           return ERROR_UP_AUF; /* Auth failed */
1175         }
1176       }else{
1177         old_version = get_old_version(arg);
1178         if(check_auth(arg, old_version,o->type->getName() ) == UP_AUTH_OK){ // note: if the obj is to-be-created, 
1179                                           //        old_version becomes NULL
1180           cout << "DEBUG: Will send the obj to be added/updated" << endl;
1181           //send_object_db(arg,"ADD");
1182         }else{
1183           // auth failed !
1184           cout << error_msg << endl;
1185           return ERROR_UP_AUF; /* Auth failed */
1186         }
1187       }
1188     }else{// even if obj doesn't parse properly, it may be a legacy object
1189           // which the user wants to delete...
1190        return ERROR_UP_NIY; /* Not implemented yet */
1191     }
1192 }
1193 
1194 
1195 
1196 
1197 
1198 
1199 void main(int argc, char **argv, char **envp){
     /* [<][>][^][v][top][bottom][index][help] */
1200   schema.initialize();
1201   //init_and_set_options(argc, argv, envp);
1202 
1203   int count = 0;
1204 
1205   
1206   char *line;
1207   char *object = NULL;
1208   char *password = NULL;
1209   GSList *list_of_objects = NULL, *next = NULL;
1210   
1211   object = NULL;
1212   
1213   line = (char *)malloc(1024);
1214 
1215   while(fgets(line, 1024,stdin ) != NULL){
1216     /* first, if it is a pasword, save it, but do not regard it as an attrib */ 
1217     if(strstr(line, "password:") == line){
1218       cout << "This is a password" << endl;
1219       free(password);
1220       password = strdup(line + strlen("password:"));
1221       continue;
1222     }
1223     if(strlen(line) == 1){
1224        cout << endl;
1225        if(object != NULL){
1226          cout << "The object was" << endl << object << endl;
1227          list_of_objects = g_slist_append(list_of_objects, object);
1228          //free(object);
1229          object = NULL;
1230        }
1231     }else{
1232       /* if the line contains only the EOL char */
1233       if(object == NULL && strlen(line) != 1){
1234         object = (char *)malloc(strlen(line));
1235         object = strdup(line);
1236       }
1237       else{
1238         object = (char *)realloc(object, strlen(object) + strlen(line));
1239         object = strcat(object, line);
1240       }
1241     }
1242       
1243   }
1244 
1245   if(password != NULL){
1246     password = g_strstrip(password);
1247     cout << "This was the password: " << password << endl;
1248   }
1249 
1250   cout << "Now, printing out the objects in the list " << endl;
1251   next = list_of_objects;
1252   for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
1253     cout << "=====" << endl << "Got a member" << endl;
1254     cout << (char *)next->data << endl;
1255     process_object((char *)next->data);
1256     cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
1257   }
1258 
1259 
1260 }

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