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. scan_for_PGP
  6. process_file
  7. generate_upd_file
  8. main

   1 /***************************************
   2   $Revision: 1.30 $
   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 "erroutines.h"
  40 #include "ca_configFns.h"
  41 #include "ca_dictSyms.h"
  42 #include "ca_macros.h"
  43 #include "ca_srcAttribs.h"
  44 #include "notification.h"
  45 #include "gpg.h"
  46 
  47 int tracing = 0;
  48 int test_mode = 0;
  49 int reading_from_mail = 0;
  50 
  51 /* required configuration variables */
  52 char *tmpdir = NULL;
  53 char *mailcmd = NULL;
  54 char *notitxt = NULL;
  55 char *notimailtxt = NULL;
  56 char *fwtxt   = NULL;
  57 char *fwmailtxt = NULL;
  58 char *mailtxt = NULL;
  59 char *notiflog = NULL;
  60 char *crosslog = NULL;
  61 char *acklog = NULL;
  62 char *forwlog = NULL;
  63 char *humailbox = NULL;
  64 char *overridecryptedpw = NULL;
  65 char *country = NULL;
  66 char *countries[400];
  67 char *sources[100];
  68 char *pgppath = NULL;
  69 char *pgp_public_key_ring = NULL;
  70 char *update_host = NULL;
  71 int  update_port;
  72 char *query_host = NULL;
  73 int  query_port;   
  74 
  75 /* end of config variables */
  76 
  77 void error_init(int argc, char ** argv) {
     /* [<][>][^][v][top][bottom][index][help] */
  78   er_path_t erlogstr;
  79 
  80   ER_init(argc, argv);
  81 
  82   erlogstr.fdes = stderr;
  83   erlogstr.asp  = 0;
  84   erlogstr.sev  = ER_SEV_W;
  85   erlogstr.mode = ER_M_SEVCHAR | ER_M_TEXTLONG;
  86 
  87   ER_setpath(& erlogstr);  
  88 
  89 } /* error_init() */
  90 
  91 
  92 
  93 /* Deletes the key defined in the incoming object (a key-cert object)
  94    from the public keyring. Returns NULL if there was no error,
  95    returns an error message if there is an error */
  96 char * delete_key(char * obj){
     /* [<][>][^][v][top][bottom][index][help] */
  97 
  98   struct ImportKeyObject iKO;
  99   char * obj_keyID;
 100   char * key_cert_attr;
 101   GSList * templist, * certiflist, * next;
 102   u32 keyID;
 103   char * tempfile;
 104   char ** lines;
 105   int i;
 106   FILE * key_file;
 107   char * temp, * temp2;
 108   char * error_string;
 109 
 110   templist = get_attr_list(obj, "key-cert");
 111   key_cert_attr = strdup((char *)templist->data);
 112   g_slist_free(templist);
 113 
 114   tempfile = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
 115   sprintf(tempfile, "%s/tmp-key.%i", tmpdir, getpid());
 116   printf("DEBUG: tempfile=%s\n", tempfile);
 117 
 118   /* now we must write certif attribute(s) of this key-certif into the tempfile */
 119   /* get the certif first */
 120   certiflist = get_attr_list(obj, "certif");
 121   if(( key_file = fopen(tempfile, "w")) == NULL){
 122      fprintf(stderr, "Can't open temporary file, %s", tempfile);
 123      exit(1);
 124   }
 125   for( next = certiflist; next != NULL ; next = g_slist_next(next) ){
 126     lines = g_strsplit((char *)next->data, "\n", 0);
 127     //printf("DEBUG: attr: %s\n", (char *)next->data);
 128     if(lines[0] == NULL){/* if this was an empty attribute, just print an empty line */
 129       fprintf(key_file, "\n"); 
 130     }
 131     for(i = 0; lines[i] != NULL; i++){
 132       //printf("DEBUG: i=%i\n", i);
 133       temp = strdup(lines[i]);
 134       if(i != 0 && temp[0] == '+'){/* if it begins with a plus */
 135         temp2 = strdup(temp + 1);
 136         g_strstrip(temp2);
 137         fprintf(key_file, "%s\n", temp2);
 138         free(temp);free(temp2);
 139       }else{
 140         g_strstrip(temp);
 141         fprintf(key_file, "%s\n", temp);
 142         free(temp); 
 143       }
 144     }
 145     g_strfreev(lines);
 146     //fprintf(key_file, "%s\n", (char *)next->data);
 147   }
 148   fclose(key_file);
 149   g_slist_free(certiflist);
 150 
 151   strcpy(iKO.iFilename, tempfile);
 152 
 153   printf("DEBUG: delete_key: key_cert_attr: [%s]\n", key_cert_attr);
 154   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
 155   printf("DEBUG: delete_key: obj_keyID: [%s]\n", obj_keyID);
 156   keyID = strtoul(obj_keyID, NULL, 16);
 157   printf("DEBUG: delete_key: keyID is: %u, %X\n", keyID, keyID);
 158   
 159   
 160   
 161   strcpy(iKO.keyRing, pgp_public_key_ring);
 162   //iKO.keyID = keyID; 
 163   PA_RemoveKey(&iKO);
 164   printf("DEBUG: importKeyObj status:\n");
 165   printf("DEBUG: isValid: %d\n", iKO.rc);
 166   
 167 
 168 
 169   unlink(tempfile);
 170   if(iKO.rc == iKO_OK){/* if PA_RemoveKey returned OK */
 171     return NULL;
 172   }else{/* if PA_RemoveKey returned not OK */
 173       switch(iKO.rc){
 174         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break; 
 175         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
 176         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
 177         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
 178         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
 179         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
 180         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
 181         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
 182         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
 183         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
 184         default:            error_string = strdup("general PGP error");
 185       }
 186       return error_string; 
 187   }
 188 
 189   return NULL;
 190 }
 191 
 192 
 193 /* Takes a key-certif object, extracts its 'certif' attribute and adds
 194    the key into public keyring
 195    If there is no problem, it returns NULL
 196    If there is a problem, then it returns a string which contains an error
 197    message */
 198 char * import_key(char *obj){
     /* [<][>][^][v][top][bottom][index][help] */
 199 
 200   char * tempfile;
 201   struct ImportKeyObject iKO;
 202   GSList * certiflist, * next, * templist;
 203   FILE * key_file;
 204   char keyID[9];
 205   char * obj_keyID, * key_cert_attr;
 206   char * error_string = NULL;
 207   char ** lines;
 208   int i;
 209   char * temp, * temp2;
 210    
 211   tempfile = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
 212   sprintf(tempfile, "%s/tmp-key.%i", tmpdir, getpid());
 213   printf("DEBUG: tempfile=%s\n", tempfile);
 214 
 215   /* now we must write certif attribute(s) of this key-certif into the tempfile */
 216   /* get the certif first */
 217   certiflist = get_attr_list(obj, "certif");
 218   if(( key_file = fopen(tempfile, "w")) == NULL){
 219      fprintf(stderr, "Can't open temporary file, %s", tempfile);
 220      exit(1);
 221   }
 222   for( next = certiflist; next != NULL ; next = g_slist_next(next) ){
 223     lines = g_strsplit((char *)next->data, "\n", 0);
 224     //printf("DEBUG: attr: %s\n", (char *)next->data);
 225     if(lines[0] == NULL){/* if this was an empty attribute, just print an empty line */
 226       fprintf(key_file, "\n"); 
 227     }
 228     for(i = 0; lines[i] != NULL; i++){
 229       //printf("DEBUG: i=%i\n", i);
 230       temp = strdup(lines[i]);
 231       if(i != 0 && temp[0] == '+'){/* if it begins with a plus */
 232         temp2 = strdup(temp + 1);
 233         g_strstrip(temp2);
 234         fprintf(key_file, "%s\n", temp2);
 235         free(temp);free(temp2);
 236       }else{
 237         g_strstrip(temp);
 238         fprintf(key_file, "%s\n", temp);
 239         free(temp); 
 240       }
 241     }
 242     g_strfreev(lines);
 243     //fprintf(key_file, "%s\n", (char *)next->data);
 244   }
 245   fclose(key_file);
 246   g_slist_free(certiflist);
 247 
 248   strcpy(iKO.iFilename, tempfile);
 249   strcpy(iKO.keyRing, pgp_public_key_ring);
 250   PA_ImportKey(&iKO);
 251 
 252   printf("importKeyObj status:\n");
 253     
 254   printf("isValid: %d\n", iKO.rc);
 255   printf("keyID: %08lX\n", iKO.keyID);
 256   snprintf(keyID, 9, "%08lX", iKO.keyID);
 257   printf("keyID: [%s]\n", keyID);
 258   
 259   unlink(tempfile);
 260   free(tempfile);
 261 
 262   
 263   templist = get_attr_list(obj, "key-cert");
 264   key_cert_attr = strdup((char *)templist->data);
 265   g_slist_free(templist);
 266 
 267   printf("key_cert_attr: [%s]\n", key_cert_attr);
 268   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
 269   printf("obj_keyID: [%s]\n", obj_keyID);
 270   if(iKO.rc == iKO_OK && (strcmp(obj_keyID, keyID) == 0)){/* if PA_ImportKey returned OK 
 271                                                             and the real keyID is equal to the
 272                                                             keyID in the 'key-cert' attribute */
 273     return NULL;
 274   }else{/* if PA_ImportKey returned not OK or obj_keyID, keyID didn't match */
 275     if(iKO.rc != iKO_OK){
 276       switch(iKO.rc){
 277         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break; 
 278         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
 279         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
 280         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
 281         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
 282         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
 283         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
 284         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
 285         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
 286         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
 287         default:            error_string = strdup("general PGP error");
 288       }
 289       return error_string; 
 290     }else{
 291       error_string = (char *)malloc(1024);/* this should be enough */
 292       sprintf(error_string, "Keyid for this certificate (%s) is not the same as the PGPKEY field (%s)", 
 293                  keyID, obj_keyID);
 294       return error_string;
 295     }
 296   }
 297       
 298 }
 299 
 300 
 301 
 302 /* Checks the object's syntax, retrives the old version of it from the db, 
 303    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
 304    integrity is checked, and the object is really committed to the db.
 305   
 306      Arguments:
 307         char * arg: The object,
 308         credentials_struct credentials: The struct containing the credentials, such as 
 309           'From:' field of the e-mail update,
 310         GHashTable * NIC_hdl_hash: A hash containing 
 311         char * ack_file_name:  The file name, to be used to store ACK message 
 312 */
 313 
 314 
 315 
 316 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name,
     /* [<][>][^][v][top][bottom][index][help] */
 317                    GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
 318     bool code = true;
 319     Object *o;
 320     char * old_version = NULL;
 321     o = new Object;
 322     int result = 0;
 323     int result_from_RIPupd = 0;
 324     char * result_from_import_key = NULL;
 325     char * result_from_delete_key = NULL;
 326     char * auto_nic = NULL;
 327     char * changed_obj = NULL;
 328     char * obj_with_AUTO_NIC_hdl;
 329     char * assigned_NIC;
 330     char * type;
 331 
 332     char * value = NULL;/* these two are for */
 333     Attr * attr;        /* ack messages only */ 
 334     
 335     if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
 336        /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
 337        if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
 338          return UP_ANE; /* AUTO NIC hdl error */
 339        };
 340     }
 341    
 342     code = o->scan(arg,strlen(arg));
 343     if(code){
 344       type = get_type(o);
 345       /* is the object to be deleted? */
 346       if(o->isDeleted){
 347         //printf("DEBUG: This object is to be deleted\n"); 
 348         old_version = get_old_version(arg);
 349         if(old_version == NULL){ /* the object doesn't exist in the db! */
 350           AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nEntry not found\n\n%s\n", 
 351                         o->type->getName(), get_search_key(o, o->type->getName(), arg), arg);
 352           return UP_NSO; /* no such object */
 353         }else {/* the object is in the db */
 354           if(identical(old_version, arg)){/* if the old & new versions are identical */
 355             result = check_auth(NULL, old_version, o->type->getName(), credentials);
 356             if(result == UP_AUTH_OK){ 
 357               if(tracing) {
 358                 printf("TRACING: Will send the obj to be deleted\n");
 359               }
 360               if(strcmp(type, "key-cert") == 0){
 361                 result_from_delete_key = delete_key(arg);
 362               }else{
 363                 result_from_delete_key = NULL;
 364               }
 365               /* if there was no problem with key deletion from the key-ring */
 366               if(result_from_delete_key == NULL){
 367                 result_from_RIPupd = send_object_db(arg, NULL, "DEL");
 368                 if(result_from_RIPupd == 0){
 369                   AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n", 
 370                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 371                   NT_write_all_ntfs(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 372                 }else{
 373                   AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nReferential integrity failure\n",
 374                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 375                 }
 376                 result_from_RIPupd = 0;
 377               }else{
 378                  AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
 379                                 o->type->getName(), get_search_key(o, o->type->getName(), arg), result_from_delete_key);
 380               }
 381             }else{ /* auth failed */
 382               if(tracing) {
 383                 printf("TRACING: Auth failed\n");
 384               }
 385 
 386               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuth failed\n",
 387                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
 388               NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 389               return UP_AUF; /* Auth failed */
 390             } 
 391           }else{/* the new & old versions do not match */
 392             AK_add_to_ack(ack_file_name, "\nDelete FAILED: new & old versions do not match\n");
 393             return UP_NOM; /* new & old versions do not match */
 394           }
 395         }
 396       }else {/* the object is _not_ to be deleted */
 397         if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
 398           /* then its nic-hdl attribute must be modified so that RIPupdate
 399              would understand that it must assign a NIC handle to it */
 400           /* but first check the auth */
 401           result = check_auth(arg, NULL, o->type->getName(), credentials);
 402           if(result == UP_AUTH_OK){
 403             if(tracing) {                                
 404                 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
 405             }
 406             auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
 407             obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
 408             if(tracing) {  
 409               printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
 410               printf("TRACING: Will send the obj to be added\n");
 411             }
 412             assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
 413             result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
 414             if(result_from_RIPupd == 0){
 415               AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", 
 416                             o->type->getName(), assigned_NIC);
 417               NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 418             }else{
 419               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
 420                             o->type->getName(), arg);
 421             }
 422             result_from_RIPupd = 0;
 423             if(tracing && assigned_NIC != NULL) {  
 424               printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
 425             }
 426             if(assigned_NIC != NULL){
 427               printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
 428               g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
 429               printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
 430             }
 431             
 432           }else{
 433             /* auth failed ! */
 434             if(tracing) {
 435               printf("TRACING: Auth failed\n");
 436             }
 437 
 438             ER_perror(0, result, "");
 439             AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
 440                           o->type->getName(), get_search_key(o, o->type->getName(), arg));
 441             NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 442             return UP_AUF; /* Auth failed */
 443           }
 444         }
 445         else{ 
 446           old_version = get_old_version(arg);
 447           if(old_version != NULL){/* so, this is an update operation */
 448             result = check_auth(arg, old_version, o->type->getName(), credentials);    
 449             if(result == UP_AUTH_OK){
 450               if(tracing) {                                
 451                 printf("TRACING: Will send the obj to be updated\n");
 452               }
 453               result_from_RIPupd = send_object_db(arg, NULL, "UPD");
 454               if(result_from_RIPupd == 0){
 455                 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
 456                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
 457                 NT_write_all_ntfs(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 458               }else{
 459                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
 460                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
 461               }
 462               result_from_RIPupd = 0;
 463             }else{
 464               /* auth failed ! */
 465               if(tracing) {
 466                 printf("TRACING: Auth failed\n");
 467               }
 468 
 469               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
 470                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
 471               NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 472               return UP_AUF; /* Auth failed */
 473             }
 474           }else { /* old_version  == NULL, so, creation */
 475             result = check_auth(arg, NULL, o->type->getName(), credentials);
 476             if(result == UP_AUTH_OK){ 
 477               if(tracing) {                                
 478                 printf("TRACING: Will send the obj to be added\n");
 479               }
 480               /* if the object is a key-cert object, then we must import the PGP key */
 481               if(strcmp(type, "key-cert") == 0){
 482                 result_from_import_key = import_key(arg);
 483               }else{
 484                 result_from_import_key = NULL;
 485               }
 486               if(result_from_import_key == NULL){/* no PGP problem */
 487                 result_from_RIPupd = send_object_db(arg, NULL, "ADD");
 488                 if(result_from_RIPupd == 0){/* if there was no problem */
 489                   AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
 490                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 491                   NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 492 
 493                 }else{
 494                   AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
 495                                 o->type->getName(), get_search_key(o, o->type->getName(), arg));
 496                 }
 497                 result_from_RIPupd = 0;
 498               }else{/* there was a problem with PGP key import */
 499                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
 500                                 o->type->getName(), get_search_key(o, o->type->getName(), arg),
 501                                 result_from_import_key);
 502               }
 503             }else{
 504               /* auth failed ! */
 505               if(tracing) {
 506                 printf("TRACING: Auth failed\n");
 507               }
 508 
 509               ER_perror(0, result, "");
 510               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
 511                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
 512               NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
 513               return UP_AUF; /* Auth failed */
 514             }
 515           } 
 516         }
 517       }
 518     }else{/* even if obj doesn't parse properly, it may be a legacy object
 519             which the user wants to delete... */
 520        if(tracing){   
 521          printf("TRACING: Object didn't parse\n");   
 522        }
 523        AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
 524        //////////////////////////////////
 525        if(o->attrs.head() != NULL){
 526          for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 527            if(attr->len > 0){
 528              value = (char*)malloc(attr->len);
 529              strncpy(value, (char *)(arg+attr->offset) ,
 530                attr->len - 1);
 531              value[attr->len - 1] = '\0';
 532              AK_add_to_ack(ack_file_name, "%s\n", value);
 533              if(!attr->errors.empty()){
 534                AK_add_to_ack_string(ack_file_name, attr->errors);
 535              }
 536              free(value);
 537            }else{
 538              if(!attr->errors.empty()){
 539                AK_add_to_ack_string(ack_file_name, attr->errors);
 540              }
 541            }
 542          }
 543        }
 544        if(o->has_error){
 545          AK_add_to_ack_string(ack_file_name, o->errors);
 546        }
 547        AK_add_to_ack(ack_file_name, "\n");
 548        //////////////////////////////////
 549        return UP_NIY; /* Not implemented yet */
 550     }
 551 }
 552 
 553 
 554 /* A temporary function to test if there is a PGP signed portion in the file */
 555 int scan_for_PGP(const char * filename){
     /* [<][>][^][v][top][bottom][index][help] */
 556 
 557   FILE *file;
 558   char *line;
 559 
 560   line = (char *)malloc(1024);
 561   if((file = fopen(filename, "r")) == NULL){
 562     printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
 563     exit(1);  
 564   }
 565   while(fgets(line, 1024, file) != NULL){
 566     if(strstr(line, "-----BEGIN PGP") == line){/* yes, we have a PGP signed portion, so return true */
 567       fclose(file);
 568       free(line);
 569       return 1;
 570     }
 571   } 
 572   fclose(file);
 573   free(line);
 574   return 0; /* no, we din't have any PGP signed portions */
 575 }
 576 
 577 
 578 
 579 
 580 
 581 /* processes the objects in the given file */
 582 void process_file(char * filename, credentials_struct credentials, 
     /* [<][>][^][v][top][bottom][index][help] */
 583                   GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name, 
 584                   GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
 585 
 586 FILE * input_file;
 587 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;   
 588 GSList *next = NULL;
 589 int object_count = 0;
 590 char *object = NULL;
 591 char line[1024];
 592 int result = 0;
 593 struct VerifySignObject vSO, *pvSO;
 594 
 595 
 596   /* allocate space for pgp_struct, it will be set to pgp key ID when we encounter a pgp signed message */
 597   credentials.pgp_struct == (char *)malloc(10);
 598 
 599   //line = (char *)malloc(1024);
 600 
 601   /* if we have PGP signed portions in the message */ 
 602   if(scan_for_PGP(filename)){ 
 603     strcpy(vSO.outputPath, "/tmp");
 604     strcpy(vSO.iDocSigFilename, filename);
 605     strcpy(vSO.iSigFilename, "");
 606     strcpy(vSO.keyRing, pgp_public_key_ring);
 607 
 608     PA_VerifySignature(&vSO);
 609 
 610     pvSO = vSO.next;
 611     while (pvSO != NULL) {
 612       printf("isValid: %d\n", pvSO->isValid);
 613       printf("key ID: %x\n",  pvSO->keyID);
 614       printf("oStream is %s\n", pvSO->oStream);
 615     
 616 
 617       if(pvSO->isValid == vSO_IS_VALID){/* if this PGP signed portion is valid, read it */
 618         if((input_file = fopen( pvSO->oStream/*filename*/, "r")) == NULL){
 619            printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
 620            exit(1);  
 621         }
 622         AK_add_to_ack(ack_file_name, "\n*** Beginning of PGP signed part from key ID %X\n", pvSO->keyID);
 623         sprintf(credentials.pgp_struct, "%.8X", pvSO->keyID);
 624         printf("DEBUG:  credentials.pgp_struct=[%s]\n", credentials.pgp_struct);  
 625         while(fgets(line, 1024, input_file) != NULL){
 626           /* first, if it is a pasword, save it, but do not regard it as an attrib */ 
 627           if(strstr(line, "password:") == line){
 628             if(tracing){
 629               printf("DEBUG: This is a password\n");
 630             }
 631             credentials.password_list = g_slist_append(credentials.password_list, 
 632                                           g_strstrip(strdup(line + strlen("password:"))));
 633             continue;
 634           }
 635           /* if the length of the line read is 2, then this is an empty line ("\n\r")*/
 636           if(strlen(line) == 2){
 637             if(object != NULL){
 638               list_of_objects = g_slist_append(list_of_objects, object);
 639               object = NULL;
 640             }
 641           }else{
 642             /* if the line contains only the EOL sequence "\n\r" */
 643             if(object == NULL && strlen(line) != 2){
 644               object = (char *)malloc(strlen(line));
 645               object = strdup(line);
 646             }
 647             else{
 648               object = (char *)realloc(object, strlen(object) + strlen(line) + 1);
 649               object = strcat(object, line);
 650             }
 651           }
 652         
 653         }
 654         fclose(input_file);
 655 
 656         /* now, if at the very and of the input file there wasn't an 
 657            empty line, we have to add the remaining object in the 'object'
 658            variable */
 659         if(object != NULL){
 660            //cout << "The object was" << endl << object << endl;
 661            list_of_objects = g_slist_append(list_of_objects, object);
 662            object = NULL;
 663         }
 664   
 665   
 666   
 667         if(tracing) {
 668            printf("TRACING: Will process the objects in the list\n");
 669         }
 670         next = list_of_objects;
 671         object_count = 0;
 672         for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
 673           object_count++;
 674   
 675           if(tracing) {
 676             cout << "TRACING: Got an object from the list" << endl;
 677             cout << (char *)next->data << endl;
 678           }
 679        
 680           if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
 681             if(tracing) {
 682               printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
 683             }
 684             list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
 685           }else{
 686             result = 0;
 687             result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
 688                                      ntfy_hash, forw_hash, cross_hash);
 689           }
 690         }
 691 
 692         if(tracing) {
 693           printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
 694         }
 695     
 696         if(tracing) {
 697           printf("TRACING: will start to process the second list\n");
 698         }
 699      
 700         for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
 701           if(tracing) {
 702             printf("TRACING: Will process object: %s\n", (char *)next->data);
 703           }
 704           result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
 705                                    ntfy_hash, forw_hash, cross_hash);
 706         }
 707         /* empty the object lists (this must be done by properly freeing the memory taken by them!) */
 708         list_of_objects = NULL;
 709         list_of_objects2 = NULL;
 710         AK_add_to_ack(ack_file_name, "\n*** End of PGP signed part from key ID %X\n", pvSO->keyID);  
 711 
 712         }else{
 713           AK_add_to_ack(ack_file_name, "\n***  Ignoring PGP signed part from key ID %X", pvSO->keyID); 
 714           AK_add_to_ack(ack_file_name, "\n***  Bad signature or key is not in public key ring or other error\n\n"); 
 715         }
 716 
 717       pvSO = pvSO->next;
 718       /* empty out credentials.pgp_struct for the next loop  */
 719       strcpy(credentials.pgp_struct,"");
 720       }
 721 
 722     }
 723     else{/* the file doesn't contain PGP signed portions */ 
 724      if((input_file = fopen(filename, "r")) == NULL){
 725          printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
 726          exit(1);  
 727      }
 728 
 729   
 730     while(fgets(line, 1024, input_file) != NULL){
 731       /* first, if it is a pasword, save it, but do not regard it as an attrib */ 
 732       if(strstr(line, "password:") == line){
 733         if(tracing){
 734           printf("DEBUG: This is a password\n");
 735         }
 736         credentials.password_list = g_slist_append(credentials.password_list, 
 737                                       g_strstrip(strdup(line + strlen("password:"))));
 738         continue;
 739       }
 740       /* if the length of the line read is 2, then this is an empty line ("\n\r")*/
 741       if(strlen(line) == 2){
 742         if(object != NULL){
 743            list_of_objects = g_slist_append(list_of_objects, object);
 744            object = NULL;
 745         }
 746       }else{
 747         /* if the line contains only the EOL sequence "\n\r" */
 748         if(object == NULL && strlen(line) != 2){
 749           object = (char *)malloc(strlen(line));
 750           object = strdup(line);
 751         }
 752         else{
 753           object = (char *)realloc(object, strlen(object) + strlen(line) + 1);
 754           object = strcat(object, line);
 755         }
 756       }
 757       
 758     }
 759     fclose(input_file);
 760 
 761     /* now, if at the very and of the input file there wasn't an 
 762        empty line, we have to add the remaining object in the 'object'
 763        variable */
 764     if(object != NULL){
 765        //cout << "The object was" << endl << object << endl;
 766        list_of_objects = g_slist_append(list_of_objects, object);
 767        object = NULL;
 768     }
 769 
 770 
 771 
 772     if(tracing) {
 773        printf("TRACING: Will process the objects in the list\n");
 774     }
 775     next = list_of_objects;
 776     object_count = 0;
 777     for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
 778       object_count++;
 779 
 780       if(tracing) {
 781         cout << "TRACING: Got an object from the list" << endl;
 782         cout << (char *)next->data << endl;
 783       }
 784       
 785       if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
 786         if(tracing) {
 787           printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
 788         }
 789         list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
 790       }else{
 791         result = 0;
 792         result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
 793                                  ntfy_hash, forw_hash, cross_hash);
 794       }
 795     }
 796 
 797     if(tracing) {
 798       printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
 799     }
 800   
 801     if(tracing) {
 802       printf("TRACING: will start to process the second list\n");
 803     }
 804   
 805     for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
 806       if(tracing) {
 807         printf("TRACING: Will process object: %s\n", (char *)next->data);
 808       }
 809       result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name, 
 810                                ntfy_hash, forw_hash, cross_hash);
 811     }
 812   
 813   }
 814   
 815 }/* process_file */
 816 
 817 
 818 
 819 
 820 
 821 
 822 /*  Generates a unique file name and returns the full path of the filename 
 823     for storing notification message.  */
 824       
 825 char * generate_upd_file(){
     /* [<][>][^][v][top][bottom][index][help] */
 826 
 827    char * name;
 828      
 829    /* allocate space for name.  32 should be enough for PID */
 830    name = (char*)malloc(strlen("/tmp/dbupdate-tmp.") + strlen("notify") +32 ); 
 831    
 832    sprintf(name, "/tmp/dbupdate-tmp.%i", getpid());
 833 
 834      
 835    return name;
 836       
 837 }
 838 
 839 
 840 
 841 
 842 
 843 /* main */
 844 void main(int argc, char **argv, char **envp){
     /* [<][>][^][v][top][bottom][index][help] */
 845   //init_and_set_options(argc, argv, envp);
 846 
 847   int count = 0;
 848   int i,j;
 849   int no_of_updateables = 0;
 850   char ** temp_vector;
 851   char * temp;
 852   char * temp_upd_file = NULL;
 853   char *input_file_name = NULL;
 854   GHashTable *AUTO_NIC_hdl_hash;
 855   credentials_struct credentials;
 856   FILE * upd_file;
 857   char c;
 858   /* temp variables to read from conf */
 859   char * source = NULL, * canupd = NULL;
 860   ca_dbSource_t *source_hdl;
 861 
 862   GHashTable *ntfy_hash, *forw_hash, *cross_hash;
 863   
 864 
 865   char *mail_command_line, * ack_file_name;
 866   char *config_file_name = NULL;
 867   
 868 
 869   /* for using MM module */
 870   int retcode;
 871   MM_header *mail_header = NULL;
 872   MM_xmp_list *part_list;
 873   MM_xmp *partptr;
 874   long debug = 0;
 875     
 876   /* optarg & optind are necessary to use getopt(3C) */ 
 877   extern char *optarg;
 878   extern int optind;
 879 
 880 
 881   /* create notification hashes */
 882   ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
 883   forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
 884   cross_hash = g_hash_table_new(g_str_hash, g_str_equal);
 885       
 886   credentials.password_list = NULL;
 887   credentials.from = NULL;
 888   int ch;
 889   char * to_address = NULL;
 890 
 891   AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);       
 892   error_init(argc, argv);
 893   
 894       
 895               
 896 
 897   while ((ch = getopt(argc, argv, "MtTf:c:")) != -1){
 898           switch(ch) {
 899           case 'M':
 900                   reading_from_mail = 1;
 901                   break;
 902           case 'f':
 903                   input_file_name = strdup(optarg);
 904                   break;
 905           case 'c':
 906                   config_file_name = strdup(optarg);
 907                   break;
 908           case 't': 
 909                   tracing = 1;
 910                   break;
 911           case 'T':
 912                   test_mode = 1; 
 913                   break;       
 914           case '?':
 915           default:
 916                   printf("Unknown option\n");exit(1);
 917           }
 918   }
 919 
 920 
 921   /* config stuff */
 922   ca_populateDictionary(dictionary, VARS);
 923   /* if -c flag is given, use the named file as config file, otherwise use
 924      default filename */ 
 925   if( config_file_name != NULL){
 926     ca_readConfig(config_file_name, confVars, VARS);
 927   }else{
 928     ca_readConfig("dbupdate.conf", confVars, VARS);
 929   }
 930 
 931   tmpdir = ca_get_tmpdir;
 932   tmpdir = g_strstrip(tmpdir);
 933   mailcmd = ca_get_mailcmd;
 934   mailcmd = g_strstrip(mailcmd);
 935   notitxt = ca_get_notitxt;
 936   mailtxt = ca_get_mailtxt; 
 937   crosslog = ca_get_crosslog;
 938   fwtxt = ca_get_fwtxt;
 939   humailbox = ca_get_humailbox;
 940   humailbox = g_strstrip(humailbox);
 941   overridecryptedpw = ca_get_overridecryptedpw;
 942   overridecryptedpw = g_strstrip(overridecryptedpw);
 943   acklog = ca_get_acklog;
 944   notiflog = ca_get_notiflog;
 945   notimailtxt = ca_get_notimailtxt;  
 946   forwlog = ca_get_forwlog;
 947   fwmailtxt = ca_get_fwmailtxt;
 948   country = ca_get_country;
 949   pgppath = ca_get_pgppath;
 950   pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
 951   sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
 952   if(test_mode != 1){/* if it is not already set to 1 (from command line), read from config */
 953     test_mode = ca_get_testmode;
 954   }
 955   /* retrieve source variables */
 956   for(i=0, j=0, no_of_updateables=0; (source_hdl = ca_get_SourceHandleByPosition(i))!=NULL ; i++){   
 957     source = ca_get_srcname(source_hdl);
 958     printf("DEBUG: source: [%s]\n", source);
 959     canupd = ca_get_srccanupd(source_hdl);
 960     printf("DEBUG: canupd: [%s]\n", canupd);
 961     if(strcmp(canupd, "y") == 0){
 962       sources[j++] = strdup(source);
 963       no_of_updateables++;
 964     }
 965     if(no_of_updateables == 1 && strcmp(canupd, "y") == 0){/* if this is the first updatable source */
 966       /* get the port and hostname of RIPupdate, and those of query server */
 967       /* Note: We use NRTM part of the SOURCE line of the conf for update host 
 968                and MySQL part of it for query host
 969                so do not confuse */
 970       update_host = ca_get_srcnrtmhost(source_hdl);
 971       update_port = ca_get_srcnrtmport(source_hdl);
 972       query_host = ca_get_srcdbmachine(source_hdl);
 973       query_port = ca_get_srcdbport(source_hdl);   
 974     }
 975     free(source);free(canupd);
 976   }
 977   sources[j] = NULL; /* mark the end of array */
 978   if(no_of_updateables == 0){
 979     printf("There must be at least one updateable source in the config file. Exiting.\n");exit(1); 
 980   }else if(no_of_updateables > 1){
 981     printf("Warning: Multiple updateable sources are not supported yet. Exiting.\n");exit(1);
 982   }
 983 
 984   /* construct country array from country string variable */
 985   
 986   temp_vector = g_strsplit(country, "\n", 0);
 987   for(i=0, j=0; temp_vector[i] != NULL; i++){
 988     temp_vector[i] == g_strstrip(temp_vector[i]);
 989     if(strlen(temp_vector[i]) > 0){
 990       countries[j] = strdup(temp_vector[i]);
 991       g_strup(countries[j]);
 992       printf("DEBUG: got a country country[%i] =[%s],\n", j, countries[j]);
 993       j++;
 994     }
 995   }
 996   countries[j] = NULL; /* mark the end of array */
 997   printf("DEBUG: countries[%i] = NULL\n", j);
 998 
 999   printf("TMPDIR is: [%s]\n", tmpdir);
1000   printf("MAILCMD is: [%s]\n", mailcmd);
1001   printf("NOTITXT is: [%s]\n", notitxt);
1002   printf("CROSSLOG is: [%s]\n", crosslog);
1003   printf("FWTXT is: [%s]\n", fwtxt);
1004   printf("HUMAILBOX is: [%s]\n", humailbox);
1005   printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
1006   printf("ACKLOG is: [%s]\n", acklog);
1007   printf("NOTIFLOG is: [%s]\n", notiflog);
1008   printf("FORWLOG is: [%s]\n", forwlog);
1009   printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
1010   printf("FWMAILTXT is: [%s]\n", fwmailtxt);
1011   printf("COUNTRY is: [%s]\n", country);
1012   printf("PGPPATH is: [%s]\n", pgppath);
1013   printf("UPDATE_HOST is: [%s]\n", update_host);
1014   printf("UPDATE_PORT is: [%i]\n", update_port);
1015   printf("QUERY_HOST is: [%s]\n",  query_host);
1016   printf("QUERY_PORT is: [%i]\n",  query_port);   
1017  
1018   printf("TESTMODE is: [%i]\n", test_mode);
1019   /* end of config stuff */
1020 
1021   
1022     
1023   /* initialize the parser */
1024   schema.initialize();
1025 
1026 
1027   /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
1028       also creates it) */
1029   ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
1030   
1031 
1032   /* Allocate memory for the header */
1033   mail_header = (MM_header *)malloc(sizeof(MM_header));
1034 
1035   /* Initialize the list of extracted MIME parts */
1036   part_list = (MM_xmp_list *)malloc(sizeof(MM_xmp_list));
1037   MM_xmp_list_init (part_list);
1038 
1039   
1040   if(reading_from_mail){
1041     if(input_file_name != NULL){
1042       temp_upd_file = generate_upd_file();
1043       printf("DEBUG: temp_upd_file is [%s]\n", temp_upd_file);
1044       MM_store(input_file_name, temp_upd_file, 0);
1045       if((retcode = MM_decode(temp_upd_file, mail_header, part_list, 1, 0)) != 0){
1046         printf("DEBUG: MM_decode returned %i\n", retcode);
1047         exit(retcode);
1048       }
1049       
1050     }else{/* input_file_name == NULL */
1051       temp_upd_file = generate_upd_file();
1052       printf("DEBUG: temp_upd_file is [%s]\n", temp_upd_file);
1053       MM_store("-", temp_upd_file, 0);
1054       if((retcode = MM_decode(temp_upd_file, mail_header, part_list, 1, 0)) != 0){
1055         printf("DEBUG: MM_decode returned %i\n", retcode);
1056         exit(retcode);
1057       }
1058 
1059     }
1060         //unlink(temp_upd_file);
1061         printf ("Mail headers:\n\n");
1062         printf ("From - [%s]",mail_header->from);
1063         /* some MAIL-FROM's in mntner auths contain "From: " string too,
1064            so we have to have it in credential.from */
1065         temp = (char *)malloc(strlen(mail_header->from) + strlen("From: ") + 1);
1066         sprintf(temp, "From: %s", mail_header->from);
1067         temp[strlen(temp) - 4] = '\0'; /* cut two '\r\n's at the end */
1068         credentials.from = temp;
1069         printf ("credentials.from = [%s]\n", credentials.from );
1070         /* cut off the '\n's and '\r's at the end of mail_header->subject */
1071         while(mail_header->subject[strlen(mail_header->subject) - 1] == '\n' || 
1072               mail_header->subject[strlen(mail_header->subject) - 1] == '\r'){
1073           mail_header->subject[strlen(mail_header->subject) - 1] = '\0';
1074         }
1075         //mail_header->subject[strlen(mail_header->subject) - 4] = '\0';
1076         printf ("Subject - [%s]",mail_header->subject);
1077         printf ("Date - [%s]",mail_header->date);
1078         printf ("Message-ID - [%s]",mail_header->message_id);
1079         printf ("Reply-To - [%s]",mail_header->reply_to); 
1080         printf ("Cc - [%s]",mail_header->cc);
1081         to_address = find_to_address(credentials.from);
1082         /* if Reply-To was in the incoming mail's header, set to_address to that value */
1083         if(strlen(mail_header->reply_to) > 5){
1084           to_address = (char *)realloc(to_address, strlen(mail_header->reply_to) + 1);
1085           to_address = strcpy(to_address, mail_header->reply_to);
1086           //printf("DEBUG:   strlen(to_address)=[%i]\n", strlen(to_address));
1087           while(to_address[strlen(to_address) - 1] == '\n' || 
1088                 to_address[strlen(to_address) - 1] == '\r' ){
1089             //printf("DEBUG: cutting final '\\n'\n");
1090             //printf("DEBUG:   strlen(to_address)=[%i]\n", strlen(to_address));
1091             to_address[strlen(to_address) - 1] = '\0';
1092           }
1093           //printf("DEBUG: to_address is [%s]\n", to_address);
1094           //printf("DEBUG:   strlen(to_address)=[%i]\n", strlen(to_address));
1095         }
1096         AK_add_to_ack(ack_file_name, "To: %s\nFrom: %s\nSubject: Re: %s \nReply-To: %s\n\nAcknowledgement message from database software, beta version\n", to_address, humailbox, mail_header->subject, humailbox);
1097         if(credentials.from != NULL){
1098           AK_add_to_ack(ack_file_name, "\n[%s]\n", credentials.from);
1099         }
1100 
1101         partptr = part_list->head;
1102         while (partptr != NULL){
1103           
1104           printf("-----------------------------------------\n");
1105           printf ("Section: %s\n",partptr->number);
1106           printf ("Content-type: %s\n",partptr->type);
1107           if (partptr->supported){
1108             printf ("Supported\n");
1109             printf ("Filename is [%s]\n", partptr->file);
1110             process_file(partptr->file, credentials, 
1111                   AUTO_NIC_hdl_hash, ack_file_name, 
1112                   ntfy_hash, forw_hash, cross_hash);
1113           }
1114           else{
1115             printf ("Unsupported MIME type\n");
1116             AK_add_to_ack(ack_file_name, "\nWarning: Unsupported MIME type: %s. Ignored.\n", partptr->type);
1117           }
1118           partptr = partptr->next;
1119         }
1120       
1121 
1122       /* Clean up the temporary files */
1123       MM_cleanup(part_list, 0);
1124 
1125       
1126   }else{/* not reading from the mail message */
1127     if(input_file_name != NULL){
1128       process_file(input_file_name, credentials, 
1129                   AUTO_NIC_hdl_hash, ack_file_name, 
1130                   ntfy_hash, forw_hash, cross_hash);
1131     }else{/* the filename is not given, so we have to write 
1132              stdin to a temp file, and give it to process_file */
1133        temp_upd_file = generate_upd_file();
1134        printf("DEBUG: main: temp_upd_file=%s\n", temp_upd_file);
1135        if(( upd_file = fopen(temp_upd_file, "a")) == NULL){
1136          fprintf(stderr, "Can't open ack file, %s", temp_upd_file);
1137        }
1138 
1139        while((c = getchar()) != EOF){
1140          fprintf(upd_file, "%c",c);
1141        }
1142        fclose(upd_file);
1143        process_file(temp_upd_file, credentials, 
1144                   AUTO_NIC_hdl_hash, ack_file_name, 
1145                   ntfy_hash, forw_hash, cross_hash);
1146        unlink(temp_upd_file);
1147         
1148     }
1149       
1150   }  
1151 
1152 
1153   if(reading_from_mail && to_address != NULL){
1154     AK_send_ack(ack_file_name, to_address, mailcmd);
1155   }
1156   AK_log_ack(ack_file_name, acklog);
1157   AK_delete_ack(ack_file_name);
1158 
1159   NT_send_ntfy_list(ntfy_hash, mailcmd);
1160   NT_log_ntfy_list(ntfy_hash, notiflog); 
1161   NT_delete_ntfy_list(ntfy_hash);
1162 
1163   NT_send_ntfy_list(forw_hash, mailcmd);
1164   NT_log_ntfy_list(forw_hash, forwlog); 
1165   //NT_delete_ntfy_list(forw_hash);
1166 
1167   
1168 
1169   if(tracing) {
1170     printf("TRACING: END\n");
1171   }
1172 
1173 
1174 }

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