bin/dbupdate/dbupdate.cc

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

FUNCTIONS

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

   1 /***************************************
   2   $Revision: 1.52 $
   3 
   4   DBupdate 
   5 
   6   Status: NOT REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (01/03/2000) Created.
  13   ******************/ /******************
  14   Copyright (c) 2000                              RIPE NCC
  15 
  16   All Rights Reserved
  17 
  18   Permission to use, copy, modify, and distribute this software and its
  19   documentation for any purpose and without fee is hereby granted,
  20   provided that the above copyright notice appear in all copies and that
  21   both that copyright notice and this permission notice appear in
  22   supporting documentation, and that the name of the author not be
  23   used in advertising or publicity pertaining to distribution of the
  24   software without specific, written prior permission.
  25 
  26   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  27   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  28   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  29   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  30   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  31   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  32  ***************************************/
  33 
  34 
  35 
  36 
  37 
  38 #include "dbupdate.h"
  39 #include "UP_extrnl_syntax.h"
  40 #include "er_yacc_helper.h"
  41 #include "erroutines.h"
  42 #include "ca_configFns.h"
  43 #include "ca_dictionary.h"
  44 #include "ca_macros.h"
  45 #include "ca_srcAttribs.h"
  46 #include "notification.h"
  47 #include "gpg.h"
  48 #include "mail_parser.h"
  49 
  50 int tracing = 0;
  51 int test_mode = 0;
  52 int supress_ack_notif = 0;
  53 
  54 /* do we process a mail */
  55 int reading_from_mail = 0;
  56 
  57 /* sender of the mail, in case of a mail update */
  58 char *update_mail_sender = NULL;
  59 char *update_mail_subject = NULL;
  60 char *update_mail_date = NULL;
  61 char *update_mail_ID = NULL;
  62 char *update_mail_cc = NULL;
  63 
  64 /* required configuration variables */
  65 char *tmpdir = NULL;
  66 char *lockdir = NULL;
  67 char *mailcmd = NULL;
  68 char *notitxt = NULL;
  69 char *notimailtxt = NULL;
  70 char *fwtxt   = NULL;
  71 char *fwmailtxt = NULL;
  72 char *mailtxt = NULL;
  73 char *defmail = NULL;
  74 char *notiflog = NULL;
  75 char *crosslog = NULL;
  76 char *acklog = NULL;
  77 char *forwlog = NULL;
  78 char *humailbox = NULL;
  79 char *autobox = NULL;
  80 char *overridecryptedpw = NULL;
  81 char *country = NULL;
  82 char *countries[400];
  83 char *sources[100];
  84 char *pgppath = NULL;
  85 char *gpgcmd = NULL;
  86 char *pgp_public_key_ring = NULL;
  87 char *update_host = NULL;
  88 int  update_port;
  89 char *query_host = NULL;
  90 int  query_port;
  91 char *cn_subject_add = NULL;
  92 char *cn_subject_del = NULL;
  93 char *cn_explain_add = NULL;
  94 char *cn_explain_del = NULL;
  95 char *cn_overlap_add = NULL;
  96 char *cn_overlap_del = NULL;
  97 char *cno_subject_add = NULL;
  98 char *cno_subject_del = NULL;
  99 char *cno_explain_add = NULL;
 100 char *cno_explain_del = NULL;
 101 char *cno_overlap_add = NULL;
 102 char *cno_overlap_del = NULL;
 103 char *mheader = NULL;
 104 char *DBhost = NULL;
 105 int  DBport;
 106 char *DBuser = NULL;
 107 char *DBname = NULL;
 108 char *DBpasswd = NULL;
 109 /* end of config variables */
 110 
 111 /* hostname and pid are used all over the program, so we save them into these variables */
 112 char hostname[MAXHOSTNAMELEN];
 113 //char * hostname;
 114 int pid;
 115 
 116 /* name of the lock file, which is used for the crash recovery mechanism */
 117 char * lock_file_name;
 118 
 119 void error_init(int argc, char ** argv) {
     /* [<][>][^][v][top][bottom][index][help] */
 120 
 121   ER_init("dbupdate", 1);
 122   
 123 
 124 } /* error_init() */
 125 
 126 
 127 
 128 
 129 
 130 
 131 /* 'lockfile' struct is for keeping both the name of the lock file and the file descriptor
 132     of it, which is open during the execution of dbupdate. We need the filedes to close it,
 133     when dbupdate finishes, and the name to delete the file. */
 134 typedef struct {
 135    char * lockname;
 136    int filedes;
 137 } lockfilestruct;
 138 
 139 
 140 lockfilestruct lockfile;
 141 
 142 
 143 
 144 /* Deletes the key defined in the incoming object (a key-cert object)
 145    from the public keyring. Returns NULL if there was no error,
 146    returns an error message if there is an error */
 147 char * delete_key(char * obj){
     /* [<][>][^][v][top][bottom][index][help] */
 148 
 149   struct ImportKeyObject iKO;
 150   char * obj_keyID;
 151   char * key_cert_attr;
 152   GSList * templist, * certiflist, * next;
 153   u32 keyID;
 154   char * tempfile;
 155   char ** lines;
 156   int i;
 157   FILE * key_file;
 158   char * temp, * temp2;
 159   char * error_string;
 160 
 161   templist = get_attr_list(obj, "key-cert");
 162   key_cert_attr = strdup((char *)templist->data);
 163   g_slist_free(templist);
 164 
 165   tempfile = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
 166   sprintf(tempfile, "%s/tmp-key.%i", tmpdir, pid /*getpid()*/);
 167   //printf("DEBUG: tempfile=%s\n", tempfile);
 168 
 169   /* now we must write certif attribute(s) of this key-certif into the tempfile */
 170   /* get the certif first */
 171   certiflist = get_attr_list(obj, "certif");
 172   if(( key_file = fopen(tempfile, "w")) == NULL){
 173      //fprintf(stderr, "Can't open temporary file, %s", tempfile);
 174      ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", tempfile);
 175      exit(1);
 176   }
 177   for( next = certiflist; next != NULL ; next = g_slist_next(next) ){
 178     lines = g_strsplit((char *)next->data, "\n", 0);
 179     //printf("DEBUG: attr: %s\n", (char *)next->data);
 180     if(lines[0] == NULL){/* if this was an empty attribute, just print an empty line */
 181       fprintf(key_file, "\n"); 
 182     }
 183     for(i = 0; lines[i] != NULL; i++){
 184       //printf("DEBUG: i=%i\n", i);
 185       temp = strdup(lines[i]);
 186       if(i != 0 && temp[0] == '+'){/* if it begins with a plus */
 187         temp2 = strdup(temp + 1);
 188         g_strstrip(temp2);
 189         fprintf(key_file, "%s\n", temp2);
 190         free(temp);free(temp2);
 191       }else{
 192         g_strstrip(temp);
 193         fprintf(key_file, "%s\n", temp);
 194         free(temp); 
 195       }
 196     }
 197     g_strfreev(lines);
 198     //fprintf(key_file, "%s\n", (char *)next->data);
 199   }
 200   fclose(key_file);
 201   g_slist_free(certiflist);
 202 
 203   strcpy(iKO.iFilename, tempfile);
 204 
 205   printf("DEBUG: delete_key: key_cert_attr: [%s]\n", key_cert_attr);
 206   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
 207   printf("DEBUG: delete_key: obj_keyID: [%s]\n", obj_keyID);
 208   keyID = strtoul(obj_keyID, NULL, 16);
 209   printf("DEBUG: delete_key: keyID is: %u, %X\n", keyID, keyID);
 210   
 211   
 212   
 213   strcpy(iKO.keyRing, pgp_public_key_ring);
 214   //iKO.keyID = keyID; 
 215   PA_RemoveKey(&iKO);
 216   printf("DEBUG: importKeyObj status:\n");
 217   printf("DEBUG: isValid: %d\n", iKO.rc);
 218   
 219 
 220 
 221   unlink(tempfile);
 222   if(iKO.rc == iKO_OK){/* if PA_RemoveKey returned OK */
 223     return NULL;
 224   }else{/* if PA_RemoveKey returned not OK */
 225       switch(iKO.rc){
 226         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break; 
 227         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
 228         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
 229         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
 230         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
 231         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
 232         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
 233         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
 234         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
 235         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
 236         default:            error_string = strdup("general PGP error");
 237       }
 238       return error_string; 
 239   }
 240 
 241   return NULL;
 242 }
 243 
 244 
 245 /* Takes a key-certif object, extracts its 'certif' attribute and adds
 246    the key into public keyring
 247    If there is no problem, it returns NULL
 248    If there is a problem, then it returns a string which contains an error
 249    message */
 250 char * import_key(char *obj){
     /* [<][>][^][v][top][bottom][index][help] */
 251 
 252   char * tempfile;
 253   struct ImportKeyObject iKO;
 254   GSList * certiflist, * next, * templist;
 255   FILE * key_file;
 256   char keyID[9];
 257   char * obj_keyID, * key_cert_attr;
 258   char * error_string = NULL;
 259   char ** lines;
 260   int i;
 261   char * temp, * temp2;
 262    
 263   tempfile = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
 264   sprintf(tempfile, "%s/tmp-key.%i", tmpdir, pid /*getpid()*/);
 265   //printf("DEBUG: tempfile=%s\n", tempfile);
 266 
 267   /* now we must write certif attribute(s) of this key-certif into the tempfile */
 268   /* get the certif first */
 269   certiflist = get_attr_list(obj, "certif");
 270   if(( key_file = fopen(tempfile, "w")) == NULL){
 271      ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", tempfile);
 272      exit(1);
 273   }
 274   for( next = certiflist; next != NULL ; next = g_slist_next(next) ){
 275     lines = g_strsplit((char *)next->data, "\n", 0);
 276     if(lines[0] == NULL){/* if this was an empty attribute, just print an empty line */
 277       fprintf(key_file, "\n"); 
 278     }
 279     for(i = 0; lines[i] != NULL; i++){
 280       temp = strdup(lines[i]);
 281       if(i != 0 && temp[0] == '+'){/* if it begins with a plus */
 282         temp2 = strdup(temp + 1);
 283         g_strstrip(temp2);
 284         fprintf(key_file, "%s\n", temp2);
 285         free(temp);free(temp2);
 286       }else{
 287         g_strstrip(temp);
 288         fprintf(key_file, "%s\n", temp);
 289         free(temp); 
 290       }
 291     }
 292     g_strfreev(lines);
 293     //fprintf(key_file, "%s\n", (char *)next->data);
 294   }
 295   fclose(key_file);
 296   g_slist_free(certiflist);
 297 
 298   strcpy(iKO.iFilename, tempfile);
 299   strcpy(iKO.keyRing, pgp_public_key_ring);
 300   PA_ImportKey(&iKO);
 301 
 302   printf("importKeyObj status:\n");
 303     
 304   printf("isValid: %d\n", iKO.rc);
 305   printf("keyID: %08lX\n", iKO.keyID);
 306   snprintf(keyID, 9, "%08lX", iKO.keyID);
 307   printf("keyID: [%s]\n", keyID);
 308   
 309   unlink(tempfile);
 310   free(tempfile);
 311 
 312   
 313   templist = get_attr_list(obj, "key-cert");
 314   key_cert_attr = strdup((char *)templist->data);
 315   g_slist_free(templist);
 316 
 317   printf("key_cert_attr: [%s]\n", key_cert_attr);
 318   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
 319   printf("obj_keyID: [%s]\n", obj_keyID);
 320   if(iKO.rc == iKO_OK && (strcmp(obj_keyID, keyID) == 0)){/* if PA_ImportKey returned OK 
 321                                                             and the real keyID is equal to the
 322                                                             keyID in the 'key-cert' attribute */
 323     return NULL;
 324   }else{/* if PA_ImportKey returned not OK or obj_keyID, keyID didn't match */
 325     if(iKO.rc != iKO_OK){
 326       switch(iKO.rc){
 327         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break; 
 328         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
 329         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
 330         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
 331         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
 332         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
 333         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
 334         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
 335         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
 336         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
 337         default:            error_string = strdup("general PGP error");
 338       }
 339       return error_string; 
 340     }else{
 341       error_string = (char *)malloc(1024);/* this should be enough */
 342       sprintf(error_string, "Keyid for this certificate (%s) is not the same as the PGPKEY field (%s)", 
 343                  keyID, obj_keyID);
 344       return error_string;
 345     }
 346   }
 347       
 348 }
 349 
 350 
 351 
 352 /* Checks the object's syntax, retrives the old version of it from the db, 
 353    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
 354    integrity is checked, and the object is really committed to the db.
 355   
 356      Arguments:
 357         char * arg: The object,
 358         credentials_struct credentials: The struct containing the credentials, such as 
 359           'From:' field of the e-mail update,
 360         GHashTable * NIC_hdl_hash: A hash containing 
 361         char * ack_file_name:  The file name, to be used to store ACK message 
 362 */
 363 
 364 
 365 
 366 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name,
     /* [<][>][^][v][top][bottom][index][help] */
 367                    GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
 368     bool code = true;
 369     Object *o;
 370     char * old_version = NULL;
 371     o = new Object;
 372     int result = 0;
 373     int result_from_RIPupd = 0;
 374     char * result_from_import_key = NULL;
 375     char * result_from_delete_key = NULL;
 376     char * auto_nic = NULL;
 377     char * changed_obj = NULL;
 378     char * obj_with_AUTO_NIC_hdl;
 379     char * assigned_NIC;
 380     char * type;
 381     external_syntax_struct * external_syntax_results;
 382 
 383     //external_syntax_results = (external_syntax_struct *)malloc(sizeof(external_syntax_struct)); 
 384      
 385     char * value = NULL;/* these two are for */
 386     Attr * attr;        /* ack messages only */ 
 387     
 388     if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
 389        /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
 390        if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
 391          return UP_ANE; /* AUTO NIC hdl error */
 392        };
 393     }
 394    
 395     code = o->scan(arg,strlen(arg));
 396     if(code){
 397       type = get_class_type(o);
 398       /* is the object to be deleted? */
 399       if(o->isDeleted){
 400         old_version = get_old_version(arg);
 401         if(old_version == NULL){ /* the object doesn't exist in the db! */
 402           AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nEntry not found\n\n%s\n", 
 403                         o->type->getName(), get_search_key(o, o->type->getName(), arg), arg);
 404           return UP_NSO; /* no such object */
 405         }else {/* the object is in the db */
 406           if(identical(old_version, arg)){/* if the old & new versions are identical */
 407             result = check_auth(NULL, old_version, o->type->getName(), credentials);
 408             if(result == UP_AUTH_OK){ 
 409               if(tracing) {
 410                 printf("TRACING: Will send the obj to be deleted\n");
 411               }
 412               if(strcmp(type, "key-cert") == 0){
 413                 result_from_delete_key = delete_key(arg);
 414               }else{
 415                 result_from_delete_key = NULL;
 416               }
 417               /* if there was no problem with key deletion from the key-ring */
 418               if(result_from_delete_key == NULL){
 419                 result_from_RIPupd = send_object_db(arg, NULL, "DEL");
 420                 if(result_from_RIPupd == 0){
 421                   AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n", 
 422                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 423                   NT_write_all_ntfs(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 424                 }else{
 425                   AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nReferential integrity failure\n",
 426                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 427                 }
 428                 result_from_RIPupd = 0;
 429               }else{
 430                  AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
 431                                 o->type->getName(), get_search_key(o, o->type->getName(), arg), result_from_delete_key);
 432               }
 433             }else{ /* auth failed */
 434               if(tracing) {
 435                 printf("TRACING: Auth failed\n");
 436               }
 437 
 438               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuth failed\n",
 439                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
 440               NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 441               return UP_AUF; /* Auth failed */
 442             } 
 443           }else{/* the new & old versions do not match */
 444             AK_add_to_ack(ack_file_name, "\nDelete FAILED: new & old versions do not match\n");
 445             return UP_NOM; /* new & old versions do not match */
 446           }
 447         }
 448       }else {/* the object is _not_ to be deleted */
 449         
 450         if(has_AUTO_NIC_hdl(arg)){/* if the object has an AUTO NIC hdl */
 451           external_syntax_results = UP_check_external_syntax(o, arg);
 452           if(external_syntax_results->result != 1 && external_syntax_results->result != 3){/* if there is no error */
 453             /* then its nic-hdl attribute must be modified so that RIPupdate
 454                would understand that it must assign a NIC handle to it */
 455             /* but first check the auth */
 456             result = check_auth(arg, NULL, o->type->getName(), credentials);
 457             if(result == UP_AUTH_OK){
 458               if(tracing) {                                
 459                   printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
 460               }
 461               auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
 462               obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(external_syntax_results->new_obj/*arg*/, auto_nic);
 463               if(tracing) {  
 464                 printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
 465                 printf("TRACING: Will send the obj to be added\n");
 466               }
 467               assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
 468               result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
 469               if(result_from_RIPupd == 0){
 470                 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", 
 471                               o->type->getName(), assigned_NIC);
 472                 NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 473               }else{
 474                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
 475                               o->type->getName(), arg);
 476               }
 477               result_from_RIPupd = 0;
 478               if(tracing && assigned_NIC != NULL) {  
 479                 printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
 480               }
 481               if(assigned_NIC != NULL){
 482                 if(tracing){
 483                   printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
 484                 }
 485                 g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
 486                 if(tracing){
 487                   printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
 488                 }
 489               }
 490               
 491             }else{
 492               /* auth failed ! */
 493               if(tracing) {
 494                 printf("TRACING: Auth failed\n");
 495               }
 496   
 497               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
 498                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
 499               NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 500               return UP_AUF; /* Auth failed */
 501             }
 502           }else{/* external syntax check failed */
 503             printf("DEBUG: external syntax check failed (1)\n");
 504             AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s",
 505                    o->type->getName(), get_search_key(o, o->type->getName(), arg), 
 506                    arg, external_syntax_results->error_str);
 507           }
 508         }
 509         else{ 
 510           old_version = get_old_version(arg);
 511           if(old_version != NULL){/* so, this is an update operation */
 512             external_syntax_results = UP_check_external_syntax(o, arg);
 513             if(external_syntax_results->result != 1 && external_syntax_results->result != 3){/* if there is no error */
 514               result = check_auth(arg, old_version, o->type->getName(), credentials);    
 515               if(result == UP_AUTH_OK){
 516                 if(tracing) {                                
 517                   printf("TRACING: Will send the obj to be updated\n");
 518                 }
 519                 result_from_RIPupd = send_object_db(external_syntax_results->new_obj/*arg*/, NULL, "UPD");
 520                 if(result_from_RIPupd == 0){
 521                   AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
 522                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 523                   NT_write_all_ntfs(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 524                 }else{
 525                   AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
 526                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 527                 }
 528                 result_from_RIPupd = 0;
 529               }else{
 530                 /* auth failed ! */
 531                 if(tracing) {
 532                   printf("TRACING: Auth failed\n");
 533                 }
 534   
 535                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
 536                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
 537                 NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 538                 return UP_AUF; /* Auth failed */
 539               }
 540             }else{/* if there is an error in external syntax checks */
 541               printf("DEBUG: External syntax check failed (2)\n");
 542               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s",
 543                    o->type->getName(), get_search_key(o, o->type->getName(), arg), 
 544                    arg, external_syntax_results->error_str);
 545             }
 546           }else { /* old_version  == NULL, so, creation */
 547             external_syntax_results = UP_check_external_syntax(o, arg);
 548             if(external_syntax_results->result != 1 && external_syntax_results->result != 3){/* if there is no error */
 549               result = check_auth(arg, NULL, o->type->getName(), credentials);
 550               if(result == UP_AUTH_OK){ 
 551                 if(tracing) {                                
 552                   printf("TRACING: Will send the obj to be added\n");
 553                 }
 554                  /* if the object is a key-cert object, then we must import the PGP key */
 555                 if(strcmp(type, "key-cert") == 0){
 556                   result_from_import_key = import_key(arg);
 557                 }else{
 558                   result_from_import_key = NULL;
 559                 }
 560                 if(result_from_import_key == NULL){/* no PGP problem */
 561                   result_from_RIPupd = send_object_db(external_syntax_results->new_obj/*arg*/, NULL, "ADD");
 562                   if(result_from_RIPupd == 0){/* if there was no problem */
 563                     AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
 564                                   o->type->getName(), get_search_key(o, o->type->getName(), arg));
 565                     NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 566 
 567                   }else{
 568                     AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
 569                                   o->type->getName(), get_search_key(o, o->type->getName(), arg));
 570                   }
 571                   result_from_RIPupd = 0;
 572                 }else{/* there was a problem with PGP key import */
 573                   AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
 574                                   o->type->getName(), get_search_key(o, o->type->getName(), arg),
 575                                   result_from_import_key);
 576                 }
 577               }else{
 578                 /* auth failed ! */
 579                 if(tracing) {
 580                   printf("TRACING: Auth failed\n");
 581                 }
 582 
 583                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
 584                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
 585                 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 586                 return UP_AUF; /* Auth failed */
 587               }
 588             }else{
 589               printf("DEBUG: External syntax check failed (3)\n");
 590               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s%s",
 591                               o->type->getName(), get_search_key(o, o->type->getName(), arg), 
 592                               arg, external_syntax_results->error_str);
 593             }
 594           } 
 595         }
 596 
 597       }
 598     }else{/* even if obj doesn't parse properly, it may be a legacy object
 599             which the user wants to delete... */
 600        if(tracing){   
 601          printf("TRACING: Object didn't parse\n");   
 602        }
 603        AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
 604        
 605        if(o->attrs.head() != NULL){
 606          for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 607            if(attr->len > 0){
 608              value = (char*)malloc(attr->len);
 609              strncpy(value, (char *)(arg+attr->offset) ,
 610                attr->len - 1);
 611              value[attr->len - 1] = '\0';
 612              AK_add_to_ack(ack_file_name, "%s\n", value);
 613              if(!attr->errors.empty()){
 614                AK_add_to_ack_string(ack_file_name, attr->errors);
 615              }
 616              free(value);
 617            }else{
 618              if(!attr->errors.empty()){
 619                AK_add_to_ack_string(ack_file_name, attr->errors);
 620              }
 621            }
 622          }
 623        }
 624        if(o->has_error){
 625          AK_add_to_ack_string(ack_file_name, o->errors);
 626        }
 627        AK_add_to_ack(ack_file_name, "\n");
 628        
 629        return UP_NIY; /* XXX Not implemented yet */
 630     }
 631 }
 632 
 633 
 634 
 635 
 636 /* removes the '\n's and '\r's at the end of the arg, and returns it  */
 637 char * remove_EOLs(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 638 
 639   while(strlen(arg) > 0 &&
 640         (arg[strlen(arg) - 1] == '\n' || 
 641          arg[strlen(arg) - 1] == '\r')){
 642     arg[strlen(arg) - 1] = '\0';
 643   }
 644  
 645   return arg;
 646 }
 647 
 648 
 649 
 650 /* processes the objects in the given file */
 651 void process_file(char * filename, credentials_struct credentials, 
     /* [<][>][^][v][top][bottom][index][help] */
 652                   GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name, 
 653                   GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
 654 
 655 FILE * input_file;
 656 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;   
 657 GSList *next = NULL;
 658 int object_count = 0;
 659 char *object = NULL;
 660 char * line;
 661 int result = 0;
 662 struct VerifySignObject vSO, *pvSO;
 663 
 664 
 665   
 666   line = (char *)malloc(1024);
 667 
 668      if((input_file = fopen(filename, "r")) == NULL){
 669          ER_perror(FAC_UP, UP_CANTOPEN, "Couldn't open the file %s: %s\n", filename, strerror(errno));
 670          exit(1);  
 671      }
 672 
 673   
 674     while(fgets(line, 1023, input_file) != NULL){
 675       /* first, if it is a pasword, save it, but do not regard it as an attrib */ 
 676       if(strstr(line, "password:") == line){
 677         if(tracing){
 678           printf("TRACING: This is a password\n");
 679         }
 680         credentials.password_list = g_slist_append(credentials.password_list, 
 681                                       g_strstrip(strdup(line + strlen("password:"))));
 682         continue;
 683       }
 684       line = remove_EOLs(line); /* remove '\n's and '\r' first */
 685       if(strlen(line) == 0){/* then, this was an empty line */
 686         if(object != NULL){
 687            list_of_objects = g_slist_append(list_of_objects, object);
 688            if(tracing){
 689              printf("TRACING: added an object: [%s]\n", object);
 690            }
 691            object = NULL;
 692         }
 693       }else{
 694         if(object == NULL && strlen(line) != 0){
 695           object = (char *)malloc(strlen(line) + 2);
 696           object = strcpy(object, line);
 697           object = strcat(object, "\n"); /* add EOL again (we removed it before) */
 698         }
 699         else{
 700           object = (char *)realloc(object, strlen(object) + strlen(line) + 2);
 701           object = strcat(object, line);
 702           object = strcat(object, "\n");
 703         }
 704       }
 705       
 706       ///* if the length of the line read is 2, then this is an empty line ("\n\r")*/
 707       //if(strlen(line) == 2){
 708       //  if(object != NULL){
 709       //     list_of_objects = g_slist_append(list_of_objects, object);
 710       //     object = NULL;
 711       //  }
 712       //}else{
 713       //  /* if the line contains only the EOL sequence "\n\r" */
 714       //  if(object == NULL && strlen(line) != 2){
 715       //    object = (char *)malloc(strlen(line));
 716       //    object = strdup(line);
 717       //  }
 718       //  else{
 719       //    object = (char *)realloc(object, strlen(object) + strlen(line) + 1);
 720       //    object = strcat(object, line);
 721       //  }
 722       //}
 723       
 724     }
 725     fclose(input_file);
 726 
 727     /* now, if at the very and of the input file there wasn't an 
 728        empty line, we have to add the remaining object in the 'object'
 729        variable */
 730     if(object != NULL){
 731        list_of_objects = g_slist_append(list_of_objects, object);
 732        object = NULL;
 733     }
 734 
 735 
 736 
 737     if(tracing) {
 738        printf("TRACING: Will process the objects in the list\n");
 739     }
 740     next = list_of_objects;
 741     object_count = 0;
 742     for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
 743       object_count++;
 744 
 745       if(tracing) {
 746         cout << "TRACING: Got an object from the list" << endl;
 747         cout << (char *)next->data << endl;
 748       }
 749       
 750       if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
 751         if(tracing) {
 752           printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
 753         }
 754         list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
 755       }else{
 756         result = 0;
 757         result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
 758                                  ntfy_hash, forw_hash, cross_hash);
 759       }
 760     }
 761 
 762     if(tracing) {
 763       printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
 764     }
 765   
 766     if(tracing) {
 767       printf("TRACING: will start to process the second list\n");
 768     }
 769   
 770     for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
 771       if(tracing) {
 772         printf("TRACING: Will process object: %s\n", (char *)next->data);
 773       }
 774       result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
 775                                ntfy_hash, forw_hash, cross_hash);
 776     }
 777   
 778 }/* process_file */
 779 
 780 
 781 
 782 
 783 
 784 
 785 /*  Generates a unique file name and returns the full path of the filename 
 786     for storing notification message.  */
 787       
 788 char * generate_upd_file(){
     /* [<][>][^][v][top][bottom][index][help] */
 789 
 790    char * name;
 791      
 792    /* allocate space for name.  32 should be enough for PID */
 793    name = (char*)malloc(strlen("/tmp/dbupdate-tmp.") + strlen("notify") +32 ); 
 794    
 795    sprintf(name, "/tmp/dbupdate-tmp.%i", pid /*getpid()*/);
 796 
 797      
 798    return name;
 799       
 800 }
 801 
 802 
 803 /* create_lock_file: creates a lock file in lockdir and locks it. This is a 
 804    part of crash recovery. Must be called in the beginning of the run. At the
 805    end, the file must be removed. */
 806 /* The idea: Create the "lock" file, and lock it. When another process starts
 807    running, it checks the existing lock files. If some exists, then it checks
 808    if it is locked or not. It not locked, then assumes that the corresponding
 809    dbupdate is alredy running. If not locked, assumes that it has crashed. 
 810    (note: when a process crashes, the kernel releases all the files locked by
 811    this process [by the OS]) 
 812    Problem: locking doesn't work properly on some NFS implementations. */
 813 
 814 lockfilestruct create_lock_file(){
     /* [<][>][^][v][top][bottom][index][help] */
 815   
 816   lockfilestruct lock;
 817   int file;
 818   int length;
 819 
 820   /* allocate space for file name */
 821   length = strlen(lockdir) +  strlen(hostname) + 32;
 822   lock.lockname = (char *)malloc(length + 1);
 823 
 824   snprintf(lock.lockname, length, "%s/dbupdate.%s.%ld", lockdir, hostname, pid /*getpid()*/);
 825 
 826   /* we will lock the file, so we have to use open(), but not fopen() (see man 
 827      page of lockf(3C)) */
 828   if(( file = open(lock.lockname, O_RDWR|O_CREAT)) == -1){
 829     ER_perror(FAC_UP, UP_CANTOPEN, "Can't open lock file, %s", lock.lockname);
 830     exit(1);
 831   }
 832  
 833   if(lockf(file, F_LOCK, 0) == -1){
 834     ER_perror(FAC_UP, UP_CANTLOCK, "Can't lock the file, %s", lock.lockname);
 835     exit(1);
 836   }; 
 837 
 838   lock.filedes = file;
 839 
 840   return lock;
 841 
 842 }
 843 
 844 
 845 
 846 
 847 
 848 /* remove_lock_file(): unlocks and removes the file  */
 849 void remove_lock_file(lockfilestruct lockfile){
     /* [<][>][^][v][top][bottom][index][help] */
 850 
 851   close(lockfile.filedes); /* this will remove the lock at the same time */ 
 852   unlink(lockfile.lockname);
 853 
 854 }
 855 
 856 
 857 
 858 /* writes the checkpoint file with the specified state */
 859 void write_checkpoint(int state){
     /* [<][>][^][v][top][bottom][index][help] */
 860 
 861   char * filename;
 862   char * tmpfilename;
 863   int length;
 864   FILE * file;
 865 
 866   if(tracing){
 867     printf("DEBUG: write_checkpoint, state=[%i]\n", state); 
 868   }
 869   length = strlen(lockdir) +  strlen(hostname) + 64;
 870   filename    = (char *)malloc(length + 1);
 871   tmpfilename = (char *)malloc(length + 5);
 872  
 873   snprintf(filename,    length, "%s/dbupdate.chekpoint.%s.%ld",     lockdir, hostname, pid );
 874   snprintf(tmpfilename, length, "%s/dbupdate.chekpoint.%s.%ld.tmp", lockdir, hostname, pid );
 875 
 876   if(( file = fopen(tmpfilename, "w")) == NULL){
 877     //fprintf(stderr, "Can't open temp checkpoint file, %s", tmpfilename);
 878     ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temp checkpoint file, %s", tmpfilename);
 879     exit(1);
 880   }
 881 
 882   fprintf(file, "[STATE]\n%i\n", state);
 883 
 884   fprintf(file, "[FLAGS]\n");
 885   /* should print the flags here */
 886   
 887   fprintf(file, "[PARTS]\n");
 888   /* should print the parts (filenames) here */
 889 
 890   fprintf(file, "[OBJECTS1]\n");
 891 
 892   fprintf(file, "[OBJECTS2]\n");
 893 
 894   fprintf(file, "[ACKFILE]\n");
 895   
 896   fprintf(file, "[NOTIFFILES]\n");
 897 
 898   fprintf(file, "[TIDS1]\n");
 899   
 900   fprintf(file, "[TIDS2]\n");
 901 
 902   fprintf(file, "[NICHDLHASH]\n");
 903 
 904   fprintf(file, "[CURRENTOBJECT]\n");
 905 
 906   fprintf(file, "[CURRENTPART]\n");
 907 
 908   
 909   fclose(file);
 910   rename(tmpfilename, filename);
 911 }
 912 
 913 
 914 
 915 
 916 /* main */
 917 void main(int argc, char **argv, char **envp){
     /* [<][>][^][v][top][bottom][index][help] */
 918   //init_and_set_options(argc, argv, envp);
 919 
 920   int count = 0;
 921   int i,j;
 922   int no_of_updateables = 0;
 923   char ** temp_vector;
 924   char * temp;
 925   char * temp_upd_file = NULL;
 926   char *input_file_name = NULL;
 927   GHashTable *AUTO_NIC_hdl_hash;
 928   credentials_struct credentials;
 929   FILE * upd_file;
 930   char c;
 931   char * mheader_replaced = NULL;
 932   char * mailtxt_replaced = NULL;
 933 
 934   /* temp variables to read from conf */
 935   char * source = NULL, * canupd = NULL;
 936   ca_dbSource_t *source_hdl;
 937   ca_updDbSource_t *upd_source_hdl;
 938 
 939   GHashTable *ntfy_hash, *forw_hash, *cross_hash;
 940   
 941 
 942   char *mail_command_line, * ack_file_name;
 943   char *config_file_name = NULL;
 944   
 945 
 946 
 947   /* to use EP module */
 948   EP_Mail_DescrPtr p; 
 949   EPTokenPtr pt;
 950   EPTokenPtr list_item;
 951   EPTokenKeysPtr ptk;
 952 
 953   char * temp_keyid;
 954 
 955   /* a variable to be used to know if the part is pgp_signed or not */
 956   int pgp_signed = 0;
 957 
 958   long debug = 0;
 959     
 960   /* optarg & optind are necessary to use getopt(3C) */ 
 961   extern char *optarg;
 962   extern int optind;
 963 
 964 
 965   /* create notification hashes */
 966   ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
 967   forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
 968   cross_hash = g_hash_table_new(g_str_hash, g_str_equal);
 969       
 970   credentials.password_list = NULL;
 971   credentials.from = NULL;
 972   int ch;
 973   char * to_address = NULL;
 974   char * subject = NULL;
 975   char * reply_to = NULL;
 976 
 977   AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);       
 978   
 979       
 980               
 981 
 982   while ((ch = getopt(argc, argv, "MtSTf:c:")) != -1){
 983           switch(ch) {
 984           case 'M':
 985                   reading_from_mail = 1;
 986                   break;
 987           case 'f':
 988                   input_file_name = strdup(optarg);
 989                   break;
 990           case 'c':
 991                   config_file_name = strdup(optarg);
 992                   break;
 993           case 't': 
 994                   tracing = 1;
 995                   break;
 996           /* Test mode? In test mode, creation of mntners and as-blocks is possible, without overriding */        
 997           case 'T':
 998                   test_mode = 1; 
 999                   break;
1000           /* Supress acks and notifications? If yes, the acks and notifs will go to DEFMAIL config var */        
1001           case 'S': 
1002                   supress_ack_notif = 1;
1003                   break;                
1004           case '?':
1005           default:
1006                   printf("Unknown option\n"); exit(1);
1007           }
1008   }
1009 
1010 
1011   /* config stuff */
1012   /* if -c flag is given, use the named file as config file, otherwise use
1013      default filename */ 
1014   if( config_file_name != NULL){
1015     /*ca_readConfig(config_file_name, confVars, VARS);*/
1016     ca_init(config_file_name);
1017   }else{
1018     /*ca_readConfig("dbupdate.conf", confVars, VARS);*/
1019     ca_init("dbupdate.conf");
1020   }
1021 
1022   error_init(argc, argv);
1023 
1024 
1025   tmpdir = ca_get_tmpdir;
1026   tmpdir = g_strstrip(tmpdir);
1027   lockdir = ca_get_lockdir;
1028   mailcmd = ca_get_mailcmd;
1029   mailcmd = g_strstrip(mailcmd);
1030   notitxt = ca_get_notitxt;
1031   mailtxt = ca_get_mailtxt; 
1032   defmail = ca_get_defmail; defmail=remove_EOLs(defmail);
1033   crosslog = ca_get_crosslog;
1034   fwtxt = ca_get_fwtxt;
1035   humailbox = ca_get_humailbox;
1036   humailbox = g_strstrip(humailbox);
1037   autobox = ca_get_autobox;
1038   overridecryptedpw = ca_get_overridecryptedpw;
1039   overridecryptedpw = g_strstrip(overridecryptedpw);
1040   acklog = ca_get_acklog;
1041   notiflog = ca_get_notiflog;
1042   notimailtxt = ca_get_notimailtxt;  
1043   forwlog = ca_get_forwlog;
1044   fwmailtxt = ca_get_fwmailtxt;
1045   country = ca_get_country;
1046   pgppath = ca_get_pgppath;
1047   gpgcmd = ca_get_gpgcmd;
1048   cn_subject_add = ca_get_cn_subject_add; cn_subject_add = remove_EOLs(cn_subject_add);
1049   cn_subject_del = ca_get_cn_subject_del; cn_subject_del = remove_EOLs(cn_subject_del);
1050   cn_explain_add = ca_get_cn_explain_add;
1051   cn_explain_del = ca_get_cn_explain_del;
1052   cn_overlap_add = ca_get_cn_overlap_add;
1053   cn_overlap_del = ca_get_cn_overlap_del;
1054   cno_subject_add = ca_get_cno_subject_add; cno_subject_add = remove_EOLs(cno_subject_add); 
1055   cno_subject_del = ca_get_cno_subject_del; cno_subject_del = remove_EOLs(cno_subject_del);
1056   cno_explain_add = ca_get_cno_explain_add;
1057   cno_explain_del = ca_get_cno_explain_del;
1058   cno_overlap_add = ca_get_cno_overlap_add;
1059   cno_overlap_del = ca_get_cno_overlap_del;
1060   mheader = ca_get_mheader;
1061   pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
1062   sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
1063   if(test_mode != 1){/* if it is not already set to 1 (from command line), read from config */
1064     
1065     test_mode = ca_get_testmode;
1066   }
1067   /* retrieve source variables */
1068   upd_source_hdl = ca_get_UpdSourceHandle(CA_UPDSOURCE);
1069 
1070   if(upd_source_hdl == NULL){
1071     printf("There must be one updateable source in the config file. Exiting.\n");
1072     ER_perror(FAC_UP, UP_CONFERR, "There must be one updateable source in"
1073                                   " the config file. Exiting.");
1074     exit(1);
1075   }else{
1076     if(tracing){
1077       printf("\nTRACING: The upd_source_hdl is: %s\n", upd_source_hdl->name);
1078     }
1079     sources[0] = strdup(upd_source_hdl->name);
1080     update_host = upd_source_hdl->whoisd_host;
1081     query_host = strdup(update_host);
1082     update_port = upd_source_hdl->updPort;
1083     query_port = upd_source_hdl->qryPort;
1084     DBhost = upd_source_hdl->updDb.host;
1085     DBport = upd_source_hdl->updDb.port;
1086     DBname = upd_source_hdl->updDb.dbName;
1087     DBuser = upd_source_hdl->updDb.user;
1088     DBpasswd = upd_source_hdl->updDb.password; 
1089   }
1090 
1091   
1092 
1093   /* construct country array from country string variable */
1094   
1095   temp_vector = g_strsplit(country, "\n", 0);
1096   for(i=0, j=0; temp_vector[i] != NULL; i++){
1097     temp_vector[i] == g_strstrip(temp_vector[i]);
1098     if(strlen(temp_vector[i]) > 0){
1099       countries[j] = strdup(temp_vector[i]);
1100       g_strup(countries[j]);
1101       j++;
1102     }
1103   }
1104   countries[j] = NULL; /* mark the end of array */
1105   
1106   if(tracing){
1107     /* print out the config variables for debugging */
1108     printf("TRACING: countries[%i] = NULL\n", j);
1109  
1110     printf("TMPDIR is: [%s]\n", tmpdir);
1111     printf("MAILCMD is: [%s]\n", mailcmd);
1112     printf("NOTITXT is: [%s]\n", notitxt);
1113     printf("CROSSLOG is: [%s]\n", crosslog);
1114     printf("FWTXT is: [%s]\n", fwtxt);
1115     printf("HUMAILBOX is: [%s]\n", humailbox);
1116     printf("AUTOBOX is: [%s]\n", autobox);
1117     printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
1118     printf("ACKLOG is: [%s]\n", acklog);
1119     printf("NOTIFLOG is: [%s]\n", notiflog);
1120     printf("FORWLOG is: [%s]\n", forwlog);
1121     printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
1122     printf("FWMAILTXT is: [%s]\n", fwmailtxt);
1123     printf("COUNTRY is: [%s]\n", country);
1124     printf("PGPPATH is: [%s]\n", pgppath);
1125     printf("UPDATE_HOST is: [%s]\n", update_host);
1126     printf("UPDATE_PORT is: [%i]\n", update_port);
1127     printf("QUERY_HOST is: [%s]\n",  query_host);
1128     printf("QUERY_PORT is: [%i]\n",  query_port);   
1129     printf("LOCKDIR is: [%s]\n", lockdir); 
1130     printf("TESTMODE is: [%i]\n", test_mode);
1131     printf("CNO_SUBJECT_ADD is: [%s]\n", cno_subject_add);
1132     printf("CNO_SUBJECT_DEL is: [%s]\n", cno_subject_del);
1133   }
1134   /* end of config stuff */
1135 
1136 
1137   /* set hostname global variable */
1138   gethostname(hostname, MAXHOSTNAMELEN);
1139 
1140   /* set pid global variable */
1141   pid = getpid(); 
1142 
1143   /* create the lock file and lock it */
1144   lockfile = create_lock_file();
1145 
1146     
1147   /* initialize the parser */
1148   schema.initialize();
1149 
1150 
1151   /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
1152       also creates it) */
1153   ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
1154 
1155   /* initialize credentials.pgp_key_list */
1156   credentials.pgp_key_list = NULL;
1157 
1158 
1159   
1160  
1161   if(reading_from_mail){
1162     if(input_file_name != NULL){
1163       temp_upd_file = generate_upd_file();
1164       if(tracing){
1165         printf("TRACING: temp_upd_file is [%s]\n", temp_upd_file);
1166       }
1167       MM_store(input_file_name, temp_upd_file, 0);
1168       p = EP_ParseMail(input_file_name, "/tmp" /*tmpdir*/, pgp_public_key_ring, gpgcmd);
1169       
1170     }else{/* input_file_name == NULL */
1171       temp_upd_file = generate_upd_file();
1172       printf("DEBUG: temp_upd_file is [%s]\n", temp_upd_file);
1173       MM_store("-", temp_upd_file, 0);
1174       p = EP_ParseMail(temp_upd_file, "/tmp" /*tmpdir*/, pgp_public_key_ring, gpgcmd);
1175 
1176     }
1177 
1178     /* write off the checkpoint file */
1179     write_checkpoint(1);
1180 
1181     /* the new stuff using the EP module's interface */
1182     if(tracing){
1183       printf("\nTRACING: From field is: [%s]\n", p->from->field);
1184     }
1185 
1186     temp = (char *)malloc(strlen(p->from->field) + strlen("From: ") + 1);
1187     sprintf(temp, "From: %s", p->from->field);
1188     /* cut off the '\n's and '\r's at the end of temp */
1189     while(temp[strlen(temp) - 1] == '\n' || 
1190           temp[strlen(temp) - 1] == '\r'){
1191        temp[strlen(temp) - 1] = '\0';
1192     }
1193     credentials.from = temp;
1194     credentials.from_email = strdup(p->from->field);
1195 
1196     update_mail_sender = strdup(p->from->field); 
1197                
1198     if(p->subject != NULL && p->subject->field != NULL){
1199       subject = strdup(p->subject->field);
1200     }else{
1201       subject = strdup("");
1202     }
1203     
1204     while(subject[strlen(subject) - 1] == '\n' || 
1205           subject[strlen(subject) - 1] == '\r'){
1206        subject[strlen(subject) - 1] = '\0';
1207     }
1208     
1209     update_mail_subject = strdup(subject);
1210 
1211     if(p->reply_to != NULL && p->reply_to->field != NULL){
1212       reply_to = strdup(p->reply_to->field);
1213     }else{
1214       reply_to = strdup("");
1215     }
1216 
1217     
1218                         
1219     while( strlen(reply_to) > 0 &&
1220           (reply_to[strlen(reply_to) - 1] == '\n' || 
1221            reply_to[strlen(reply_to) - 1] == '\r')){
1222        reply_to[strlen(reply_to) - 1] = '\0';
1223     }
1224 
1225     
1226 
1227     to_address = find_email_address(credentials.from);
1228 
1229     /* if Reply_To was available in the incoming header, then use it */
1230     if(strlen(reply_to) > 0){
1231       to_address = (char *)realloc(to_address, strlen(reply_to) + 1);
1232       to_address = strcpy(to_address, reply_to);
1233     }
1234 
1235     if(p->message_id != NULL && p->message_id->field != NULL){
1236       update_mail_ID = strdup(p->message_id->field);
1237     }else{
1238       update_mail_ID = strdup("");
1239     }
1240 
1241     while(strlen(update_mail_ID) > 0  &&
1242           (update_mail_ID[strlen(update_mail_ID) - 1] == '\n' || 
1243            update_mail_ID[strlen(update_mail_ID) - 1] == '\r')){
1244        update_mail_ID[strlen(update_mail_ID) - 1] = '\0';
1245     }
1246     
1247 
1248     if(p->date != NULL && p->date->field != NULL){
1249       update_mail_date = strdup(p->date->field);
1250     }else{
1251       update_mail_date = strdup("");
1252     }
1253 
1254     while(strlen(update_mail_date) > 0  &&
1255           (update_mail_date[strlen(update_mail_date) - 1] == '\n' || 
1256            update_mail_date[strlen(update_mail_date) - 1] == '\r')){
1257        update_mail_date[strlen(update_mail_date) - 1] = '\0';
1258     }
1259 
1260     
1261     if(tracing){
1262       printf("\nEP_ShowTree outputs:\n");
1263       EP_ShowTree(p->tree);
1264     }
1265     
1266     pt = EP_GetTokens(p->tree, NULL, NULL);
1267 
1268     if(tracing){
1269       /* Print the list out (debugging) */
1270       printf("\nEP_PrintTokens outputs:\n");
1271       EP_PrintTokens(pt);
1272     }
1273 
1274     /* replace the global variables in mheader */
1275     mheader_replaced = replace_globals(mheader);
1276     /* replace the global variables in mailtxt */
1277     mailtxt_replaced = replace_globals(mailtxt);
1278     /* Print out the header of the ackonwledgement */
1279     AK_add_to_ack(ack_file_name, "To: %s\n%s\n\nAcknowledgement message from database software, beta version\n\n%s\n", to_address, mheader_replaced, mailtxt_replaced);
1280 
1281     /* ... and now process the items in the list */
1282     list_item = pt;
1283     while (list_item != NULL) {
1284       if(tracing){
1285         printf("\n\nWill process: %s, MIMEtype: %d\n", list_item->file, list_item->MIMEContentType);
1286       }
1287       /* initialize pgp_key_list (XXX This should be a proper freeing of the list) */
1288       credentials.pgp_key_list = NULL;
1289       ptk = list_item->keys;
1290       if(ptk != NULL){
1291         AK_add_to_ack(ack_file_name, "==== BEGIN PGP SIGNED PART (keyID(s):");
1292         pgp_signed = 1; 
1293         while (ptk != NULL) {
1294           printf("     key: %.8X, isValid: %i\n", 
1295                  ptk->keyID, ptk->isValidPGPSignature/*vS_strRC[ptk->isValidPGPSignature]*/);
1296           temp_keyid = (char *)malloc(10);
1297           sprintf(temp_keyid, "%.8X", ptk->keyID);
1298           printf("DEBUG: This key will be added to the list: [%s]\n", temp_keyid);
1299           AK_add_to_ack(ack_file_name, " %s", temp_keyid);
1300           credentials.pgp_key_list = g_slist_append (credentials.pgp_key_list, temp_keyid);
1301           ptk = ptk->next;
1302           if(ptk != NULL){
1303             AK_add_to_ack(ack_file_name, ",");
1304           }else{
1305             AK_add_to_ack(ack_file_name, ") ====\n");
1306           }
1307         }
1308       }
1309       process_file(list_item->file, credentials, 
1310                    AUTO_NIC_hdl_hash, ack_file_name, 
1311                    ntfy_hash, forw_hash, cross_hash);
1312       if(pgp_signed){
1313         AK_add_to_ack(ack_file_name, "==== END PGP SIGNED PART ====\n\n");
1314         pgp_signed = 0;
1315       }
1316       list_item = list_item->next;
1317     }
1318 
1319 
1320     EP_CleanTokens(pt);
1321 
1322     EP_MailDescrCleanUp(p);
1323 
1324 
1325       
1326   }else{/* not reading from the mail message */
1327     if(input_file_name != NULL){
1328 
1329       write_checkpoint(1);
1330       process_file(input_file_name, credentials, 
1331                   AUTO_NIC_hdl_hash, ack_file_name, 
1332                   ntfy_hash, forw_hash, cross_hash);
1333     }else{/* the filename is not given, so we have to write 
1334              stdin to a temp file, and give it to process_file */
1335        temp_upd_file = generate_upd_file();
1336        if(tracing){
1337          printf("TRACING: main: temp_upd_file=%s\n", temp_upd_file);
1338        }
1339        if(( upd_file = fopen(temp_upd_file, "a")) == NULL){
1340          ER_perror(FAC_UP, UP_CANTOPENW, "Can't open ack file, %s", temp_upd_file);
1341        }
1342 
1343        while((c = getchar()) != EOF){
1344          fprintf(upd_file, "%c",c);
1345        }
1346        fclose(upd_file);
1347 
1348        write_checkpoint(1);
1349        process_file(temp_upd_file, credentials, 
1350                   AUTO_NIC_hdl_hash, ack_file_name, 
1351                   ntfy_hash, forw_hash, cross_hash);
1352        unlink(temp_upd_file);
1353         
1354     }
1355       
1356   }  
1357 
1358 
1359   if(reading_from_mail && to_address != NULL){
1360     AK_send_ack(ack_file_name, to_address, mailcmd);
1361   }
1362   AK_log_ack(ack_file_name, acklog);
1363   AK_delete_ack(ack_file_name);
1364 
1365   NT_send_ntfy_list(ntfy_hash, mailcmd);
1366   NT_log_ntfy_list(ntfy_hash, notiflog); 
1367   NT_delete_ntfy_list(ntfy_hash);
1368 
1369   NT_send_ntfy_list(forw_hash, mailcmd);
1370   NT_log_ntfy_list(forw_hash, forwlog); 
1371   NT_delete_ntfy_list(forw_hash);
1372 
1373 
1374   NT_send_ntfy_list(cross_hash, mailcmd);
1375   NT_log_ntfy_list(cross_hash, crosslog); 
1376   NT_delete_ntfy_list(cross_hash);
1377       
1378   /* remove the lock file */
1379   remove_lock_file(lockfile);
1380   
1381   if(tracing) {
1382     printf("TRACING: END\n");
1383   }
1384 
1385 
1386 }

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