## 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] */