bin/dbupdate/dbupdate.c

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

FUNCTIONS

This source file includes following functions.
  1. error_init
  2. delete_key
  3. import_key
  4. get_keyowner_fingerpr
  5. process_object
  6. process_file
  7. generate_upd_file
  8. create_lock_file
  9. remove_lock_file
  10. write_checkpoint
  11. remove_checkpoint
  12. main

   1 /***************************************
   2   $Revision: 1.15 $
   3 
   4   DBupdate 
   5 
   6   Status: PARTIALLY REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (01/03/2000) Created.
  13                 denis (31/08/2001) Modified for new API
  14   ******************/ /******************
  15   Copyright (c) 2001,2002                         RIPE NCC
  16 
  17   All Rights Reserved
  18 
  19   Permission to use, copy, modify, and distribute this software and its
  20   documentation for any purpose and without fee is hereby granted,
  21   provided that the above copyright notice appear in all copies and that
  22   both that copyright notice and this permission notice appear in
  23   supporting documentation, and that the name of the author not be
  24   used in advertising or publicity pertaining to distribution of the
  25   software without specific, written prior permission.
  26 
  27   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  28   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  29   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  30   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  31   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  32   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33  ***************************************/
  34 
  35 
  36 
  37 
  38 #include <config.h>
  39 #include "dbupdate.h"
  40 #include "UP_extrnl_syntax.h"
  41 #include "UP_subject.h"
  42 #include "er_yacc_helper.h"
  43 #include "erroutines.h"
  44 #include "ca_configFns.h"
  45 #include "ca_dictionary.h"
  46 #include "ca_macros.h"
  47 #include "ca_srcAttribs.h"
  48 #include "notification.h"
  49 #include "gpg.h"
  50 #include "mail_parser.h"
  51 #include "process.h"
  52 
  53 #ifdef HAVE_SYS_PARAM_H
  54 #include <sys/param.h>
  55 #endif
  56 
  57 
  58 int tracing = 0;
  59 int test_mode = 0;
  60 int supress_ack_notif = 0;
  61 int print_out_ack = 0;
  62 
  63 /* do we process a mail */
  64 int reading_from_mail = 0;
  65 
  66 /* are we processing networkupdate? */
  67 int networkupdate = 0;
  68 
  69 /* IP of the networkupdate client */
  70 char * netupdclientIP = NULL;
  71 
  72 /* two global variables to tally the processed objects */
  73 int count_successful = 0;
  74 int count_unsuccessful = 0;
  75 
  76 
  77 /* sender of the mail, in case of a mail update */
  78 char *update_mail_sender = NULL;
  79 char *update_mail_subject = NULL;
  80 char *update_mail_date = NULL;
  81 char *update_mail_ID = NULL;
  82 char *update_mail_cc = NULL;
  83 
  84 /* re-direct to humail message */
  85 char *header_type = NULL;
  86 char *text_type = NULL;
  87 
  88 /* required configuration variables */
  89 char *tmpdir = NULL;
  90 char *lockdir = NULL;
  91 char *mailcmd = NULL;
  92 char *notitxt = NULL;
  93 char *successtxt = NULL;
  94 char *failuretxt = NULL;
  95 char *helpheader = NULL;
  96 char *notimailtxt = NULL;
  97 char *notinetworktxt = NULL;
  98 char *fwtxt   = NULL;
  99 char *fwmailtxt = NULL;
 100 char *mtfwheader = NULL; 
 101 char *mtfwtxt = NULL;
 102 char *mailtxt = NULL;
 103 char *acksig = NULL;
 104 char *defmail = NULL;
 105 char *updlog = NULL;
 106 char *notiflog = NULL;
 107 char *crosslog = NULL;
 108 char *acklog = NULL;
 109 char *forwlog = NULL;
 110 char *humailbox = NULL;
 111 char *autobox = NULL;
 112 char *copyright_notice = NULL;
 113 char *overridecryptedpw = NULL;
 114 char *country = NULL;
 115 char *countries[400];
 116 char *nicsuffixes[7];
 117 char *sources[100];
 118 char *pgppath = NULL;
 119 char *gpgcmd = NULL;
 120 char *pgp_public_key_ring = NULL;
 121 char *autodbmhelp = NULL; 
 122 char *update_host = NULL;
 123 int  update_port;
 124 char *query_host = NULL;
 125 int  query_port;
 126 char *cn_subject_add = NULL;
 127 char *cn_subject_del = NULL;
 128 char *cn_explain_add = NULL;
 129 char *cn_explain_del = NULL;
 130 char *cn_overlap_add = NULL;
 131 char *cn_overlap_del = NULL;
 132 char *cno_subject_add = NULL;
 133 char *cno_subject_del = NULL;
 134 char *cno_explain_add = NULL;
 135 char *cno_explain_del = NULL;
 136 char *cno_overlap_add = NULL;
 137 char *cno_overlap_del = NULL;
 138 char *allocmnt = NULL;
 139 char *mheader = NULL;
 140 char *DBhost = NULL;
 141 int  DBport;
 142 char *DBuser = NULL;
 143 char *DBname = NULL;
 144 char *DBpasswd = NULL;
 145 /* end of config variables */
 146 
 147 char * fingerprint = NULL;
 148 char * keyowner = NULL;
 149 
 150 /* result of subject line processing is kept in the following struct. */
 151 up_subject_struct subject_result;
 152 
 153 
 154 /* hostname and pid are used all over the program, so we save them into these variables */
 155 char hostname[MAXHOSTNAMELEN];
 156 /* char * hostname; */
 157 int pid;
 158 
 159 /* name of the lock file, which is used for the crash recovery mechanism */
 160 char * lock_file_name;
 161 
 162 void error_init(int argc, char ** argv) {
     /* [<][>][^][v][top][bottom][index][help] */
 163 
 164   ER_init("dbupdate", 1);
 165   
 166 
 167 } /* error_init() */
 168 
 169 
 170 
 171 
 172 
 173 
 174 /* 'lockfile' struct is for keeping both the name of the lock file and the file descriptor
 175     of it, which is open during the execution of dbupdate. We need the filedes to close it,
 176     when dbupdate finishes, and the name to delete the file. */
 177 typedef struct {
 178    char * lockname;
 179    int filedes;
 180 } lockfilestruct;
 181 
 182 
 183 lockfilestruct lockfile;
 184 
 185 
 186 
 187 /* Deletes the key defined in the incoming object (a key-cert object)
 188    from the public keyring. Returns NULL if there was no error,
 189    returns an error message if there is an error */
 190 char *delete_key(rpsl_object_t * obj)
     /* [<][>][^][v][top][bottom][index][help] */
 191 {
 192   struct ImportKeyObject iKO;
 193   char * obj_keyID;
 194   char * key_cert_attr;
 195   GList * templist;
 196   GList * certiflist, * next;
 197   u32 keyID;
 198   char * key_file_name;
 199   char ** lines;
 200   int i;
 201   FILE * key_file;
 202   char * temp, * temp2;
 203   char * error_string;
 204   rpsl_attr_t *attr;
 205 
 206   templist = get_attr_list(obj, "key-cert");
 207   attr = (rpsl_attr_t *)(templist->data);
 208   key_cert_attr = strdup((char *)(attr->value));
 209 /*  key_cert_attr = strdup( (char *)( ((rpsl_attr_t *)(templist->data))->value ) );  */
 210   rpsl_attr_delete_list(templist);
 211 
 212   key_file_name = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
 213   sprintf(key_file_name, "%s/tmp-key.%i", tmpdir, pid);
 214 
 215   /* now we must write certif attribute(s) of this key-certif into the key_file_name */
 216   /* get the certif first */
 217   certiflist = get_attr_list(obj, "certif");
 218   if (( key_file = fopen(key_file_name, "w")) == NULL)
 219   {
 220      ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", key_file_name);
 221      exit(1);
 222   }
 223   for ( next = certiflist; next != NULL ; next = g_list_next(next) )
 224   {
 225     attr = (rpsl_attr_t *)(next->data);
 226     lines = g_strsplit((char *)(attr->value), "\n", 0);
 227     if (lines[0] == NULL)
 228         { /* if this was an empty attribute, just print an empty line */
 229       fprintf(key_file, "\n"); 
 230     }
 231     for (i = 0; lines[i] != NULL; i++)
 232         {
 233       temp = strdup(lines[i]);
 234       if (i != 0 && temp[0] == '+')
 235           { /* if it begins with a plus */
 236         temp2 = strdup(temp + 1);
 237         g_strstrip(temp2);
 238         fprintf(key_file, "%s\n", temp2);
 239         free(temp);free(temp2);
 240       }
 241           else
 242           {
 243         g_strstrip(temp);
 244         fprintf(key_file, "%s\n", temp);
 245         free(temp); 
 246       }
 247     }
 248     g_strfreev(lines);
 249   }
 250   fclose(key_file);
 251   rpsl_attr_delete_list(certiflist);
 252 
 253   strcpy(iKO.iFilename, key_file_name);
 254 
 255   if (tracing)
 256   {
 257     printf("TRACING: delete_key: key_cert_attr: [%s]\n", key_cert_attr);
 258   }
 259   
 260   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
 261 
 262   if (tracing)
 263   {
 264     printf("TRACING: delete_key: obj_keyID: [%s]\n", obj_keyID);
 265   }
 266   
 267   keyID = strtoul(obj_keyID, NULL, 16);
 268 
 269   if (tracing)
 270   {
 271     printf("TRACING: delete_key: keyID is: %u, %X\n", keyID, keyID);
 272   }
 273   
 274   strcpy(iKO.keyRing, pgp_public_key_ring);
 275   PA_RemoveKey(&iKO);
 276 
 277   if (tracing)
 278   {
 279     printf("TRACING: importKeyObj status:\n");
 280     printf("TRACING: isValid: %d\n", iKO.rc);
 281   }
 282 
 283   /* clean-up: delete the file, free the char *    */
 284   unlink(key_file_name);
 285   free(key_file_name);
 286 
 287   if (iKO.rc == iKO_OK)
 288   { /* if PA_RemoveKey returned OK */
 289     return NULL;
 290   }
 291   else
 292   {  /* if PA_RemoveKey returned not OK */
 293       switch (iKO.rc)
 294           {
 295         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break; 
 296         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
 297         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
 298         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
 299         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
 300         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
 301         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
 302         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
 303         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
 304         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
 305         default:            error_string = strdup("general PGP error");
 306       }
 307       return error_string; 
 308   }
 309 
 310 }
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 /* Takes a key-certif object, extracts its 'certif' attribute and adds
 319    the key into public keyring
 320    If there is no problem, it returns NULL
 321    If there is a problem, then it returns a string which contains an error
 322    message */
 323 char * import_key(rpsl_object_t *object)
     /* [<][>][^][v][top][bottom][index][help] */
 324 {
 325   char * key_file_name;
 326   char *value;
 327   struct ImportKeyObject iKO;
 328   GList * certiflist, * item, * templist;
 329   FILE * key_file;
 330   char keyID[9];
 331   char * obj_keyID, * key_cert_attr;
 332   char * error_string = NULL;
 333    
 334   key_file_name = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
 335   sprintf(key_file_name, "%s/tmp-key.%i", tmpdir, pid );
 336 
 337   /* now we must write certif attribute(s) of this key-certif into the key_file_name */
 338   /* get the certif first */
 339   certiflist = rpsl_object_get_attr(object, "certif");
 340   if (( key_file = fopen(key_file_name, "w")) == NULL)
 341   {
 342      ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", key_file_name);
 343      exit(1);
 344   }
 345   for( item = certiflist; item != NULL ; item = g_list_next(item) )
 346   {
 347     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(item->data) );
 348         if (value == NULL)
 349         { /* if this was an empty attribute, just print an empty line */
 350       fprintf(key_file, "\n"); 
 351     }
 352         else
 353         {
 354           fprintf(key_file, "%s\n", value);
 355           free(value);
 356         }
 357   }
 358   fclose(key_file);
 359   rpsl_attr_delete_list(certiflist);
 360 
 361   strcpy(iKO.iFilename, key_file_name);
 362   strcpy(iKO.keyRing, pgp_public_key_ring);
 363   PA_ImportKey(&iKO);
 364 
 365   if (tracing)
 366   {
 367     printf("importKeyObj status:\n");
 368     
 369     printf("isValid: %d\n", iKO.rc);
 370     printf("keyID: %08lX\n", (long)(iKO.keyID) );
 371   }
 372   snprintf(keyID, 9, "%08lX", iKO.keyID);
 373   
 374   if (tracing)
 375   {
 376     printf("keyID: [%s]\n", keyID);
 377   }
 378   
 379   templist = rpsl_object_get_attr(object, "key-cert");
 380   key_cert_attr = rpsl_attr_get_clean_value((rpsl_attr_t *)(templist->data));
 381   rpsl_attr_delete_list(templist);
 382 
 383   if (tracing)
 384   {
 385     printf("key_cert_attr: [%s]\n", key_cert_attr);
 386   }
 387   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
 388   free(key_cert_attr);
 389   if (tracing)
 390   {
 391     printf("obj_keyID: [%s]\n", obj_keyID);
 392   }
 393 
 394   if (iKO.rc == iKO_OK && (strcasecmp(obj_keyID, keyID) == 0))
 395   { /* if PA_ImportKey returned OK 
 396     and the real keyID is equal to the
 397     keyID in the 'key-cert' attribute */
 398     fingerprint = strdup(iKO.fingerPrint); 
 399     keyowner    = strdup(iKO.keyOwner);
 400 
 401     /* clean-up: delete the file, free the variable */ 
 402     unlink(key_file_name);
 403     free(key_file_name);
 404     
 405     return NULL;
 406   }
 407   else
 408   {
 409     /* if PA_ImportKey returned not OK or obj_keyID, keyID didn't match */
 410     if  (iKO.rc != iKO_OK)
 411         {
 412       switch (iKO.rc)
 413           {
 414         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break; 
 415         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
 416         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
 417         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
 418         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
 419         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
 420         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
 421         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
 422         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
 423         case iKO_MULTIPLE_KEYS:  error_string = strdup("multiple keys in key-cert object");break;
 424         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
 425         default:            error_string = strdup("general PGP error");
 426       }
 427 
 428       /* clean-up: delete the file, free the variable */ 
 429       unlink(key_file_name);
 430       free(key_file_name);
 431       return error_string; 
 432 
 433     }
 434         else
 435         {
 436       error_string = (char *)malloc(1024);/* this should be enough */
 437       sprintf(error_string, "Keyid for this certificate (%s) is not the same as the PGPKEY field (%s)", 
 438                  keyID, obj_keyID);
 439       /* roll-back: we encountered a problem, so we have to remove the key that
 440          we've added */
 441       PA_RemoveKey(&iKO);
 442 
 443       /* clean-up: delete the file, free the variable */ 
 444       unlink(key_file_name);
 445       free(key_file_name);
 446 
 447             free(obj_keyID);
 448       return error_string;
 449     }
 450   }
 451       
 452 }
 453 
 454 
 455 
 456 /* Gets the keyowner and fingerprint of a PGP key 
 457    from the keycert object. The keycert object must already
 458    be in the database (thus, in the keyring) 
 459    The fingerprint and keyowner will be saved in global variables */
 460    
 461 void get_keyowner_fingerpr(rpsl_object_t *obj)
     /* [<][>][^][v][top][bottom][index][help] */
 462 {
 463   GList * templist = NULL;
 464   char * obj_keyID = NULL;
 465   struct ImportKeyObject iKO;
 466   u32 keyID;
 467   char * key_cert_value;
 468    
 469   
 470   templist = rpsl_object_get_attr(obj, "key-cert");
 471   key_cert_value = rpsl_attr_get_clean_value((rpsl_attr_t *)(templist->data));
 472   rpsl_attr_delete_list(templist);
 473 
 474   if (tracing)
 475   {
 476     printf("get_keyowner_fingerpr: key_cert_attr is [%s]\n", key_cert_value);
 477   } 
 478   
 479   obj_keyID = strdup(key_cert_value + strlen("PGPKEY-"));
 480   if (tracing)
 481   {
 482     printf("get_keyowner_fingerpr: obj_keyID is [%s]\n", obj_keyID);
 483   }
 484  
 485   sscanf(obj_keyID, "%8X", &keyID); 
 486   if (tracing)
 487   {
 488     printf("get_keyowner_fingerpr: keyID is [%u]\n", keyID);
 489  }
 490   
 491   /* set appropriate fields of iKO */ 
 492   iKO.keyID = keyID;
 493   strcpy(iKO.keyRing, pgp_public_key_ring);
 494 
 495   GetFingerPrint(&iKO);
 496   fingerprint = strdup(iKO.fingerPrint);
 497   
 498   GetKeyOwner(&iKO);
 499   keyowner = strdup(iKO.keyOwner); 
 500 
 501   free(key_cert_value);
 502   free(obj_keyID);
 503 
 504   if(tracing)
 505   {
 506     if (fingerprint != NULL)
 507         {
 508       printf("get_keyowner_fingerpr: fingerprint is [%s]\n", fingerprint);
 509     }
 510     if (keyowner)
 511         {
 512       printf("get_keyowner_fingerpr: keyowner is [%s]\n", keyowner);
 513     }
 514   }
 515 }
 516 
 517 
 518 
 519 
 520 
 521 
 522 /* Checks the object's syntax, retrives the old version of it from the db, 
 523    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
 524    integrity is checked, and the object is really committed to the db.
 525   
 526      Arguments:
 527         char * incoming: The object,
 528         credentials_struct credentials: The struct containing the credentials, such as 
 529           'From:' field of the e-mail update,
 530         GHashTable * NIC_hdl_hash: A hash containing 
 531         char * ack_file_name:  The file name, to be used to store ACK message 
 532         GHashTable * ntfy_hash, 
 533         GHashTable * forw_hash, 
 534         GHashTable * cross_hash: hashes that contain files that have notifications. 
 535 */
 536 
 537 
 538 
 539 int process_object(char * incoming, credentials_struct credentials, 
     /* [<][>][^][v][top][bottom][index][help] */
 540                    GHashTable * NIC_hdl_hash, char * ack_file_name,
 541                    GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash)
 542 {
 543     rpsl_object_t *object = NULL;
 544     rpsl_object_t *old_obj = NULL;
 545     rpsl_object_t *external_syntax_obj = NULL;
 546     rpsl_object_t *obj_with_AUTO_NIC_hdl = NULL;
 547     rpsl_object_t *formatted_object = NULL;
 548     rpsl_object_t *generated_obj = NULL;
 549     const GList * error_list = NULL;
 550     const GList * error_list_item = NULL;
 551     const GList * attr_list = NULL;
 552     const GList * attr_list_item = NULL;
 553     const GList * attr_error_list = NULL;
 554     const GList * attr_error_list_item = NULL;
 555     char * old_version = NULL;
 556     int result = 0;
 557     char * result_from_import_key = NULL;
 558     char * result_from_delete_key = NULL;
 559     char * auto_nic = NULL;
 560     char * changed_obj_str = NULL;
 561         char *obj_with_AUTO_NIC_hdl_str;
 562     char * assigned_NIC;
 563     char * formatted_object_str;
 564     const char * type;
 565         char *lctype;
 566     char * arg;
 567     char * arg2;
 568     char * generated_obj_str;
 569         const char * value = NULL;
 570         const char * name = NULL;
 571         char * attribute = NULL;
 572         int noclass;
 573         char *key;
 574     up_ripupd_result_struct * result_from_RIPupd;
 575     external_syntax_struct * external_syntax_results;
 576         gint elevel, ecode;
 577         gchar *edescr = NULL;
 578 
 579     arg = strdup(incoming);
 580         
 581         object = rpsl_object_init(arg);
 582         error_list = rpsl_object_errors(object);
 583         if (tracing && error_list)
 584         {
 585           printf("TRACING: errors found on initial object parse\n");
 586           for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
 587           {
 588             elevel = ((rpsl_error_t *)(error_list_item->data))->level;
 589                 ecode = ((rpsl_error_t *)(error_list_item->data))->code;
 590                 edescr = strdup(((rpsl_error_t *)(error_list_item->data))->descr);
 591                 
 592                 printf("TRACING: level [%d]  code [%d]  [%s]\n", elevel, ecode, edescr);
 593                 free(edescr);
 594           }
 595         }
 596         if ( error_list )
 597         {
 598           if ( ((rpsl_error_t *)(error_list->data))->code == RPSL_ERR_ONLYCOMMENTS )
 599             return UP_NOOBJECT;
 600         }
 601 
 602     if ( !rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) 
 603                         && has_ref_to_AUTO_nic_hdl(object) )
 604         {  /* parsed with no systax errors */
 605           if (tracing)
 606           { 
 607         printf("TRACING: the object has ref to AUTO nic-hdl\n");
 608           }
 609 
 610           /* if this object has refs to AUTO NIC hdls*/
 611       /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
 612       if ((changed_obj_str = replace_refs_to_AUTO_NIC_hdl(object, NIC_hdl_hash, arg)) == NULL)
 613           {
 614                 type = rpsl_object_get_class(object);
 615 
 616                 free(arg);
 617         if ( UP_remove_override_attr(object) )
 618           arg = rpsl_object_get_text(object,0);
 619                 else
 620                 {
 621                   /* there was an override attr in this object and it has not been removed */
 622                   arg = (char *)malloc(2);
 623                   strcpy(arg, "");      /* Don't include object in ack/notif msgs */
 624                 }
 625 
 626         AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] Unknown AUTO NIC handle referenced\n%s\n", 
 627                 type ? type : "unknown-type", arg);
 628 
 629         rpsl_object_delete(object);
 630         free(arg); 
 631         return UP_ANE; /* AUTO NIC hdl error */
 632       }
 633           else
 634           { /* in this case, we must use changed_obj_str instead of arg */
 635 
 636         free(arg); 
 637         arg = changed_obj_str; 
 638       };
 639     }
 640   
 641     
 642     if ( !rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
 643         {
 644           /* parsed with no systax errors */
 645       type = rpsl_object_get_class(object);
 646       /* is the object to be deleted? */
 647       if ( rpsl_object_is_deleted(object) )
 648           {
 649         old_version = get_old_version(object, arg);
 650 
 651         if(old_version == NULL)
 652                 {  /* the object doesn't exist in the db! */
 653 
 654                   if (tracing)
 655                   { 
 656                 printf("TRACING: the object doesn't exist in the db\n");
 657                   }
 658 
 659                   free(arg);
 660           if ( UP_remove_override_attr(object) )
 661                 arg = rpsl_object_get_text(object,0);
 662                   else
 663                   {
 664                         /* there was an override attr in this object and it has not been removed */
 665                         arg = (char *)malloc(2);
 666                         strcpy(arg, "");        /* Don't include object in ack/notif msgs */
 667                   }
 668 
 669           AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n***Error: Entry not found\n\n",
 670                         type, get_search_key(object, type), arg);
 671 
 672           rpsl_object_delete(object);
 673           free(arg); 
 674           return UP_NSO; /* no such object */
 675         }
 676                 else 
 677                 {  /* the object is in the db */
 678 
 679                   if (tracing)
 680                   { 
 681                 printf("TRACING: the object is in the db\n");
 682                   }
 683 
 684                   lctype = strdup(type);
 685                   g_strdown(lctype);
 686           if (    identical(old_version, object)      /* if the old & new versions are identical */
 687                || (strcmp(lctype, "key-cert") == 0)   /* or it is a key-cert object  */
 688                || (strcmp(lctype, "inet6num") == 0) ) /* or it is an inet6num object */
 689                   {  
 690             result = check_auth(NULL, object, type, credentials);
 691             if(result == UP_AUTH_OK)
 692                         { 
 693               if (tracing)
 694                           {
 695                 printf("TRACING: Will send the obj to be deleted\n");
 696               }
 697               if(strcmp(type, "key-cert") == 0)
 698                           {
 699                 result_from_delete_key = delete_key(object);
 700               }
 701                           else
 702                           {
 703                 result_from_delete_key = NULL;
 704               }
 705               /* if there was no problem with key deletion from the key-ring */
 706               if (result_from_delete_key == NULL)
 707                           {
 708                 result_from_RIPupd = send_object_db(object, NULL, "DEL");
 709                 if (result_from_RIPupd->result == 0)
 710                                 {
 711                   AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n", 
 712                                 type, get_search_key(object, type));
 713                   NT_write_all_ntfs(old_version, NULL, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, 
 714                                     credentials.from);
 715 
 716                   rpsl_object_delete(object);
 717                                   free(result_from_RIPupd);
 718                   free(arg); 
 719                           free(old_version);
 720                   return UP_OK;
 721                 }
 722                                 else
 723                                 {
 724                   AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
 725                                 type, get_search_key(object, type),
 726                                 result_from_RIPupd->error_str);
 727 
 728                   rpsl_object_delete(object);
 729                                   free(result_from_RIPupd->error_str);
 730                                   free(result_from_RIPupd);
 731                   free(arg); 
 732                           free(old_version);
 733                   return UP_INT;
 734                 }
 735               }
 736                           else
 737                           {
 738                  AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
 739                                 type, get_search_key(object, type),
 740                                 result_from_delete_key);
 741 
 742                  rpsl_object_delete(object);
 743                  free(arg); 
 744                          free(old_version);
 745                  free(result_from_delete_key); 
 746                  return UP_INT;
 747               }
 748             }
 749                         else
 750                         { /* auth failed */
 751               if (tracing) 
 752                           {
 753                 printf("TRACING: Auth failed\n");
 754               }
 755 
 756                       free(arg);
 757                   if ( UP_remove_override_attr(object) )
 758                         arg = rpsl_object_get_text(object,0);
 759                           else
 760                           {
 761                                 /* there was an override attr in this object and it has not been removed */
 762                                 arg = (char *)malloc(2);
 763                                 strcpy(arg, "");        /* Don't include object in ack/notif msgs */
 764                           }
 765 
 766               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
 767                             type, get_search_key(object, type), arg);
 768               NT_write_all_frwds(old_version, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 769 
 770               rpsl_object_delete(object);
 771               free(arg); 
 772                       free(old_version);
 773               return UP_AUF; /* Auth failed */
 774             } 
 775           }  /* end of identical match */
 776                   else
 777                   {  /* the new & old versions do not match */
 778                     free(arg);
 779                 if ( UP_remove_override_attr(object) )
 780                   arg = rpsl_object_get_text(object,0);
 781                         else
 782                         {
 783                           /* there was an override attr in this object and it has not been removed */
 784                           arg = (char *)malloc(2);
 785                           strcpy(arg, "");      /* Don't include object in ack/notif msgs */
 786                         }
 787 
 788             AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n***Error: new & old versions do not match\n",
 789                  type, get_search_key(object, type), arg);
 790 
 791             rpsl_object_delete(object);
 792             free(arg); 
 793                     free(old_version);
 794             return UP_NOM; /* new & old versions do not match */
 795           }
 796         }  /* end of the object is in the db */
 797       } /* end of the object is to be deleted */
 798           else 
 799           { /* the object is _NOT_ to be deleted */
 800         
 801         if (has_AUTO_NIC_hdl(object))
 802                 { /* if the object has an AUTO NIC hdl */
 803                   external_syntax_obj = rpsl_object_copy(object);
 804           external_syntax_results = UP_check_external_syntax(external_syntax_obj);
 805           if (    external_syntax_results->result != UP_EXTSYN_ERR 
 806                && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
 807                   { /* if there is no error */
 808             /* then its nic-hdl attribute must be modified so that RIPupdate
 809                would understand that it must assign a NIC handle to it */
 810             /* but first check the auth */
 811             result = check_auth(external_syntax_obj, NULL, type, credentials);
 812             if (result == UP_AUTH_OK)
 813                         {
 814               if (tracing)
 815                           {                                
 816                   printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
 817               }
 818               auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
 819               obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(external_syntax_obj, auto_nic);
 820               if (tracing)
 821                           {  
 822                             obj_with_AUTO_NIC_hdl_str = rpsl_object_get_text(obj_with_AUTO_NIC_hdl,0);
 823                 printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl_str);
 824                 printf("TRACING: Will send the obj to be added\n");
 825                                 free(obj_with_AUTO_NIC_hdl_str);
 826                                 obj_with_AUTO_NIC_hdl_str = NULL;
 827               }
 828               assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
 829               result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
 830               if (result_from_RIPupd->result == 0)
 831                           {
 832                 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", type, assigned_NIC);
 833 
 834                 /* replace the AUTO nic hdl with the assigned one (for reporting purposes, in the notif mesg) */
 835                 formatted_object = UP_put_assigned_NIC(external_syntax_obj, assigned_NIC);
 836 
 837                 formatted_object_str = rpsl_object_get_text(formatted_object,0);
 838                 NT_write_all_ntfs(NULL, arg, formatted_object_str, tmpdir, ntfy_hash, forw_hash, cross_hash, 
 839                                   credentials.from);
 840                 
 841                 result_from_RIPupd->result = 0;
 842                 if (tracing && assigned_NIC != NULL)
 843                                 {  
 844                   printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
 845                 }
 846                 if (assigned_NIC != NULL)
 847                                 {
 848                   if (tracing)
 849                                   {
 850                     printf("TRACING: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
 851                   }
 852                   g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
 853                   if (tracing)
 854                                   {
 855                     printf("TRACING: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
 856                   }
 857                 }
 858                 
 859                                 rpsl_object_delete(formatted_object);
 860                                 rpsl_object_delete(obj_with_AUTO_NIC_hdl);
 861                                 rpsl_object_delete(external_syntax_obj);
 862                 rpsl_object_delete(object);
 863                                 free(result_from_RIPupd);
 864                                 free(formatted_object_str);
 865                                 free(external_syntax_results->new_obj);
 866 /*                              free(external_syntax_results->error_str);*/
 867 /*                              free(external_syntax_results->warning_str);*/
 868                                 free(external_syntax_results);
 869                 free(arg); 
 870                 return UP_OK;
 871               }
 872                           else
 873                           {
 874                         if ( UP_remove_override_attr(object) )
 875                           arg2 = rpsl_object_get_text(object,0);
 876                                 else
 877                                 {
 878                                   /* there was an override attr in this object and it has not been removed */
 879                                   arg2 = (char *)malloc(2);
 880                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
 881                                 }
 882 
 883                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s]\n%s\n%s\n",
 884                               type, arg2, result_from_RIPupd->error_str);
 885 
 886                                 rpsl_object_delete(obj_with_AUTO_NIC_hdl);
 887                                 rpsl_object_delete(external_syntax_obj);
 888                 rpsl_object_delete(object);
 889                                 free(result_from_RIPupd);
 890                                 free(external_syntax_results->new_obj);
 891                                 free(external_syntax_results);
 892                                 free(arg2);
 893                 free(arg); 
 894                 return UP_INT;
 895               }
 896             }
 897                         else
 898                         {
 899               /* auth failed ! */
 900               if (tracing)
 901                           {
 902                 printf("TRACING: Auth failed\n");
 903               }
 904   
 905                   if ( UP_remove_override_attr(object) )
 906                         arg2 = rpsl_object_get_text(object,0);
 907                           else
 908                           {
 909                                 /* there was an override attr in this object and it has not been removed */
 910                                 arg2 = (char *)malloc(2);
 911                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
 912                           }
 913 
 914               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
 915                             type, get_search_key(object, type), arg2);
 916               NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 917 
 918                       rpsl_object_delete(external_syntax_obj);
 919               rpsl_object_delete(object);
 920                           free(external_syntax_results->new_obj);
 921                       free(external_syntax_results);
 922                       free(arg2);
 923               free(arg); 
 924               return UP_AUF; /* Auth failed */
 925             }
 926           }
 927                   else
 928                   { /* external syntax check failed */
 929                 if ( UP_remove_override_attr(object) )
 930                   arg2 = rpsl_object_get_text(object,0);
 931                         else
 932                         {
 933                           /* there was an override attr in this object and it has not been removed */
 934                           arg2 = (char *)malloc(2);
 935                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
 936                         }
 937 
 938             AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s\n",
 939                    type, get_search_key(object, type), 
 940                    arg2, external_syntax_results->error_str);
 941 
 942                     rpsl_object_delete(external_syntax_obj);
 943             rpsl_object_delete(object);
 944                         free(external_syntax_results->new_obj);
 945                         free(external_syntax_results);
 946                     free(arg2);
 947             free(arg); 
 948             return UP_SYN;
 949           }
 950         }  /* end of the object has an AUTO NIC hdl */
 951         else
 952                 { /* process object without an AUTO NIC hdl */
 953           old_version = get_old_version(object, arg);
 954           if (old_version != NULL)
 955                   { 
 956                     /* so, this is an update operation */
 957             if ( (!reading_from_mail) || 
 958                 (subject_result.result != UP_SUBJ_NEW_ENFORCED))
 959                         { 
 960                           /* If the user didn't enforce creation in the subject line */
 961                       external_syntax_obj = rpsl_object_copy(object);
 962               external_syntax_results = UP_check_external_syntax(external_syntax_obj);
 963               if (    external_syntax_results->result != UP_EXTSYN_ERR 
 964                    && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
 965                           { 
 966                             /* if there is no error */
 967                 if ( identical(old_version, external_syntax_obj) != 1 )
 968                                 {
 969                   /* if the old version & the new one are not identical */ 
 970                       old_obj = rpsl_object_init(old_version);
 971                       error_list = rpsl_object_errors(old_obj);
 972                       /***************************** DO SOME ERROR CHECKING / REPORTING HERE ***************/
 973 
 974                   result = check_auth(object, old_obj, type, credentials);    
 975                   if (result == UP_AUTH_OK)
 976                                   {
 977                     if (tracing)
 978                                         {                                
 979                       printf("TRACING: Will send the obj to be updated\n");
 980                     }
 981 
 982                     generated_obj = rpsl_object_copy(external_syntax_obj);
 983                     if (strcasecmp(type, "key-cert") == 0)
 984                                         {
 985                       get_keyowner_fingerpr(object);/* get keyowner and fingerprint, 
 986                                                        save them into global vars  */
 987                       generated_obj_str = UP_generate_kc_attrs(generated_obj);
 988                                       free(external_syntax_results->new_obj);
 989                       external_syntax_results->new_obj = generated_obj_str;
 990                     }
 991                    
 992                     /* XXX this will be put back when UP_generate_i6_attrs is ready*/ 
 993                     else if(strcasecmp(type, "inet6num") == 0)
 994                                         {
 995                       generated_obj_str = UP_generate_i6_attrs(generated_obj);
 996                                       free(external_syntax_results->new_obj);
 997                       external_syntax_results->new_obj = generated_obj_str;
 998                     }
 999                     /**/
1000                     result_from_RIPupd = send_object_db(generated_obj, NULL, "UPD");
1001 
1002                                 if ( UP_remove_override_attr(object) )
1003                                   arg2 = rpsl_object_get_text(object,0);
1004                                         else
1005                                         {
1006                                           /* there was an override attr in this object and it has not been removed */
1007                                           arg2 = (char *)malloc(2);
1008                                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1009                                         }
1010 
1011                     if (result_from_RIPupd->result == 0)
1012                                         {
1013                       AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
1014                                     type, get_search_key(object, type));
1015 
1016                       NT_write_all_ntfs(old_version, arg, external_syntax_results->new_obj, tmpdir, ntfy_hash, forw_hash, cross_hash, 
1017                                         credentials.from);
1018 
1019                                       rpsl_object_delete(generated_obj);
1020                                       rpsl_object_delete(old_obj);
1021                                       rpsl_object_delete(external_syntax_obj);
1022                       rpsl_object_delete(object);
1023                                       free(result_from_RIPupd);
1024                                           free(old_version);
1025                                       free(external_syntax_results->new_obj);
1026                                           free(external_syntax_results);
1027                                       free(arg2);
1028                       free(arg); 
1029                       return UP_OK;
1030                     }
1031                                         else
1032                                         {
1033                       AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n%s\n",
1034                                     type, get_search_key(object, type),
1035                                     arg2, result_from_RIPupd->error_str);
1036 
1037                                       rpsl_object_delete(generated_obj);
1038                                       rpsl_object_delete(old_obj);
1039                                       rpsl_object_delete(external_syntax_obj);
1040                       rpsl_object_delete(object);
1041                                       free(result_from_RIPupd->error_str);
1042                                       free(result_from_RIPupd);
1043                                           free(old_version);
1044                                       free(external_syntax_results->new_obj);
1045                                           free(external_syntax_results);
1046                                       free(arg2);
1047                       free(arg); 
1048                       return UP_INT;
1049                     }
1050                   }
1051                                   else if (result == UP_NAM)
1052                                   {
1053                     /* name of a person/role object cannot be changed */
1054                     if (tracing)
1055                                         {
1056                       printf("TRACING: name of a person/role object cannot be changed\n");
1057                     }
1058                     
1059                                 if ( UP_remove_override_attr(object) )
1060                                   arg2 = rpsl_object_get_text(object,0);
1061                                         else
1062                                         {
1063                                           /* there was an override attr in this object and it has not been removed */
1064                                           arg2 = (char *)malloc(2);
1065                                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1066                                         }
1067 
1068                     AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n***Error: Name of a person or role object cannot be changed.\n",
1069                                   type, get_search_key(object, type), arg2);
1070 
1071                                     rpsl_object_delete(old_obj);
1072                                     rpsl_object_delete(external_syntax_obj);
1073                     rpsl_object_delete(object);
1074                                         free(old_version);
1075                                     free(external_syntax_results->new_obj);
1076                                         free(external_syntax_results);
1077                                     free(arg2);
1078                     free(arg); 
1079                     return UP_NAM; /* name of a person/role object cannot be changed */
1080 
1081 
1082                   }
1083                   else
1084                                   {
1085                     /* auth failed ! */
1086                     if (tracing)
1087                                         {
1088                       printf("TRACING: Auth failed\n");
1089                     }
1090       
1091                                 if ( UP_remove_override_attr(object) )
1092                                   arg2 = rpsl_object_get_text(object,0);
1093                                         else
1094                                         {
1095                                           /* there was an override attr in this object and it has not been removed */
1096                                           arg2 = (char *)malloc(2);
1097                                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1098                                         }
1099 
1100                     AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1101                                   type, get_search_key(object, type), arg2);
1102 
1103                     NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1104 
1105                                     rpsl_object_delete(old_obj);
1106                                     rpsl_object_delete(external_syntax_obj);
1107                     rpsl_object_delete(object);
1108                                         free(old_version);
1109                                     free(external_syntax_results->new_obj);
1110                                         free(external_syntax_results);
1111                                     free(arg2);
1112                     free(arg); 
1113                     return UP_AUF; /* Auth failed */
1114                   }
1115 
1116                 }
1117                                 else
1118                                 { /* if the old and new versions of the object are the same */
1119                   if (tracing)
1120                                   {                                
1121                       printf("TRACING: The obj sent is identical to the one in the DB (NOOP)\n");
1122                   }
1123 
1124                   AK_add_to_ack(ack_file_name, "\nUpdate NOOP: [%s] %s\n",
1125                                     type, get_search_key(object, type));
1126 
1127                                   rpsl_object_delete(external_syntax_obj);
1128                   rpsl_object_delete(object);
1129                               free(old_version);
1130                                   free(external_syntax_results->new_obj);
1131                               free(external_syntax_results);
1132                   free(arg); 
1133                   return UP_OK;
1134                 }
1135               }
1136                           else
1137                           { /* if there is an error in external syntax checks */
1138                         if ( UP_remove_override_attr(object) )
1139                            arg2 = rpsl_object_get_text(object,0);
1140                                 else
1141                                 {
1142                                   /* there was an override attr in this object and it has not been removed */
1143                                   arg2 = (char *)malloc(2);
1144                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1145                                 }
1146 
1147                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s\n",
1148                      type, get_search_key(object, type), 
1149                      arg2, external_syntax_results->error_str);
1150 
1151                                 rpsl_object_delete(external_syntax_obj);
1152                 rpsl_object_delete(object);
1153                             free(old_version);
1154                                 free(external_syntax_results->new_obj);
1155                             free(external_syntax_results);
1156                 free(arg2); 
1157                 free(arg); 
1158                 return UP_SYN;
1159               }
1160             }
1161                         else
1162                         { /* if the user enforced creation (using NEW keyword) in the subject line */
1163                   if ( UP_remove_override_attr(object) )
1164                         arg2 = rpsl_object_get_text(object,0);
1165                           else
1166                           {
1167                                 /* there was an override attr in this object and it has not been removed */
1168                                 arg2 = (char *)malloc(2);
1169                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
1170                           }
1171 
1172               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n"
1173                    "***Error:  Object already exists\n",
1174                    type, get_search_key(object, type), arg2),
1175 
1176               rpsl_object_delete(object);
1177                           free(old_version);
1178               free(arg2); 
1179               free(arg); 
1180               return UP_INT;
1181               
1182             }
1183           }  /* end of this is an update operation */
1184                   else
1185                   { /* old_version  == NULL, so, creation */
1186                     external_syntax_obj = rpsl_object_copy(object);
1187             external_syntax_results = UP_check_external_syntax(external_syntax_obj);
1188             if (    external_syntax_results->result != UP_EXTSYN_ERR 
1189                  && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
1190                         {
1191                           /* if there is no error */
1192               result = check_auth(object, NULL, type, credentials);
1193               if (result == UP_AUTH_OK)
1194                           { 
1195                 if (tracing)
1196                                 {                                
1197                   printf("TRACING: Will send the obj to be added\n");
1198                 }
1199                  /* if the object is a key-cert object, then we must import the PGP key */
1200                 if ( strcmp(type, "key-cert") == 0 )
1201                                 {
1202                   result_from_import_key = import_key(object);
1203                 }
1204                                 else
1205                                 {
1206                   result_from_import_key = NULL;
1207                 }
1208                 if (result_from_import_key == NULL)
1209                                 { 
1210                                   /* no PGP problem */
1211                                   generated_obj = rpsl_object_copy(external_syntax_obj);
1212                   if (strcasecmp(type, "key-cert") == 0)
1213                                   {
1214                                     /* if the object is a key-cert object */
1215                     generated_obj_str = UP_generate_kc_attrs(generated_obj);
1216                                     free(external_syntax_results->new_obj);
1217                     external_syntax_results->new_obj = generated_obj_str;
1218                   }
1219                   else if(strcasecmp(type, "inet6num") == 0)
1220                                   {
1221                                     /* if the object is an inet6num object */
1222                     generated_obj_str = UP_generate_i6_attrs(generated_obj);
1223                                     free(external_syntax_results->new_obj);
1224                     external_syntax_results->new_obj = generated_obj_str;
1225                   }
1226                   result_from_RIPupd = send_object_db(generated_obj, NULL, "ADD");                     
1227 
1228                   if (result_from_RIPupd->result == 0)
1229                                   { 
1230                                     /* if there was no problem */
1231                     AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n",
1232                                   type, get_search_key(object, type));
1233 
1234                      NT_write_all_ntfs(NULL, arg, external_syntax_results->new_obj, tmpdir, 
1235                                                            ntfy_hash, forw_hash, cross_hash, credentials.from);
1236 
1237                                     rpsl_object_delete(generated_obj);
1238                                     rpsl_object_delete(external_syntax_obj);
1239                     rpsl_object_delete(object);
1240                                     free(result_from_RIPupd);
1241                                     free(external_syntax_results->new_obj);
1242                                         free(external_syntax_results);
1243                     free(arg); 
1244                     return UP_OK;
1245 
1246                   }
1247                                   else
1248                                   {
1249                     AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
1250                                   type, get_search_key(object, type),
1251                                   result_from_RIPupd->error_str);
1252 
1253                                     rpsl_object_delete(generated_obj);
1254                                     rpsl_object_delete(external_syntax_obj);
1255                     rpsl_object_delete(object);
1256                                     free(result_from_RIPupd->error_str);
1257                                     free(result_from_RIPupd);
1258                                     free(external_syntax_results->new_obj);
1259                                         free(external_syntax_results);
1260                     free(arg); 
1261                     return UP_INT;
1262                   }
1263                 }
1264                                 else
1265                                 {
1266                                   /* there was a problem with PGP key import */
1267                   AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
1268                                   type, get_search_key(object, type),
1269                                   result_from_import_key);
1270 
1271                                   rpsl_object_delete(external_syntax_obj);
1272                   rpsl_object_delete(object);
1273                   free(result_from_import_key);
1274                                   free(external_syntax_results->new_obj);
1275                                   free(external_syntax_results);
1276                   free(arg); 
1277                   return UP_INT;
1278                 }
1279               }
1280                           else if (result == UP_FWD)
1281                           { 
1282                             /* this was a maintainer or as-block creation request, so
1283                    forward it to <HUMAILBOX> */
1284                 if (tracing)
1285                                 {
1286                   printf("TRACING: Maintainer or as-block or irt request will be forwarded to <HUMAILBOX>\n");
1287                 }
1288 
1289                         if ( UP_remove_override_attr(object) )
1290                           arg2 = rpsl_object_get_text(object,0);
1291                                 else
1292                                 {
1293                                   /* there was an override attr in this object and it has not been removed */
1294                                   arg2 = (char *)malloc(2);
1295                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1296                                 }
1297 
1298                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n"
1299                               "***Error:     %s objects cannot be created automatically\n"
1300                               "***Error:     This object has been forwarded to %s\n"
1301                               "***Error:     for authorisation.\n"
1302                               "***Error:     No further action from your part is required\n",
1303                               type, get_search_key(object, type),
1304                               arg2, type, humailbox);
1305 
1306                 if ( ! strcmp(type, "mntner") )
1307                 {
1308                   header_type = strdup("Maintainer");
1309                   text_type = strdup("maintainer");
1310                 }
1311                 else if ( ! strcmp(type, "as-block") )
1312                 {
1313                   header_type = strdup("as-block");
1314                   text_type = strdup("as-block");
1315                 }
1316                 else if ( ! strcmp(type, "irt") )
1317                 {
1318                   header_type = strdup("irt");
1319                   text_type = strdup("irt");
1320                 }
1321                 else
1322                 {
1323                   header_type = strdup("");
1324                   text_type = strdup("");
1325                 }
1326 
1327                 /* and forward this creation request to <HUMAILBOX> */
1328                 NT_forw_create_req(external_syntax_results->new_obj);
1329 
1330                                 rpsl_object_delete(external_syntax_obj);
1331                 rpsl_object_delete(object);
1332                                 free(external_syntax_results->new_obj);
1333                                 free(external_syntax_results);
1334                                 free(arg2);
1335                 free(arg); 
1336                 free(header_type);
1337                 free(text_type);
1338                 return UP_AUF;
1339               }
1340                           else if (result == UP_HOF)
1341                           {
1342                             /* hierarchical authorisation failed */
1343                 if (tracing)
1344                                 {
1345                   printf("TRACING: Auth failed\n");
1346                 }
1347 
1348                         if ( UP_remove_override_attr(object) )
1349                           arg2 = rpsl_object_get_text(object,0);
1350                                 else
1351                                 {
1352                                   /* there was an override attr in this object and it has not been removed */
1353                                   arg2 = (char *)malloc(2);
1354                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1355                                 }
1356 
1357                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nHierarchical authorisation failed, request forwarded to maintainer.\n%s\n",
1358                               type, get_search_key(object, type), arg2);
1359 
1360                 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1361 
1362                                 rpsl_object_delete(external_syntax_obj);
1363                 rpsl_object_delete(object);
1364                                 free(external_syntax_results->new_obj);
1365                                 free(external_syntax_results);
1366                                 free(arg2);
1367                 free(arg); 
1368                 return UP_AUF;
1369               }
1370                           else
1371                           {
1372                 /* auth failed ! */
1373                 if (tracing)
1374                                 {
1375                   printf("TRACING: Auth failed\n");
1376                 }
1377 
1378                         if ( UP_remove_override_attr(object) )
1379                           arg2 = rpsl_object_get_text(object,0);
1380                                 else
1381                                 {
1382                                   /* there was an override attr in this object and it has not been removed */
1383                                   arg2 = (char *)malloc(2);
1384                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1385                                 }
1386 
1387                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1388                               type, get_search_key(object, type), arg2);
1389 
1390                 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1391 
1392                                 rpsl_object_delete(external_syntax_obj);
1393                 rpsl_object_delete(object);
1394                                 free(external_syntax_results->new_obj);
1395                                 free(external_syntax_results);
1396                                 free(arg2);
1397                 free(arg); 
1398                 return UP_AUF; /* Auth failed */
1399               }
1400             }
1401                         else
1402                         {
1403                   if ( UP_remove_override_attr(object) )
1404                         arg2 = rpsl_object_get_text(object,0);
1405                           else
1406                           {
1407                                 /* there was an override attr in this object and it has not been removed */
1408                                 arg2 = (char *)malloc(2);
1409                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
1410                           }
1411 
1412               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s%s\n",
1413                               type, get_search_key(object, type), 
1414                               arg2, external_syntax_results->error_str);
1415 
1416                           rpsl_object_delete(external_syntax_obj);
1417               rpsl_object_delete(object);
1418                           free(external_syntax_results->new_obj);
1419                           free(external_syntax_results);
1420                           free(arg2);
1421               free(arg); 
1422               return UP_SYN;
1423             }
1424           }  /* end of creation */
1425         }  /* end of process object without an AUTO NIC hdl */
1426       }  /* end of the object is _not_ to be deleted */
1427     }  /* end of parsed with no systax errors */
1428         else
1429         {
1430             /* even if obj doesn't parse properly, it may be a legacy object
1431             which the user wants to delete... */
1432        if (tracing)
1433            {   
1434          printf("TRACING: Object didn't parse, check for legacy object deletion\n");   
1435        }
1436        /* if it is for deletion */
1437        if (rpsl_object_is_deleted(object))
1438            {
1439          /* here delete it */
1440          type = rpsl_object_get_class(object);
1441          old_version = get_old_version(object, arg);
1442 
1443                  if (tracing)
1444                  { 
1445            printf("TRACING: old_version: [\n%s]\n arg: [\n%s]\n", old_version, arg);
1446                  }
1447 
1448          if (old_version == NULL)
1449                  { 
1450                    /* the object doesn't exist in the db! */
1451                    free(arg);
1452            if ( UP_remove_override_attr(object) )
1453                  arg = rpsl_object_get_text(object,0);
1454                    else
1455                    {
1456                          /* there was an override attr in this object and it has not been removed */
1457                          arg = (char *)malloc(2);
1458                          strcpy(arg, "");       /* Don't include object in ack/notif msgs */
1459                    }
1460 
1461            AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n***Error: Entry not found\n\n%s\n", 
1462                           type, get_search_key(object, type), arg);
1463 
1464            rpsl_object_delete(object);
1465            free(arg); 
1466            return UP_NSO; /* no such object */
1467          }
1468                  else
1469                  {
1470 
1471                         if (tracing)
1472                         { 
1473                   printf("TRACING: legacy object is in the database\n");
1474                         }
1475 
1476                     /* the object is in the db */
1477             if ( identical(old_version, object) )
1478                         {
1479                           /* if the old & new versions are identical */
1480 
1481                           if (tracing)
1482                           { 
1483                         printf("TRACING: old & new versions are identical\n");
1484                           }
1485               result = check_auth(NULL, object, type, credentials);
1486               if (result == UP_AUTH_OK)
1487                           { 
1488                 if (tracing)
1489                                 {
1490                   printf("TRACING: Will send the obj to be deleted\n");
1491                 }
1492                 if (strcmp(type, "key-cert") == 0)
1493                                 {
1494                   result_from_delete_key = delete_key(object);
1495                 }
1496                                 else
1497                                 {
1498                   result_from_delete_key = NULL;
1499                 }
1500                 /* if there was no problem with key deletion from the key-ring */
1501                 if (result_from_delete_key == NULL)
1502                                 {
1503                   result_from_RIPupd = send_object_db(object, NULL, "DEL");
1504                   if (result_from_RIPupd->result == 0)
1505                                   {
1506                     AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n", 
1507                                   type, get_search_key(object, type));
1508                     NT_write_all_ntfs(old_version, NULL, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, 
1509                                       credentials.from);
1510 
1511                         rpsl_object_delete(object);
1512                                         free(result_from_RIPupd);
1513                         free(arg); 
1514                                 free(old_version);
1515                     return UP_OK;
1516                   }
1517                                   else
1518                                   {
1519                     AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
1520                                   type, get_search_key(object, type),
1521                                   result_from_RIPupd->error_str);
1522 
1523                         rpsl_object_delete(object);
1524                                     free(result_from_RIPupd->error_str);
1525                                         free(result_from_RIPupd);
1526                         free(arg); 
1527                                 free(old_version);
1528                     return UP_INT;
1529                   }
1530                 }
1531                                 else
1532                                 {
1533                    AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
1534                                   type, get_search_key(object, type), result_from_delete_key);
1535 
1536                    rpsl_object_delete(object);
1537                    free(arg); 
1538                            free(old_version);
1539                    free(result_from_delete_key); 
1540                    return UP_INT;
1541                 }
1542               }
1543                           else
1544                           { /* auth failed */
1545                 if (tracing)
1546                                 {
1547                   printf("TRACING: Auth failed\n");
1548                 }
1549 
1550                         if ( UP_remove_override_attr(object) )
1551                           arg2 = rpsl_object_get_text(object,0);
1552                                 else
1553                                 {
1554                                   /* there was an override attr in this object and it has not been removed */
1555                                   arg2 = (char *)malloc(2);
1556                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
1557                                 }
1558 
1559                 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
1560                               type, get_search_key(object, type), arg2);
1561                 NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
1562 
1563                 rpsl_object_delete(object);
1564                 free(arg2); 
1565                 free(arg); 
1566                         free(old_version);
1567                 return UP_AUF; /* Auth failed */
1568               } 
1569             }  /* end of identical match */
1570                         else
1571                         {
1572                           /* the new & old versions do not match */
1573                   if ( UP_remove_override_attr(object) )
1574                         arg2 = rpsl_object_get_text(object,0);
1575                           else
1576                           {
1577                                 /* there was an override attr in this object and it has not been removed */
1578                                 arg2 = (char *)malloc(2);
1579                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
1580                           }
1581 
1582               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s \n***Error: new & old versions do not match\n%s\n",
1583                               type, get_search_key(object, type), arg2);
1584 
1585               rpsl_object_delete(object);
1586               free(arg2); 
1587                       free(arg);
1588                       free(old_version);
1589               return UP_NOM; /* new & old versions do not match */
1590             }
1591           }  /* end of the object is in the db */
1592        } /* end of the object is to be deleted */
1593            else
1594            {
1595              /* syntax error AND not deletion */
1596                  noclass = 0;
1597                  for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
1598                  {
1599                    ecode = ((rpsl_error_t *)(error_list_item->data))->code;
1600            if ( ecode == RPSL_ERR_ONLYCOMMENTS || ecode == RPSL_ERR_BADCLASS
1601                          || ecode == RPSL_ERR_BADCLASS )
1602                    {
1603                      noclass = 1;
1604                          break;
1605                    }
1606                  }
1607          if ( UP_remove_override_attr(object) )
1608            arg2 = rpsl_object_get_text(object,0);
1609                  else
1610                  {
1611                    /* there was an override attr in this object and it has not been removed */
1612                    arg2 = (char *)malloc(2);
1613                    strcpy(arg2, "");    /* Don't include object in ack/notif msgs */
1614                  }
1615 
1616 /*               if ( ! noclass )
1617                  {
1618            type = rpsl_object_get_class(object);
1619                    key = get_search_key(object, type);
1620            AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s \n***Error: Syntax error in object\n",
1621                               type, key ? key : "" );
1622                  }
1623                  else */
1624            AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
1625 
1626          if ( rpsl_object_has_error(object, RPSL_ERRLVL_CRIT) )
1627                  {
1628                    /* object not parsed so print out text version of object rather than attributes */
1629                    AK_add_to_ack(ack_file_name, "%s\n", arg);
1630          }
1631          else
1632                  {
1633                    /* add attributes along with any attribute error messages */
1634                    attr_list = rpsl_object_get_all_attr(object);
1635                    for ( attr_list_item = attr_list; attr_list_item != NULL; attr_list_item = g_list_next(attr_list_item) )
1636                    {
1637                          name = rpsl_attr_get_name( (rpsl_attr_t *)(attr_list_item->data) );
1638                          if ( strcasecmp(name, "override") != 0 )
1639                          {
1640                        /* don't include the override attibute, but still include override error messages */
1641                        value = rpsl_attr_get_value( (rpsl_attr_t *)(attr_list_item->data) );
1642                        attribute = (char *)malloc( strlen(name) + strlen(value) + 3);
1643                        sprintf(attribute, "%s: %s", name, value);
1644                AK_add_to_ack(ack_file_name, "%s\n", attribute);
1645                        free(attribute);
1646                          }
1647                          attr_error_list = rpsl_attr_errors( (rpsl_attr_t *)(attr_list_item->data) );
1648                          for ( attr_error_list_item = attr_error_list; attr_error_list_item != NULL; attr_error_list_item = g_list_next(attr_error_list_item) )
1649                          {
1650                        if ( ((rpsl_error_t *)(attr_error_list_item->data))->level > RPSL_ERRLVL_DEBUG )
1651                  AK_add_to_ack(ack_file_name, "***Error: %s\n", ((rpsl_error_t *)(attr_error_list_item->data))->descr);
1652                          }
1653                    }
1654          }
1655 
1656          /* now add any object level error messages */
1657                  error_list = rpsl_object_errors(object);
1658                  for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
1659                  {
1660                    if ( ((rpsl_error_t *)(error_list_item->data))->level > RPSL_ERRLVL_DEBUG &&
1661                          ((rpsl_error_t *)(error_list_item->data))->code != RPSL_ERR_BADATTR )
1662                    {
1663              AK_add_to_ack(ack_file_name, "***Error: %s\n", ((rpsl_error_t *)(error_list_item->data))->descr);
1664                    }
1665                  }
1666 
1667          AK_add_to_ack(ack_file_name, "\n");
1668        
1669          rpsl_object_delete(object);
1670                  free(arg);
1671          return UP_SYN; /* syntax error */
1672        }
1673     }
1674 }
1675 
1676 
1677 
1678 
1679 
1680 /* processes the objects in the given file */
1681 void process_file(char * filename, credentials_struct credentials, 
     /* [<][>][^][v][top][bottom][index][help] */
1682                   GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name, 
1683                   GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash)
1684 {
1685 FILE * input_file;
1686 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;   
1687 GSList *next = NULL;
1688 int object_count = 0;
1689 char *object = NULL;
1690 char * line;
1691 char * lwrcase_line;
1692 int result = 0;
1693 rpsl_object_t *obj = NULL;
1694 const GList * error_list = NULL;
1695 
1696   
1697     line = (char *)malloc(1024);
1698 
1699     if ((input_file = fopen(filename, "r")) == NULL)
1700         {
1701         ER_perror(FAC_UP, UP_CANTOPEN, "Couldn't open the file %s: %s\n", filename, strerror(errno));
1702         exit(1);  
1703     }
1704   
1705     while (fgets(line, 1024, input_file) != NULL)
1706         {
1707       /* first, if it is a pasword, save it, but do not regard it as an attrib */ 
1708       lwrcase_line = strdup(line);
1709       g_strdown(lwrcase_line);
1710       if (strstr(lwrcase_line, "password:") == lwrcase_line)
1711           {
1712         if (tracing)
1713                 {
1714           printf("TRACING: This is a password\n");
1715         }
1716         credentials.password_list = g_slist_append(credentials.password_list, 
1717                                       g_strstrip(strdup(line + strlen("password:"))));
1718         free(lwrcase_line);
1719         continue;
1720       }
1721       free(lwrcase_line);
1722       
1723       line = UP_remove_EOLs(line); /* remove '\n's and '\r' first */
1724       /* remove trailing white space */
1725       line = g_strchomp(line); 
1726       if (strlen(line) == 0)
1727           {
1728             /* then, this was an empty line */
1729         if (object != NULL)
1730                 {
1731            list_of_objects = g_slist_append(list_of_objects, object);
1732            if (tracing)
1733                    {
1734              printf("TRACING: added an object: [%s]\n", object);
1735            }
1736            object = NULL;
1737         }
1738       }
1739           else
1740           {
1741         if (object == NULL && strlen(line) != 0)
1742                 {
1743           object = (char *)malloc(strlen(line) + 2);
1744           object = strcpy(object, line);
1745           object = strcat(object, "\n"); /* add EOL again (we removed it before) */
1746         }
1747         else
1748                 {
1749           object = (char *)realloc(object, strlen(object) + strlen(line) + 2);
1750           object = strcat(object, line);
1751           object = strcat(object, "\n");
1752         }
1753       }
1754       
1755     }
1756     fclose(input_file);
1757         free(line);
1758 
1759     /* now, if at the very and of the input file there wasn't an 
1760        empty line, we have to add the remaining object in the 'object'
1761        variable */
1762     if (object != NULL)
1763         {
1764        list_of_objects = g_slist_append(list_of_objects, object);
1765        object = NULL;
1766     }
1767 
1768 
1769     if (tracing)
1770         {
1771        printf("TRACING: Will process the objects in the list\n");
1772     }
1773     next = list_of_objects;
1774     object_count = 0;
1775     for ( next = list_of_objects; next != NULL ; next = g_slist_next(next) )
1776         {
1777       if (UP_is_object((char *)next->data))
1778           {
1779             /* if this looks like an object */
1780       
1781         object_count++;
1782         if(tracing)
1783                 {
1784           printf("TRACING: Got an object from the list\n");
1785           printf("[%s]\n", (char *)next->data );
1786         }
1787         
1788             obj = rpsl_object_init( (char *)next->data );
1789             error_list = rpsl_object_errors(obj);
1790 
1791         if ( ! rpsl_object_has_error(obj, RPSL_ERRLVL_ERROR) && has_ref_to_AUTO_nic_hdl(obj) )
1792                 {
1793                   /* if object has a reference to an auto- nichdl and no syntax errors
1794                      then defer the processing to allow the auto- nichdl to be created first */
1795           if(tracing)
1796                   {
1797             printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
1798           }
1799           list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
1800         }
1801                 else
1802                 {
1803           result = 0;
1804           result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
1805                                    ntfy_hash, forw_hash, cross_hash);
1806           /* keep a tally */
1807           if (result == UP_NOOBJECT)
1808                   {
1809                     /* do nothing and don't increment any counts */
1810                   }
1811           else if (result == UP_OK)
1812                   {
1813             count_successful++;
1814           }
1815                   else
1816                   {
1817             count_unsuccessful++;
1818           }
1819          }
1820                 
1821         rpsl_object_delete(obj);
1822       }
1823           else
1824           {
1825             /* this does not look like an object (a signature? some other text?) */
1826         
1827         AK_add_to_ack(ack_file_name, "\nThe following paragraph does not look like an object,\n"
1828                                      "so ignoring it:\n%s\n", (char *)next->data);
1829       }
1830     }
1831 
1832 
1833     if (tracing)
1834         {
1835       printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
1836       printf("TRACING: will start to process the second list\n");
1837     }
1838   
1839     for ( next = list_of_objects2; next != NULL ; next = g_slist_next(next) )
1840         {
1841       if (tracing)
1842           {
1843         printf("TRACING: Will process object: %s\n", (char *)next->data);
1844       }
1845       result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
1846                                ntfy_hash, forw_hash, cross_hash);
1847       /* keep a tally */
1848       if (result == UP_NOOBJECT)
1849           {
1850                 /* do nothing and don't increment any counts */
1851           }
1852       else if (result == UP_OK)
1853           {
1854         count_successful++;
1855       }
1856           else
1857           {
1858         count_unsuccessful++;
1859       }
1860     }
1861 }/* process_file */
1862 
1863 
1864 
1865 
1866 /*  Generates a unique file name and returns the full path of the filename 
1867     for storing notification message.  */
1868       
1869 char * generate_upd_file()
     /* [<][>][^][v][top][bottom][index][help] */
1870 {
1871    char * name;
1872      
1873    /* allocate space for name.  32 should be enough for PID */
1874    name = (char*)malloc(strlen(tmpdir) + strlen("/dbupdate-tmp.") + 34 ); 
1875    
1876    sprintf(name, "%s/dbupdate-tmp.%i", tmpdir, pid /*getpid()*/);
1877      
1878    return name;      
1879 }
1880 
1881 
1882 /* create_lock_file: creates a lock file in lockdir and locks it. This is a 
1883    part of crash recovery. Must be called in the beginning of the run. At the
1884    end, the file must be removed. */
1885 /* The idea: Create the "lock" file, and lock it. When another process starts
1886    running, it checks the existing lock files. If some exists, then it checks
1887    if it is locked or not. It not locked, then assumes that the corresponding
1888    dbupdate is alredy running. If not locked, assumes that it has crashed. 
1889    (note: when a process crashes, the kernel releases all the files locked by
1890    this process [by the OS]) 
1891    Problem: locking doesn't work properly on some NFS implementations. */
1892 
1893 lockfilestruct create_lock_file(){
     /* [<][>][^][v][top][bottom][index][help] */
1894   
1895   lockfilestruct lock;
1896   int file;
1897   int length;
1898 
1899   /* allocate space for file name */
1900   length = strlen(lockdir) +  strlen(hostname) + 32;
1901   lock.lockname = (char *)malloc(length + 1);
1902 
1903   snprintf(lock.lockname, length, "%s/dbupdate.%s.%ld", lockdir, hostname, pid /*getpid()*/);
1904 
1905   /* we will lock the file, so we have to use open(), but not fopen() (see man 
1906      page of lockf(3C)) */
1907   if(( file = open(lock.lockname, O_RDWR|O_CREAT)) == -1){
1908     ER_perror(FAC_UP, UP_CANTOPEN, "Can't open lock file, %s", lock.lockname);
1909     exit(1);
1910   }
1911  
1912   if(lockf(file, F_LOCK, 0) == -1){
1913     ER_perror(FAC_UP, UP_CANTLOCK, "Can't lock the file, %s", lock.lockname);
1914     exit(1);
1915   }; 
1916 
1917   lock.filedes = file;
1918 
1919   return lock;
1920 
1921 }
1922 
1923 
1924 
1925 
1926 
1927 /* remove_lock_file(): unlocks and removes the file  */
1928 void remove_lock_file(lockfilestruct lockfile){
     /* [<][>][^][v][top][bottom][index][help] */
1929 
1930   close(lockfile.filedes); /* this will remove the lock at the same time */ 
1931   unlink(lockfile.lockname);
1932 
1933 }
1934 
1935 
1936 
1937 /* writes the checkpoint file with the specified state */
1938 void write_checkpoint(int state){
     /* [<][>][^][v][top][bottom][index][help] */
1939 
1940   char * filename;
1941   char * tmpfilename;
1942   int length;
1943   FILE * file;
1944 
1945   if(tracing){
1946     printf("TRACING: write_checkpoint, state=[%i]\n", state); 
1947   }
1948   length = strlen(lockdir) +  strlen(hostname) + 64;
1949   filename    = (char *)malloc(length + 1);
1950   tmpfilename = (char *)malloc(length + 5);
1951  
1952   snprintf(filename,    length, "%s/dbupdate.checkpoint.%s.%ld",     lockdir, hostname, pid );
1953   snprintf(tmpfilename, length, "%s/dbupdate.checkpoint.%s.%ld.tmp", lockdir, hostname, pid );
1954 
1955   if(( file = fopen(tmpfilename, "w")) == NULL){
1956     /* fprintf(stderr, "Can't open temp checkpoint file, %s", tmpfilename); */
1957     ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temp checkpoint file, %s", tmpfilename);
1958     exit(1);
1959   }
1960 
1961   fprintf(file, "[STATE]\n%i\n", state);
1962 
1963   fprintf(file, "[FLAGS]\n");
1964   /* should print the flags here */
1965   
1966   fprintf(file, "[PARTS]\n");
1967   /* should print the parts (filenames) here */
1968 
1969   fprintf(file, "[OBJECTS1]\n");
1970 
1971   fprintf(file, "[OBJECTS2]\n");
1972 
1973   fprintf(file, "[ACKFILE]\n");
1974   
1975   fprintf(file, "[NOTIFFILES]\n");
1976 
1977   fprintf(file, "[TIDS1]\n");
1978   
1979   fprintf(file, "[TIDS2]\n");
1980 
1981   fprintf(file, "[NICHDLHASH]\n");
1982 
1983   fprintf(file, "[CURRENTOBJECT]\n");
1984 
1985   fprintf(file, "[CURRENTPART]\n");
1986 
1987   
1988   fclose(file);
1989 
1990   rename(tmpfilename, filename);
1991 
1992   /* free the char *'s */
1993   free(tmpfilename);
1994   free(filename);
1995 
1996 }
1997 
1998 
1999 
2000 
2001 /* removes check point file */
2002 void remove_checkpoint(){
     /* [<][>][^][v][top][bottom][index][help] */
2003 
2004   char * filename;
2005   int length;
2006 
2007   if(tracing){
2008     printf("TRACING: remove_checkpoint\n"); 
2009   }
2010   
2011   length = strlen(lockdir) +  strlen(hostname) + 64;
2012   filename    = (char *)malloc(length + 1);
2013  
2014   snprintf(filename,    length, "%s/dbupdate.checkpoint.%s.%ld",     lockdir, hostname, pid );
2015 
2016   unlink(filename);
2017  
2018   /* free the char * */
2019   free(filename);
2020 
2021 }
2022 
2023 
2024 
2025 
2026 /* main */
2027 int main(int argc, char **argv, char **envp){
     /* [<][>][^][v][top][bottom][index][help] */
2028   /* init_and_set_options(argc, argv, envp); */
2029 
2030   int i,j;
2031   char ** temp_vector;
2032   char * temp;
2033   char * temp_upd_file = NULL;
2034   char *input_file_name = NULL;
2035   GHashTable *AUTO_NIC_hdl_hash;
2036   credentials_struct credentials;
2037   FILE * upd_file;
2038   char c;
2039   char * mheader_replaced = NULL;
2040   char * mailtxt_replaced = NULL;
2041 
2042   /* temp variables to read from conf */
2043   ca_updDbSource_t *upd_source_hdl;
2044 
2045   GHashTable *ntfy_hash, *forw_hash, *cross_hash;
2046   
2047 
2048   char * ack_file_name;
2049   char *config_file_name = NULL;
2050 
2051 
2052   /* to use EP module */
2053   EP_Mail_DescrPtr p; 
2054   EPTokenPtr pt;
2055   EPTokenPtr list_item;
2056   EPTokenKeysPtr ptk;
2057 
2058   char * temp_keyid;
2059 
2060   /* a variable to be used to know if the part is pgp_signed or not */
2061   int pgp_signed = 0;
2062 
2063   int ch;
2064   char * to_address = NULL;
2065   char * subject = NULL;
2066   char * reply_to = NULL;
2067     
2068 
2069   /* create notification hashes */
2070   ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
2071   forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
2072   cross_hash = g_hash_table_new(g_str_hash, g_str_equal);
2073       
2074   credentials.password_list = NULL;
2075   credentials.from = NULL;
2076 
2077   AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);       
2078   
2079   /* initialise the rpsl dictionary */
2080   rpsl_load_dictionary(RPSL_DICT_FRONT_END);
2081 
2082   while ((ch = getopt(argc, argv, "MtSTf:c:sn")) != -1){
2083           switch(ch) {
2084           case 'M':
2085                   reading_from_mail = 1;
2086                   break;
2087           case 'f':
2088                   input_file_name = strdup(optarg);
2089                   break;
2090           case 'c':
2091                   config_file_name = strdup(optarg);
2092                   break;
2093           case 't': 
2094                   tracing = 1;
2095                   break;
2096           /* Test mode? In test mode, creation of mntners and as-blocks is possible, without overriding */        
2097           case 'T':
2098                   test_mode = 1; 
2099                   break;
2100           /* Supress acks and notifications? If yes, the acks and notifs will go to DEFMAIL config var */        
2101           case 'S': 
2102                   supress_ack_notif = 1;
2103                   break;
2104           /* Print out the ack to stdout? */        
2105           case 's':
2106                   print_out_ack = 1;
2107                   break;
2108           /* are we processing networkupdate? (invoked via inetd) */        
2109           case 'n':
2110                   networkupdate = 1;
2111                   break;
2112           case '?':
2113           default:
2114                   printf("Unknown option\n"); exit(1);
2115           }
2116   }
2117 
2118 
2119   /* config stuff */
2120   /* if -c flag is given, use the named file as config file, otherwise use
2121      default filename */ 
2122   if ( config_file_name != NULL)
2123   {
2124     /*ca_readConfig(config_file_name, confVars, VARS);*/
2125     ca_init(config_file_name);
2126         free(config_file_name);
2127   }
2128   else
2129   {
2130     /*ca_readConfig("dbupdate.conf", confVars, VARS);*/
2131     ca_init("dbupdate.conf");
2132   }
2133 
2134   error_init(argc, argv);
2135 
2136 
2137   tmpdir = ca_get_tmpdir;
2138   tmpdir = g_strstrip(tmpdir);
2139   lockdir = ca_get_lockdir;
2140   mailcmd = ca_get_mailcmd;
2141   mailcmd = g_strstrip(mailcmd);
2142   notitxt = ca_get_notitxt;
2143   mailtxt = ca_get_mailtxt; 
2144   successtxt = ca_get_successtxt;
2145   failuretxt = ca_get_failuretxt;
2146   helpheader = ca_get_helpheader;
2147   defmail = ca_get_defmail; defmail = UP_remove_EOLs(defmail);
2148   crosslog = ca_get_crosslog;
2149   fwtxt = ca_get_fwtxt;
2150   acksig = ca_get_acksig;
2151   humailbox = ca_get_humailbox;
2152   humailbox = g_strstrip(humailbox);
2153   autobox = ca_get_autobox;
2154   overridecryptedpw = ca_get_overridecryptedpw;
2155   overridecryptedpw = g_strstrip(overridecryptedpw);
2156   updlog = ca_get_updlog;
2157   acklog = ca_get_acklog;
2158   notiflog = ca_get_notiflog;
2159   notimailtxt = ca_get_notimailtxt;  
2160   notinetworktxt = ca_get_notinetworktxt;
2161   forwlog = ca_get_forwlog;
2162   fwmailtxt = ca_get_fwmailtxt;
2163   mtfwheader = ca_get_mtfwheader;
2164   mtfwtxt = ca_get_mtfwtxt;
2165   country = ca_get_country;
2166   pgppath = ca_get_pgppath;
2167   gpgcmd = ca_get_gpgcmd;
2168   autodbmhelp = ca_get_autodbmhelp;
2169   allocmnt = ca_get_allocmnt; allocmnt = UP_remove_EOLs(allocmnt);
2170   /* convert all '\t's, '\n's and '\r's in allocmnt to white spaces */
2171   for(i=0;i<strlen(allocmnt);i++){
2172     if(allocmnt[i] == '\r' || allocmnt[i] == '\n' || allocmnt[i] == '\t'){
2173       allocmnt[i] = ' ';
2174     }
2175   }
2176   cn_subject_add = ca_get_cn_subject_add; cn_subject_add = UP_remove_EOLs(cn_subject_add);
2177   cn_subject_del = ca_get_cn_subject_del; cn_subject_del = UP_remove_EOLs(cn_subject_del);
2178   cn_explain_add = ca_get_cn_explain_add;
2179   cn_explain_del = ca_get_cn_explain_del;
2180   cn_overlap_add = ca_get_cn_overlap_add;
2181   cn_overlap_del = ca_get_cn_overlap_del;
2182   cno_subject_add = ca_get_cno_subject_add; cno_subject_add = UP_remove_EOLs(cno_subject_add); 
2183   cno_subject_del = ca_get_cno_subject_del; cno_subject_del = UP_remove_EOLs(cno_subject_del);
2184   cno_explain_add = ca_get_cno_explain_add;
2185   cno_explain_del = ca_get_cno_explain_del;
2186   cno_overlap_add = ca_get_cno_overlap_add;
2187   cno_overlap_del = ca_get_cno_overlap_del;
2188   copyright_notice = ca_get_pw_resp_header;
2189   mheader = ca_get_mheader;
2190   pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
2191   sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
2192   if(test_mode != 1){/* if it is not already set to 1 (from command line), read from config */
2193     
2194     test_mode = ca_get_testmode;
2195   }
2196   /* retrieve source variables */
2197   upd_source_hdl = ca_get_UpdSourceHandle(CA_UPDSOURCE);
2198 
2199   if(upd_source_hdl == NULL){
2200     printf("There must be one updateable source in the config file. Exiting.\n");
2201     ER_perror(FAC_UP, UP_CONFERR, "There must be one updateable source in"
2202                                   " the config file. Exiting.");
2203     exit(1);
2204   }else{
2205     if(tracing){
2206       printf("\nTRACING: The upd_source_hdl is: %s\n", upd_source_hdl->name);
2207     }
2208     sources[0] = strdup(upd_source_hdl->name);
2209     update_host = upd_source_hdl->whoisd_host;
2210     query_host = strdup(update_host);
2211     update_port = upd_source_hdl->updPort;
2212     query_port = upd_source_hdl->qryPort;
2213     DBhost = upd_source_hdl->updDb.host;
2214     DBport = upd_source_hdl->updDb.port;
2215     DBname = upd_source_hdl->updDb.dbName;
2216     DBuser = upd_source_hdl->updDb.user;
2217     DBpasswd = upd_source_hdl->updDb.password; 
2218   }
2219 
2220 
2221   /* construct country array from country string variable */
2222   
2223   temp_vector = g_strsplit(country, "\n", 0);
2224   for (i=0, j=0; temp_vector[i] != NULL; i++)
2225   {
2226     temp_vector[i] == g_strstrip(temp_vector[i]);
2227     if (strlen(temp_vector[i]) > 0)
2228         {
2229       countries[j] = strdup(temp_vector[i]);
2230       g_strup(countries[j++]);
2231     }
2232   }
2233   countries[j] = NULL; /* mark the end of array */
2234   g_strfreev(temp_vector);
2235   if (tracing)
2236   {
2237     printf("TRACING: number of countries [%i]\n", j);
2238   }
2239 
2240   /* hard code the nicsuffixes for now, but should be a configurable variable */
2241 
2242   nicsuffixes[0] = strdup("RIPE");
2243   nicsuffixes[1] = strdup("ORG");
2244   nicsuffixes[2] = strdup("ARIN");
2245   nicsuffixes[3] = strdup("RADB");
2246   nicsuffixes[4] = strdup("APNIC");
2247   nicsuffixes[5] = strdup("RIPN");
2248   nicsuffixes[6] = NULL;
2249   
2250   if (tracing)
2251   {
2252     /* print out the config variables for debugging */
2253     printf("TMPDIR is: [%s]\n", tmpdir);
2254     printf("MAILCMD is: [%s]\n", mailcmd);
2255     printf("NOTITXT is: [%s]\n", notitxt);
2256     printf("CROSSLOG is: [%s]\n", crosslog);
2257     printf("FWTXT is: [%s]\n", fwtxt);
2258     printf("HUMAILBOX is: [%s]\n", humailbox);
2259     printf("AUTOBOX is: [%s]\n", autobox);
2260     printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
2261     printf("ACKLOG is: [%s]\n", acklog);
2262     printf("NOTIFLOG is: [%s]\n", notiflog);
2263     printf("FORWLOG is: [%s]\n", forwlog);
2264     printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
2265     printf("FWMAILTXT is: [%s]\n", fwmailtxt);
2266 /*   printf("COUNTRY is: [%s]\n", country); */
2267     printf("PGPPATH is: [%s]\n", pgppath);
2268     printf("UPDATE_HOST is: [%s]\n", update_host);
2269     printf("UPDATE_PORT is: [%i]\n", update_port);
2270     printf("QUERY_HOST is: [%s]\n",  query_host);
2271     printf("QUERY_PORT is: [%i]\n",  query_port);   
2272     printf("LOCKDIR is: [%s]\n", lockdir); 
2273     printf("TESTMODE is: [%i]\n", test_mode);
2274     printf("CNO_SUBJECT_ADD is: [%s]\n", cno_subject_add);
2275     printf("CNO_SUBJECT_DEL is: [%s]\n", cno_subject_del);
2276   }
2277   /* end of config stuff */
2278 
2279 
2280   /* set hostname global variable */
2281   gethostname(hostname, MAXHOSTNAMELEN);
2282 
2283   /* set pid global variable */
2284   pid = getpid(); 
2285 
2286   /* create the lock file and lock it */
2287   /* lockfile = create_lock_file(); */
2288 
2289   /* initialize the parser */
2290 /*  schema.initialize(); */
2291 
2292 
2293   /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
2294       also creates it) */
2295   ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
2296 
2297   /* initialize credentials.pgp_key_list */
2298   credentials.pgp_key_list = NULL;
2299 
2300 
2301  
2302   if (reading_from_mail)
2303   {
2304     if (input_file_name != NULL)
2305     {
2306       temp_upd_file = generate_upd_file();
2307       if (tracing)
2308       {
2309         printf("TRACING: temp_upd_file is [%s]\n", temp_upd_file);
2310       }
2311 
2312       /* first log the input in the upd log file */
2313       UP_add_to_upd_log(input_file_name);
2314  
2315       
2316       MM_store(input_file_name, temp_upd_file, 0);
2317       p = EP_ParseMail(input_file_name, tmpdir, pgp_public_key_ring, gpgcmd);
2318       
2319     }
2320     else
2321     { /* input_file_name == NULL */
2322       temp_upd_file = generate_upd_file();
2323       MM_store("-", temp_upd_file, 0);
2324 
2325       /* first log the input in the upd log file */
2326       UP_add_to_upd_log(temp_upd_file);
2327       
2328       p = EP_ParseMail(temp_upd_file, tmpdir, pgp_public_key_ring, gpgcmd);
2329 
2330     }
2331 
2332     /* write off the checkpoint file */
2333     write_checkpoint(1);
2334 
2335     /* the new stuff using the EP module's interface */
2336 
2337     if(p->from != NULL && p->from->field != NULL)
2338     {
2339       credentials.from = (char *)malloc(strlen(p->from->field) + strlen("From:") + 1);
2340       sprintf(credentials.from, "From:%s", p->from->field);
2341       credentials.from_email = strdup(p->from->field); /* This doesn't contain "From:" */
2342       /* cut off the '\n's and '\r's at the end */
2343       UP_remove_EOLs(credentials.from);
2344       UP_remove_EOLs(credentials.from_email);
2345 
2346       /* now, there is a problem with EP module (or c-client): the p->from->field
2347          would contain only the first line if the "From" field has multiple lines.
2348          As a temp solution, we will add the second line (if it exists) explicitely */
2349       /* This is not a problem, it is the way the imap is written.
2350          It returns multiple lines as a linked list, so loop for all the lines */
2351       while ( (p->from = p->from->next) != NULL && p->from->field != NULL)
2352       { /* there is another line */
2353         credentials.from = (char *)realloc(credentials.from, strlen(credentials.from) + strlen(p->from->field) + 1);
2354         strcat(credentials.from, p->from->field);
2355         credentials.from_email = (char *)realloc(credentials.from_email, strlen(credentials.from_email) + strlen(p->from->field) + 1);
2356         strcat(credentials.from_email, p->from->field);
2357         UP_remove_EOLs(credentials.from);
2358         UP_remove_EOLs(credentials.from_email);
2359       }
2360     }
2361     else
2362     {
2363       credentials.from = strdup("");
2364       credentials.from_email = strdup("");
2365     }
2366     
2367     update_mail_sender = strdup(credentials.from_email); 
2368     
2369     if (tracing)
2370     {
2371       printf("TRACING: From field is: [%s]\n", credentials.from);
2372       printf("TRACING: update_mail_sender is: [%s]\n", update_mail_sender);
2373     }
2374     
2375 
2376     if(p->cc != NULL && p->cc->field != NULL)
2377     {
2378       update_mail_cc = strdup(p->cc->field);
2379       /* cut off the '\n's and '\r's at the end */
2380       UP_remove_EOLs(update_mail_cc);
2381 
2382       /* loop for all multiple lines */
2383       while ( (p->cc = p->cc->next) != NULL && p->cc->field != NULL)
2384       { /* there is another line */
2385         update_mail_cc = (char *)realloc(update_mail_cc, strlen(update_mail_cc) + strlen(p->cc->field) + 1);
2386         strcat(update_mail_cc, p->cc->field);
2387         UP_remove_EOLs(update_mail_cc);
2388       }
2389     }
2390     else
2391       update_mail_cc = strdup("");
2392     
2393     if (tracing)
2394     {
2395       printf("TRACING: Cc field is: [%s]\n", update_mail_cc);
2396     }
2397     
2398                
2399     if(p->subject != NULL && p->subject->field != NULL)
2400     {
2401       subject = strdup(p->subject->field);
2402       /* cut off the '\n' and '\r' from the end */
2403       UP_remove_EOLs(subject);
2404 
2405       /* loop for all multiple lines */
2406       while ( (p->subject = p->subject->next) != NULL && p->subject->field != NULL)
2407       { /* there is another line */
2408         subject = (char *)realloc(subject, strlen(subject) + strlen(p->subject->field) + 1);
2409         strcat(subject, p->subject->field);
2410         UP_remove_EOLs(subject);
2411       }
2412     }
2413     else
2414       subject = strdup("");
2415     
2416     update_mail_subject = strdup(subject);
2417 
2418     /* parse the subject line */ 
2419     subject_result = UP_subject_process(update_mail_subject); 
2420 
2421 
2422     if(p->reply_to != NULL && p->reply_to->field != NULL)
2423     {
2424       reply_to = strdup(p->reply_to->field);
2425       /* cut off the '\n' and '\r' from the end */                    
2426       UP_remove_EOLs(reply_to);
2427 
2428       /* loop for all multiple lines */
2429       while ( (p->reply_to = p->reply_to->next) != NULL && p->reply_to->field != NULL)
2430       { /* there is another line */
2431         reply_to = (char *)realloc(reply_to, strlen(reply_to) + strlen(p->reply_to->field) + 1);
2432         strcat(reply_to, p->reply_to->field);
2433         UP_remove_EOLs(reply_to);
2434       }
2435     }
2436     else
2437       reply_to = strdup("");
2438 
2439     
2440     to_address = find_email_address(credentials.from);
2441 
2442     /* if Reply_To was available in the incoming header, then use it */
2443     if (strlen(reply_to) > 0)
2444     {
2445       to_address = (char *)realloc(to_address, strlen(reply_to) + 1);
2446       to_address = strcpy(to_address, reply_to);
2447       to_address = find_email_address(to_address); /* so that we take only the email address */
2448     }
2449 
2450     if (p->message_id != NULL && p->message_id->field != NULL)
2451     {
2452       update_mail_ID = strdup(p->message_id->field);
2453       /* cut off the '\n' and '\r' from the end */
2454       UP_remove_EOLs(update_mail_ID);
2455 
2456       /* loop for all multiple lines */
2457       while ( (p->message_id = p->message_id->next) != NULL && p->message_id->field != NULL)
2458       { /* there is another line */
2459         update_mail_ID = (char *)realloc(update_mail_ID, strlen(update_mail_ID) + strlen(p->message_id->field) + 1);
2460         strcat(update_mail_ID, p->message_id->field);
2461         UP_remove_EOLs(update_mail_ID);
2462       }
2463     }
2464     else
2465       update_mail_ID = strdup("");
2466     
2467 
2468     if(p->date != NULL && p->date->field != NULL)
2469     {
2470       update_mail_date = strdup(p->date->field);
2471       /* cut off the '\n' and '\r' from the end  */
2472       UP_remove_EOLs(update_mail_date);
2473 
2474       /* loop for all multiple lines */
2475       while ( (p->date = p->date->next) != NULL && p->date->field != NULL)
2476       { /* there is another line */
2477         update_mail_date = (char *)realloc(update_mail_date, strlen(update_mail_date) + strlen(p->date->field) + 1);
2478         strcat(update_mail_date, p->date->field);
2479         UP_remove_EOLs(update_mail_date);
2480       }
2481     }
2482     else
2483       update_mail_date = strdup("");
2484     
2485     if (tracing)
2486     {
2487       printf("\nEP_ShowTree outputs:\n");
2488       EP_ShowTree(p->tree);
2489     }
2490     
2491     pt = EP_GetTokens(p->tree, NULL, NULL);
2492 
2493     if(tracing){
2494       /* Print the list out (debugging) */
2495       printf("\nEP_PrintTokens outputs:\n");
2496       EP_PrintTokens(pt);
2497     }
2498 
2499     /* replace the global variables in mheader */
2500     mheader_replaced = UP_replace_globals(mheader);
2501     /* replace the global variables in mailtxt */
2502     mailtxt_replaced = UP_replace_globals(mailtxt);
2503 
2504     /* If this wasn't only a help request, then we need to process the input */
2505     if(subject_result.result != UP_SUBJ_HELP_REQ){
2506       
2507       /* ... and now process the items in the list */
2508       list_item = pt;
2509       while (list_item != NULL) {
2510         if(tracing){
2511           printf("\n\nWill process: %s, MIMEtype: %d\n", list_item->file, list_item->MIMEContentType);
2512         }
2513         /* initialize pgp_key_list (XXX This should be a proper freeing of the list) */
2514         credentials.pgp_key_list = NULL;
2515         ptk = list_item->keys;
2516         if(ptk != NULL){
2517           AK_add_to_ack(ack_file_name, "==== BEGIN PGP SIGNED PART (keyID(s):");
2518           pgp_signed = 1; 
2519           while (ptk != NULL) {
2520             if(tracing){
2521               printf("TRACING:     key: %.8X, isValid: %i\n", 
2522                    ptk->keyID, ptk->isValidPGPSignature);
2523             }
2524             temp_keyid = (char *)malloc(10);
2525             sprintf(temp_keyid, "%.8X", ptk->keyID);
2526             if(tracing){
2527               printf("TRACING: This key will be added to the list: [%s]\n", temp_keyid);
2528             }
2529             AK_add_to_ack(ack_file_name, " %s", temp_keyid);
2530             credentials.pgp_key_list = g_slist_append (credentials.pgp_key_list, temp_keyid);
2531             ptk = ptk->next;
2532             if(ptk != NULL){
2533               AK_add_to_ack(ack_file_name, ",");
2534             }else{
2535               AK_add_to_ack(ack_file_name, ") ====\n");
2536             }
2537           }
2538         }
2539         process_file(list_item->file, credentials, 
2540                      AUTO_NIC_hdl_hash, ack_file_name, 
2541                      ntfy_hash, forw_hash, cross_hash);
2542         if(pgp_signed){
2543           AK_add_to_ack(ack_file_name, "==== END PGP SIGNED PART ====\n\n");
2544           pgp_signed = 0;
2545         }
2546         list_item = list_item->next;
2547       }
2548 
2549     }else{/* this was only a help request (inferred from the "Subject" line of the upd message) */
2550 
2551       /* Print out the header of the acknowledgement */
2552 /*      AK_add_to_ack(ack_file_name, "To: %s\n%s\n\nHelp file requested so body of message ignored.\n\n\n"
2553           "============================================================\n\n", 
2554           to_address, mheader_replaced);  */
2555       AK_add_to_ack(ack_file_name, "\n============================================================\n\n");
2556 
2557       AK_add_file_to_ack(ack_file_name, autodbmhelp);
2558       AK_add_to_ack(ack_file_name, "\n============================================================\n\n");
2559        
2560     }
2561     
2562     EP_CleanTokens(pt);
2563 
2564     EP_MailDescrCleanUp(p);
2565 
2566     /* if we have created a temporary file for update, delete it */
2567     if(temp_upd_file != NULL){
2568 
2569       unlink(temp_upd_file);
2570       
2571     }
2572 
2573   }else if(networkupdate){
2574 
2575     /* process networkupdate. Since we use inetd, we just process stdin */
2576     process_networkupdate(credentials, AUTO_NIC_hdl_hash, ack_file_name, 
2577                           ntfy_hash, forw_hash, cross_hash); 
2578 
2579   }else{/* not reading from the mail message or from network */
2580     if(input_file_name != NULL){
2581 
2582       /* first log the input in the upd log file */
2583       UP_add_to_upd_log(input_file_name);
2584 
2585       
2586       write_checkpoint(1);
2587       process_file(input_file_name, credentials, 
2588                   AUTO_NIC_hdl_hash, ack_file_name, 
2589                   ntfy_hash, forw_hash, cross_hash);
2590     }else{/* the filename is not given, so we have to write 
2591              stdin to a temp file, and give it to process_file */
2592        temp_upd_file = generate_upd_file();
2593        if(tracing){
2594          printf("TRACING: main: temp_upd_file=%s\n", temp_upd_file);
2595        }
2596        if(( upd_file = fopen(temp_upd_file, "a")) == NULL){
2597          ER_perror(FAC_UP, UP_CANTOPENW, "Can't open ack file, %s", temp_upd_file);
2598        }
2599 
2600        while((c = getchar()) != EOF){
2601          fprintf(upd_file, "%c",c);
2602        }
2603        fclose(upd_file);
2604 
2605        write_checkpoint(1);
2606        process_file(temp_upd_file, credentials, 
2607                   AUTO_NIC_hdl_hash, ack_file_name, 
2608                   ntfy_hash, forw_hash, cross_hash);
2609        unlink(temp_upd_file);
2610         
2611     }
2612       
2613   }  
2614 
2615 
2616   /* post-process and send the ack */
2617   if(reading_from_mail && to_address != NULL){
2618     AK_send_ack(ack_file_name, to_address, mailcmd);
2619   }
2620 
2621   /* if our update wasn't a mail update OR we have been asked explicitely
2622      to print out the ack to the stdout, print it */
2623   if(!reading_from_mail || print_out_ack){
2624     AK_print_ack(ack_file_name);
2625   }
2626   
2627   AK_log_ack(ack_file_name, acklog);
2628   AK_delete_ack(ack_file_name);
2629 
2630   NT_send_ntfy_list(ntfy_hash, mailcmd);
2631   NT_log_ntfy_list(ntfy_hash, notiflog); 
2632   NT_delete_ntfy_list(ntfy_hash);
2633 
2634   NT_send_ntfy_list(forw_hash, mailcmd);
2635   NT_log_ntfy_list(forw_hash, forwlog); 
2636   NT_delete_ntfy_list(forw_hash);
2637 
2638 
2639   NT_send_ntfy_list(cross_hash, mailcmd);
2640   NT_log_ntfy_list(cross_hash, crosslog); 
2641   NT_delete_ntfy_list(cross_hash);
2642       
2643   /* remove the lock file */
2644   /* remove_lock_file(lockfile); */
2645   
2646  
2647   /* remove checkpoint file */
2648   remove_checkpoint();
2649 
2650   free(ack_file_name);
2651 
2652   if (tracing)
2653   {
2654     printf("TRACING: END\n");
2655   }
2656   
2657   return 0 ;
2658 }

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