## bin/dbupdate/dbupdate.cc

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

## FUNCTIONS

This source file includes following functions.

1. error_init
2. delete_key
3. import_key
4. process_object
5. remove_EOLs
6. process_file
7. generate_upd_file
8. create_lock_file
9. remove_lock_file
10. write_checkpoint
11. main

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

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