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

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