## bin/dbupdate/dbupdate.c

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

## FUNCTIONS

This source file includes following functions.

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

       1 /***************************************
       2   $Revision: 1.15 $
       3
       4   DBupdate
       5
       6   Status: PARTIALLY REVIEWED, NOT TESTED
       7
       8   Author(s):       Engin Gunduz
       9
      10   ******************/ /******************
      11   Modification History:
      12         engin (01/03/2000) Created.
      13                 denis (31/08/2001) Modified for new API
      14   ******************/ /******************
      15   Copyright (c) 2001,2002                         RIPE NCC
      16
      17   All Rights Reserved
      18
      19   Permission to use, copy, modify, and distribute this software and its
      20   documentation for any purpose and without fee is hereby granted,
      21   provided that the above copyright notice appear in all copies and that
      22   both that copyright notice and this permission notice appear in
      23   supporting documentation, and that the name of the author not be
      24   used in advertising or publicity pertaining to distribution of the
      25   software without specific, written prior permission.
      26
      27   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      28   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      29   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      30   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      31   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      32   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      33  ***************************************/
      34
      35
      36
      37
      38 #include <config.h>
      39 #include "dbupdate.h"
      40 #include "UP_extrnl_syntax.h"
      41 #include "UP_subject.h"
      42 #include "er_yacc_helper.h"
      43 #include "erroutines.h"
      44 #include "ca_configFns.h"
      45 #include "ca_dictionary.h"
      46 #include "ca_macros.h"
      47 #include "ca_srcAttribs.h"
      48 #include "notification.h"
      49 #include "gpg.h"
      50 #include "mail_parser.h"
      51 #include "process.h"
      52
      53 #ifdef HAVE_SYS_PARAM_H
      54 #include <sys/param.h>
      55 #endif
      56
      57
      58 int tracing = 0;
      59 int test_mode = 0;
      60 int supress_ack_notif = 0;
      61 int print_out_ack = 0;
      62
      63 /* do we process a mail */
      64 int reading_from_mail = 0;
      65
      66 /* are we processing networkupdate? */
      67 int networkupdate = 0;
      68
      69 /* IP of the networkupdate client */
      70 char * netupdclientIP = NULL;
      71
      72 /* two global variables to tally the processed objects */
      73 int count_successful = 0;
      74 int count_unsuccessful = 0;
      75
      76
      77 /* sender of the mail, in case of a mail update */
      78 char *update_mail_sender = NULL;
      79 char *update_mail_subject = NULL;
      80 char *update_mail_date = NULL;
      81 char *update_mail_ID = NULL;
      82 char *update_mail_cc = NULL;
      83
      84 /* re-direct to humail message */
      85 char *header_type = NULL;
      86 char *text_type = NULL;
      87
      88 /* required configuration variables */
      89 char *tmpdir = NULL;
      90 char *lockdir = NULL;
      91 char *mailcmd = NULL;
      92 char *notitxt = NULL;
      93 char *successtxt = NULL;
      94 char *failuretxt = NULL;
      95 char *helpheader = NULL;
      96 char *notimailtxt = NULL;
      97 char *notinetworktxt = NULL;
      98 char *fwtxt   = NULL;
      99 char *fwmailtxt = NULL;
     100 char *mtfwheader = NULL;
     101 char *mtfwtxt = NULL;
     102 char *mailtxt = NULL;
     103 char *acksig = NULL;
     104 char *defmail = NULL;
     105 char *updlog = NULL;
     106 char *notiflog = NULL;
     107 char *crosslog = NULL;
     108 char *acklog = NULL;
     109 char *forwlog = NULL;
     110 char *humailbox = NULL;
     111 char *autobox = NULL;
     112 char *copyright_notice = NULL;
     113 char *overridecryptedpw = NULL;
     114 char *country = NULL;
     115 char *countries[400];
     116 char *nicsuffixes[7];
     117 char *sources[100];
     118 char *pgppath = NULL;
     119 char *gpgcmd = NULL;
     120 char *pgp_public_key_ring = NULL;
     121 char *autodbmhelp = NULL;
     122 char *update_host = NULL;
     123 int  update_port;
     124 char *query_host = NULL;
     125 int  query_port;
     126 char *cn_subject_add = NULL;
     127 char *cn_subject_del = NULL;
     128 char *cn_explain_add = NULL;
     129 char *cn_explain_del = NULL;
     130 char *cn_overlap_add = NULL;
     131 char *cn_overlap_del = NULL;
     132 char *cno_subject_add = NULL;
     133 char *cno_subject_del = NULL;
     134 char *cno_explain_add = NULL;
     135 char *cno_explain_del = NULL;
     136 char *cno_overlap_add = NULL;
     137 char *cno_overlap_del = NULL;
     138 char *allocmnt = NULL;
     139 char *mheader = NULL;
     140 char *DBhost = NULL;
     141 int  DBport;
     142 char *DBuser = NULL;
     143 char *DBname = NULL;
     144 char *DBpasswd = NULL;
     145 /* end of config variables */
     146
     147 char * fingerprint = NULL;
     148 char * keyowner = NULL;
     149
     150 /* result of subject line processing is kept in the following struct. */
     151 up_subject_struct subject_result;
     152
     153
     154 /* hostname and pid are used all over the program, so we save them into these variables */
     155 char hostname[MAXHOSTNAMELEN];
     156 /* char * hostname; */
     157 int pid;
     158
     159 /* name of the lock file, which is used for the crash recovery mechanism */
     160 char * lock_file_name;
     161
     162 void error_init(int argc, char ** argv) {
         /* [<][>][^][v][top][bottom][index][help] */
     163
     164   ER_init("dbupdate", 1);
     165
     166
     167 } /* error_init() */
     168
     169
     170
     171
     172
     173
     174 /* 'lockfile' struct is for keeping both the name of the lock file and the file descriptor
     175     of it, which is open during the execution of dbupdate. We need the filedes to close it,
     176     when dbupdate finishes, and the name to delete the file. */
     177 typedef struct {
     178    char * lockname;
     179    int filedes;
     180 } lockfilestruct;
     181
     182
     183 lockfilestruct lockfile;
     184
     185
     186
     187 /* Deletes the key defined in the incoming object (a key-cert object)
     188    from the public keyring. Returns NULL if there was no error,
     189    returns an error message if there is an error */
     190 char *delete_key(rpsl_object_t * obj)
         /* [<][>][^][v][top][bottom][index][help] */
     191 {
     192   struct ImportKeyObject iKO;
     193   char * obj_keyID;
     194   char * key_cert_attr;
     195   GList * templist;
     196   GList * certiflist, * next;
     197   u32 keyID;
     198   char * key_file_name;
     199   char ** lines;
     200   int i;
     201   FILE * key_file;
     202   char * temp, * temp2;
     203   char * error_string;
     204   rpsl_attr_t *attr;
     205
     206   templist = get_attr_list(obj, "key-cert");
     207   attr = (rpsl_attr_t *)(templist->data);
     208   key_cert_attr = strdup((char *)(attr->value));
     209 /*  key_cert_attr = strdup( (char *)( ((rpsl_attr_t *)(templist->data))->value ) );  */
     210   rpsl_attr_delete_list(templist);
     211
     212   key_file_name = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
     213   sprintf(key_file_name, "%s/tmp-key.%i", tmpdir, pid);
     214
     215   /* now we must write certif attribute(s) of this key-certif into the key_file_name */
     216   /* get the certif first */
     217   certiflist = get_attr_list(obj, "certif");
     218   if (( key_file = fopen(key_file_name, "w")) == NULL)
     219   {
     220      ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", key_file_name);
     221      exit(1);
     222   }
     223   for ( next = certiflist; next != NULL ; next = g_list_next(next) )
     224   {
     225     attr = (rpsl_attr_t *)(next->data);
     226     lines = g_strsplit((char *)(attr->value), "\n", 0);
     227     if (lines[0] == NULL)
     228         { /* if this was an empty attribute, just print an empty line */
     229       fprintf(key_file, "\n");
     230     }
     231     for (i = 0; lines[i] != NULL; i++)
     232         {
     233       temp = strdup(lines[i]);
     234       if (i != 0 && temp[0] == '+')
     235           { /* if it begins with a plus */
     236         temp2 = strdup(temp + 1);
     237         g_strstrip(temp2);
     238         fprintf(key_file, "%s\n", temp2);
     239         free(temp);free(temp2);
     240       }
     241           else
     242           {
     243         g_strstrip(temp);
     244         fprintf(key_file, "%s\n", temp);
     245         free(temp);
     246       }
     247     }
     248     g_strfreev(lines);
     249   }
     250   fclose(key_file);
     251   rpsl_attr_delete_list(certiflist);
     252
     253   strcpy(iKO.iFilename, key_file_name);
     254
     255   if (tracing)
     256   {
     257     printf("TRACING: delete_key: key_cert_attr: [%s]\n", key_cert_attr);
     258   }
     259
     260   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
     261
     262   if (tracing)
     263   {
     264     printf("TRACING: delete_key: obj_keyID: [%s]\n", obj_keyID);
     265   }
     266
     267   keyID = strtoul(obj_keyID, NULL, 16);
     268
     269   if (tracing)
     270   {
     271     printf("TRACING: delete_key: keyID is: %u, %X\n", keyID, keyID);
     272   }
     273
     274   strcpy(iKO.keyRing, pgp_public_key_ring);
     275   PA_RemoveKey(&iKO);
     276
     277   if (tracing)
     278   {
     279     printf("TRACING: importKeyObj status:\n");
     280     printf("TRACING: isValid: %d\n", iKO.rc);
     281   }
     282
     283   /* clean-up: delete the file, free the char *    */
     284   unlink(key_file_name);
     285   free(key_file_name);
     286
     287   if (iKO.rc == iKO_OK)
     288   { /* if PA_RemoveKey returned OK */
     289     return NULL;
     290   }
     291   else
     292   {  /* if PA_RemoveKey returned not OK */
     293       switch (iKO.rc)
     294           {
     295         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break;
     296         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
     297         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
     298         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
     299         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
     300         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
     301         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
     302         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
     303         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
     304         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
     305         default:            error_string = strdup("general PGP error");
     306       }
     307       return error_string;
     308   }
     309
     310 }
     311
     312
     313
     314
     315
     316
     317
     318 /* Takes a key-certif object, extracts its 'certif' attribute and adds
     319    the key into public keyring
     320    If there is no problem, it returns NULL
     321    If there is a problem, then it returns a string which contains an error
     322    message */
     323 char * import_key(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
     324 {
     325   char * key_file_name;
     326   char *value;
     327   struct ImportKeyObject iKO;
     328   GList * certiflist, * item, * templist;
     329   FILE * key_file;
     330   char keyID[9];
     331   char * obj_keyID, * key_cert_attr;
     332   char * error_string = NULL;
     333
     334   key_file_name = (char *)malloc(strlen(tmpdir) + strlen("tmp-key.") + 32);
     335   sprintf(key_file_name, "%s/tmp-key.%i", tmpdir, pid );
     336
     337   /* now we must write certif attribute(s) of this key-certif into the key_file_name */
     338   /* get the certif first */
     339   certiflist = rpsl_object_get_attr(object, "certif");
     340   if (( key_file = fopen(key_file_name, "w")) == NULL)
     341   {
     342      ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temporary file, %s", key_file_name);
     343      exit(1);
     344   }
     345   for( item = certiflist; item != NULL ; item = g_list_next(item) )
     346   {
     347     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(item->data) );
     348         if (value == NULL)
     349         { /* if this was an empty attribute, just print an empty line */
     350       fprintf(key_file, "\n");
     351     }
     352         else
     353         {
     354           fprintf(key_file, "%s\n", value);
     355           free(value);
     356         }
     357   }
     358   fclose(key_file);
     359   rpsl_attr_delete_list(certiflist);
     360
     361   strcpy(iKO.iFilename, key_file_name);
     362   strcpy(iKO.keyRing, pgp_public_key_ring);
     363   PA_ImportKey(&iKO);
     364
     365   if (tracing)
     366   {
     367     printf("importKeyObj status:\n");
     368
     369     printf("isValid: %d\n", iKO.rc);
     370     printf("keyID: %08lX\n", (long)(iKO.keyID) );
     371   }
     372   snprintf(keyID, 9, "%08lX", iKO.keyID);
     373
     374   if (tracing)
     375   {
     376     printf("keyID: [%s]\n", keyID);
     377   }
     378
     379   templist = rpsl_object_get_attr(object, "key-cert");
     380   key_cert_attr = rpsl_attr_get_clean_value((rpsl_attr_t *)(templist->data));
     381   rpsl_attr_delete_list(templist);
     382
     383   if (tracing)
     384   {
     385     printf("key_cert_attr: [%s]\n", key_cert_attr);
     386   }
     387   obj_keyID = strdup(key_cert_attr + strlen("PGPKEY-"));
     388   free(key_cert_attr);
     389   if (tracing)
     390   {
     391     printf("obj_keyID: [%s]\n", obj_keyID);
     392   }
     393
     394   if (iKO.rc == iKO_OK && (strcasecmp(obj_keyID, keyID) == 0))
     395   { /* if PA_ImportKey returned OK
     396     and the real keyID is equal to the
     397     keyID in the 'key-cert' attribute */
     398     fingerprint = strdup(iKO.fingerPrint);
     399     keyowner    = strdup(iKO.keyOwner);
     400
     401     /* clean-up: delete the file, free the variable */
     402     unlink(key_file_name);
     403     free(key_file_name);
     404
     405     return NULL;
     406   }
     407   else
     408   {
     409     /* if PA_ImportKey returned not OK or obj_keyID, keyID didn't match */
     410     if  (iKO.rc != iKO_OK)
     411         {
     412       switch (iKO.rc)
     413           {
     414         case iKO_UNCHANGED:      error_string = strdup("the key is already in the keyring");break;
     415         case iKO_NOUSERID:       error_string = strdup("no user ID could be extracted");break;
     416         case iKO_GENERAL:        error_string = strdup("general PGP error");break;
     417         case iKO_NOTVALIDUSERID: error_string = strdup("no valid user ID ");break;
     418         case iKO_NOPUBLICKEY:    error_string = strdup("no public key in the object");break;
     419         case iKO_NODEFAULTPUBLICKEYRING: error_string = strdup("general PGP error");break;
     420         case iKO_CRC_ERROR:      error_string = strdup("CRC error in the certificate");break;
     421         case iKO_NO_OPENPGP_DATA:error_string = strdup("no OpenPGP data in the object");break;
     422         case iKO_NO_IN_FILES:    error_string = strdup("general PGP error");break;
     423         case iKO_MULTIPLE_KEYS:  error_string = strdup("multiple keys in key-cert object");break;
     424         case iKO_GENERALFAILURE: error_string = strdup("general PGP error");break;
     425         default:            error_string = strdup("general PGP error");
     426       }
     427
     428       /* clean-up: delete the file, free the variable */
     429       unlink(key_file_name);
     430       free(key_file_name);
     431       return error_string;
     432
     433     }
     434         else
     435         {
     436       error_string = (char *)malloc(1024);/* this should be enough */
     437       sprintf(error_string, "Keyid for this certificate (%s) is not the same as the PGPKEY field (%s)",
     438                  keyID, obj_keyID);
     439       /* roll-back: we encountered a problem, so we have to remove the key that
     440          we've added */
     441       PA_RemoveKey(&iKO);
     442
     443       /* clean-up: delete the file, free the variable */
     444       unlink(key_file_name);
     445       free(key_file_name);
     446
     447             free(obj_keyID);
     448       return error_string;
     449     }
     450   }
     451
     452 }
     453
     454
     455
     456 /* Gets the keyowner and fingerprint of a PGP key
     457    from the keycert object. The keycert object must already
     458    be in the database (thus, in the keyring)
     459    The fingerprint and keyowner will be saved in global variables */
     460
     461 void get_keyowner_fingerpr(rpsl_object_t *obj)
         /* [<][>][^][v][top][bottom][index][help] */
     462 {
     463   GList * templist = NULL;
     464   char * obj_keyID = NULL;
     465   struct ImportKeyObject iKO;
     466   u32 keyID;
     467   char * key_cert_value;
     468
     469
     470   templist = rpsl_object_get_attr(obj, "key-cert");
     471   key_cert_value = rpsl_attr_get_clean_value((rpsl_attr_t *)(templist->data));
     472   rpsl_attr_delete_list(templist);
     473
     474   if (tracing)
     475   {
     476     printf("get_keyowner_fingerpr: key_cert_attr is [%s]\n", key_cert_value);
     477   }
     478
     479   obj_keyID = strdup(key_cert_value + strlen("PGPKEY-"));
     480   if (tracing)
     481   {
     482     printf("get_keyowner_fingerpr: obj_keyID is [%s]\n", obj_keyID);
     483   }
     484
     485   sscanf(obj_keyID, "%8X", &keyID);
     486   if (tracing)
     487   {
     488     printf("get_keyowner_fingerpr: keyID is [%u]\n", keyID);
     489  }
     490
     491   /* set appropriate fields of iKO */
     492   iKO.keyID = keyID;
     493   strcpy(iKO.keyRing, pgp_public_key_ring);
     494
     495   GetFingerPrint(&iKO);
     496   fingerprint = strdup(iKO.fingerPrint);
     497
     498   GetKeyOwner(&iKO);
     499   keyowner = strdup(iKO.keyOwner);
     500
     501   free(key_cert_value);
     502   free(obj_keyID);
     503
     504   if(tracing)
     505   {
     506     if (fingerprint != NULL)
     507         {
     508       printf("get_keyowner_fingerpr: fingerprint is [%s]\n", fingerprint);
     509     }
     510     if (keyowner)
     511         {
     512       printf("get_keyowner_fingerpr: keyowner is [%s]\n", keyowner);
     513     }
     514   }
     515 }
     516
     517
     518
     519
     520
     521
     522 /* Checks the object's syntax, retrives the old version of it from the db,
     523    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
     524    integrity is checked, and the object is really committed to the db.
     525
     526      Arguments:
     527         char * incoming: The object,
     528         credentials_struct credentials: The struct containing the credentials, such as
     529           'From:' field of the e-mail update,
     530         GHashTable * NIC_hdl_hash: A hash containing
     531         char * ack_file_name:  The file name, to be used to store ACK message
     532         GHashTable * ntfy_hash,
     533         GHashTable * forw_hash,
     534         GHashTable * cross_hash: hashes that contain files that have notifications.
     535 */
     536
     537
     538
     539 int process_object(char * incoming, credentials_struct credentials,
         /* [<][>][^][v][top][bottom][index][help] */
     540                    GHashTable * NIC_hdl_hash, char * ack_file_name,
     541                    GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash)
     542 {
     543     rpsl_object_t *object = NULL;
     544     rpsl_object_t *old_obj = NULL;
     545     rpsl_object_t *external_syntax_obj = NULL;
     546     rpsl_object_t *obj_with_AUTO_NIC_hdl = NULL;
     547     rpsl_object_t *formatted_object = NULL;
     548     rpsl_object_t *generated_obj = NULL;
     549     const GList * error_list = NULL;
     550     const GList * error_list_item = NULL;
     551     const GList * attr_list = NULL;
     552     const GList * attr_list_item = NULL;
     553     const GList * attr_error_list = NULL;
     554     const GList * attr_error_list_item = NULL;
     555     char * old_version = NULL;
     556     int result = 0;
     557     char * result_from_import_key = NULL;
     558     char * result_from_delete_key = NULL;
     559     char * auto_nic = NULL;
     560     char * changed_obj_str = NULL;
     561         char *obj_with_AUTO_NIC_hdl_str;
     562     char * assigned_NIC;
     563     char * formatted_object_str;
     564     const char * type;
     565         char *lctype;
     566     char * arg;
     567     char * arg2;
     568     char * generated_obj_str;
     569         const char * value = NULL;
     570         const char * name = NULL;
     571         char * attribute = NULL;
     572         int noclass;
     573         char *key;
     574     up_ripupd_result_struct * result_from_RIPupd;
     575     external_syntax_struct * external_syntax_results;
     576         gint elevel, ecode;
     577         gchar *edescr = NULL;
     578
     579     arg = strdup(incoming);
     580
     581         object = rpsl_object_init(arg);
     582         error_list = rpsl_object_errors(object);
     583         if (tracing && error_list)
     584         {
     585           printf("TRACING: errors found on initial object parse\n");
     586           for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
     587           {
     588             elevel = ((rpsl_error_t *)(error_list_item->data))->level;
     589                 ecode = ((rpsl_error_t *)(error_list_item->data))->code;
     590                 edescr = strdup(((rpsl_error_t *)(error_list_item->data))->descr);
     591
     592                 printf("TRACING: level [%d]  code [%d]  [%s]\n", elevel, ecode, edescr);
     593                 free(edescr);
     594           }
     595         }
     596         if ( error_list )
     597         {
     598           if ( ((rpsl_error_t *)(error_list->data))->code == RPSL_ERR_ONLYCOMMENTS )
     599             return UP_NOOBJECT;
     600         }
     601
     602     if ( !rpsl_object_has_error(object, RPSL_ERRLVL_ERROR)
     603                         && has_ref_to_AUTO_nic_hdl(object) )
     604         {  /* parsed with no systax errors */
     605           if (tracing)
     606           {
     607         printf("TRACING: the object has ref to AUTO nic-hdl\n");
     608           }
     609
     610           /* if this object has refs to AUTO NIC hdls*/
     611       /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
     612       if ((changed_obj_str = replace_refs_to_AUTO_NIC_hdl(object, NIC_hdl_hash, arg)) == NULL)
     613           {
     614                 type = rpsl_object_get_class(object);
     615
     616                 free(arg);
     617         if ( UP_remove_override_attr(object) )
     618           arg = rpsl_object_get_text(object,0);
     619                 else
     620                 {
     621                   /* there was an override attr in this object and it has not been removed */
     622                   arg = (char *)malloc(2);
     623                   strcpy(arg, "");      /* Don't include object in ack/notif msgs */
     624                 }
     625
     626         AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] Unknown AUTO NIC handle referenced\n%s\n",
     627                 type ? type : "unknown-type", arg);
     628
     629         rpsl_object_delete(object);
     630         free(arg);
     631         return UP_ANE; /* AUTO NIC hdl error */
     632       }
     633           else
     634           { /* in this case, we must use changed_obj_str instead of arg */
     635
     636         free(arg);
     637         arg = changed_obj_str;
     638       };
     639     }
     640
     641
     642     if ( !rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
     643         {
     644           /* parsed with no systax errors */
     645       type = rpsl_object_get_class(object);
     646       /* is the object to be deleted? */
     647       if ( rpsl_object_is_deleted(object) )
     648           {
     649         old_version = get_old_version(object, arg);
     650
     651         if(old_version == NULL)
     652                 {  /* the object doesn't exist in the db! */
     653
     654                   if (tracing)
     655                   {
     656                 printf("TRACING: the object doesn't exist in the db\n");
     657                   }
     658
     659                   free(arg);
     660           if ( UP_remove_override_attr(object) )
     661                 arg = rpsl_object_get_text(object,0);
     662                   else
     663                   {
     664                         /* there was an override attr in this object and it has not been removed */
     665                         arg = (char *)malloc(2);
     666                         strcpy(arg, "");        /* Don't include object in ack/notif msgs */
     667                   }
     668
     669           AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n***Error: Entry not found\n\n",
     670                         type, get_search_key(object, type), arg);
     671
     672           rpsl_object_delete(object);
     673           free(arg);
     674           return UP_NSO; /* no such object */
     675         }
     676                 else
     677                 {  /* the object is in the db */
     678
     679                   if (tracing)
     680                   {
     681                 printf("TRACING: the object is in the db\n");
     682                   }
     683
     684                   lctype = strdup(type);
     685                   g_strdown(lctype);
     686           if (    identical(old_version, object)      /* if the old & new versions are identical */
     687                || (strcmp(lctype, "key-cert") == 0)   /* or it is a key-cert object  */
     688                || (strcmp(lctype, "inet6num") == 0) ) /* or it is an inet6num object */
     689                   {
     690             result = check_auth(NULL, object, type, credentials);
     691             if(result == UP_AUTH_OK)
     692                         {
     693               if (tracing)
     694                           {
     695                 printf("TRACING: Will send the obj to be deleted\n");
     696               }
     697               if(strcmp(type, "key-cert") == 0)
     698                           {
     699                 result_from_delete_key = delete_key(object);
     700               }
     701                           else
     702                           {
     703                 result_from_delete_key = NULL;
     704               }
     705               /* if there was no problem with key deletion from the key-ring */
     706               if (result_from_delete_key == NULL)
     707                           {
     708                 result_from_RIPupd = send_object_db(object, NULL, "DEL");
     709                 if (result_from_RIPupd->result == 0)
     710                                 {
     711                   AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n",
     712                                 type, get_search_key(object, type));
     713                   NT_write_all_ntfs(old_version, NULL, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash,
     714                                     credentials.from);
     715
     716                   rpsl_object_delete(object);
     717                                   free(result_from_RIPupd);
     718                   free(arg);
     719                           free(old_version);
     720                   return UP_OK;
     721                 }
     722                                 else
     723                                 {
     724                   AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
     725                                 type, get_search_key(object, type),
     726                                 result_from_RIPupd->error_str);
     727
     728                   rpsl_object_delete(object);
     729                                   free(result_from_RIPupd->error_str);
     730                                   free(result_from_RIPupd);
     731                   free(arg);
     732                           free(old_version);
     733                   return UP_INT;
     734                 }
     735               }
     736                           else
     737                           {
     738                  AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
     739                                 type, get_search_key(object, type),
     740                                 result_from_delete_key);
     741
     742                  rpsl_object_delete(object);
     743                  free(arg);
     744                          free(old_version);
     745                  free(result_from_delete_key);
     746                  return UP_INT;
     747               }
     748             }
     749                         else
     750                         { /* auth failed */
     751               if (tracing)
     752                           {
     753                 printf("TRACING: Auth failed\n");
     754               }
     755
     756                       free(arg);
     757                   if ( UP_remove_override_attr(object) )
     758                         arg = rpsl_object_get_text(object,0);
     759                           else
     760                           {
     761                                 /* there was an override attr in this object and it has not been removed */
     762                                 arg = (char *)malloc(2);
     763                                 strcpy(arg, "");        /* Don't include object in ack/notif msgs */
     764                           }
     765
     766               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
     767                             type, get_search_key(object, type), arg);
     768               NT_write_all_frwds(old_version, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     769
     770               rpsl_object_delete(object);
     771               free(arg);
     772                       free(old_version);
     773               return UP_AUF; /* Auth failed */
     774             }
     775           }  /* end of identical match */
     776                   else
     777                   {  /* the new & old versions do not match */
     778                     free(arg);
     779                 if ( UP_remove_override_attr(object) )
     780                   arg = rpsl_object_get_text(object,0);
     781                         else
     782                         {
     783                           /* there was an override attr in this object and it has not been removed */
     784                           arg = (char *)malloc(2);
     785                           strcpy(arg, "");      /* Don't include object in ack/notif msgs */
     786                         }
     787
     788             AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n***Error: new & old versions do not match\n",
     789                  type, get_search_key(object, type), arg);
     790
     791             rpsl_object_delete(object);
     792             free(arg);
     793                     free(old_version);
     794             return UP_NOM; /* new & old versions do not match */
     795           }
     796         }  /* end of the object is in the db */
     797       } /* end of the object is to be deleted */
     798           else
     799           { /* the object is _NOT_ to be deleted */
     800
     801         if (has_AUTO_NIC_hdl(object))
     802                 { /* if the object has an AUTO NIC hdl */
     803                   external_syntax_obj = rpsl_object_copy(object);
     804           external_syntax_results = UP_check_external_syntax(external_syntax_obj);
     805           if (    external_syntax_results->result != UP_EXTSYN_ERR
     806                && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
     807                   { /* if there is no error */
     808             /* then its nic-hdl attribute must be modified so that RIPupdate
     809                would understand that it must assign a NIC handle to it */
     810             /* but first check the auth */
     811             result = check_auth(external_syntax_obj, NULL, type, credentials);
     812             if (result == UP_AUTH_OK)
     813                         {
     814               if (tracing)
     815                           {
     816                   printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
     817               }
     818               auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
     819               obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(external_syntax_obj, auto_nic);
     820               if (tracing)
     821                           {
     822                             obj_with_AUTO_NIC_hdl_str = rpsl_object_get_text(obj_with_AUTO_NIC_hdl,0);
     823                 printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl_str);
     824                 printf("TRACING: Will send the obj to be added\n");
     825                                 free(obj_with_AUTO_NIC_hdl_str);
     826                                 obj_with_AUTO_NIC_hdl_str = NULL;
     827               }
     828               assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
     829               result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
     830               if (result_from_RIPupd->result == 0)
     831                           {
     832                 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n", type, assigned_NIC);
     833
     834                 /* replace the AUTO nic hdl with the assigned one (for reporting purposes, in the notif mesg) */
     835                 formatted_object = UP_put_assigned_NIC(external_syntax_obj, assigned_NIC);
     836
     837                 formatted_object_str = rpsl_object_get_text(formatted_object,0);
     838                 NT_write_all_ntfs(NULL, arg, formatted_object_str, tmpdir, ntfy_hash, forw_hash, cross_hash,
     839                                   credentials.from);
     840
     841                 result_from_RIPupd->result = 0;
     842                 if (tracing && assigned_NIC != NULL)
     843                                 {
     844                   printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
     845                 }
     846                 if (assigned_NIC != NULL)
     847                                 {
     848                   if (tracing)
     849                                   {
     850                     printf("TRACING: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
     851                   }
     852                   g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
     853                   if (tracing)
     854                                   {
     855                     printf("TRACING: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
     856                   }
     857                 }
     858
     859                                 rpsl_object_delete(formatted_object);
     860                                 rpsl_object_delete(obj_with_AUTO_NIC_hdl);
     861                                 rpsl_object_delete(external_syntax_obj);
     862                 rpsl_object_delete(object);
     863                                 free(result_from_RIPupd);
     864                                 free(formatted_object_str);
     865                                 free(external_syntax_results->new_obj);
     866 /*                              free(external_syntax_results->error_str);*/
     867 /*                              free(external_syntax_results->warning_str);*/
     868                                 free(external_syntax_results);
     869                 free(arg);
     870                 return UP_OK;
     871               }
     872                           else
     873                           {
     874                         if ( UP_remove_override_attr(object) )
     875                           arg2 = rpsl_object_get_text(object,0);
     876                                 else
     877                                 {
     878                                   /* there was an override attr in this object and it has not been removed */
     879                                   arg2 = (char *)malloc(2);
     880                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
     881                                 }
     882
     883                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s]\n%s\n%s\n",
     884                               type, arg2, result_from_RIPupd->error_str);
     885
     886                                 rpsl_object_delete(obj_with_AUTO_NIC_hdl);
     887                                 rpsl_object_delete(external_syntax_obj);
     888                 rpsl_object_delete(object);
     889                                 free(result_from_RIPupd);
     890                                 free(external_syntax_results->new_obj);
     891                                 free(external_syntax_results);
     892                                 free(arg2);
     893                 free(arg);
     894                 return UP_INT;
     895               }
     896             }
     897                         else
     898                         {
     899               /* auth failed ! */
     900               if (tracing)
     901                           {
     902                 printf("TRACING: Auth failed\n");
     903               }
     904
     905                   if ( UP_remove_override_attr(object) )
     906                         arg2 = rpsl_object_get_text(object,0);
     907                           else
     908                           {
     909                                 /* there was an override attr in this object and it has not been removed */
     910                                 arg2 = (char *)malloc(2);
     911                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
     912                           }
     913
     914               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
     915                             type, get_search_key(object, type), arg2);
     916               NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     917
     918                       rpsl_object_delete(external_syntax_obj);
     919               rpsl_object_delete(object);
     920                           free(external_syntax_results->new_obj);
     921                       free(external_syntax_results);
     922                       free(arg2);
     923               free(arg);
     924               return UP_AUF; /* Auth failed */
     925             }
     926           }
     927                   else
     928                   { /* external syntax check failed */
     929                 if ( UP_remove_override_attr(object) )
     930                   arg2 = rpsl_object_get_text(object,0);
     931                         else
     932                         {
     933                           /* there was an override attr in this object and it has not been removed */
     934                           arg2 = (char *)malloc(2);
     935                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
     936                         }
     937
     938             AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s\n",
     939                    type, get_search_key(object, type),
     940                    arg2, external_syntax_results->error_str);
     941
     942                     rpsl_object_delete(external_syntax_obj);
     943             rpsl_object_delete(object);
     944                         free(external_syntax_results->new_obj);
     945                         free(external_syntax_results);
     946                     free(arg2);
     947             free(arg);
     948             return UP_SYN;
     949           }
     950         }  /* end of the object has an AUTO NIC hdl */
     951         else
     952                 { /* process object without an AUTO NIC hdl */
     953           old_version = get_old_version(object, arg);
     954           if (old_version != NULL)
     955                   {
     956                     /* so, this is an update operation */
     957             if ( (!reading_from_mail) ||
     958                 (subject_result.result != UP_SUBJ_NEW_ENFORCED))
     959                         {
     960                           /* If the user didn't enforce creation in the subject line */
     961                       external_syntax_obj = rpsl_object_copy(object);
     962               external_syntax_results = UP_check_external_syntax(external_syntax_obj);
     963               if (    external_syntax_results->result != UP_EXTSYN_ERR
     964                    && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
     965                           {
     966                             /* if there is no error */
     967                 if ( identical(old_version, external_syntax_obj) != 1 )
     968                                 {
     969                   /* if the old version & the new one are not identical */
     970                       old_obj = rpsl_object_init(old_version);
     971                       error_list = rpsl_object_errors(old_obj);
     972                       /***************************** DO SOME ERROR CHECKING / REPORTING HERE ***************/
     973
     974                   result = check_auth(object, old_obj, type, credentials);
     975                   if (result == UP_AUTH_OK)
     976                                   {
     977                     if (tracing)
     978                                         {
     979                       printf("TRACING: Will send the obj to be updated\n");
     980                     }
     981
     982                     generated_obj = rpsl_object_copy(external_syntax_obj);
     983                     if (strcasecmp(type, "key-cert") == 0)
     984                                         {
     985                       get_keyowner_fingerpr(object);/* get keyowner and fingerprint,
     986                                                        save them into global vars  */
     987                       generated_obj_str = UP_generate_kc_attrs(generated_obj);
     988                                       free(external_syntax_results->new_obj);
     989                       external_syntax_results->new_obj = generated_obj_str;
     990                     }
     991
     992                     /* XXX this will be put back when UP_generate_i6_attrs is ready*/
     993                     else if(strcasecmp(type, "inet6num") == 0)
     994                                         {
     995                       generated_obj_str = UP_generate_i6_attrs(generated_obj);
     996                                       free(external_syntax_results->new_obj);
     997                       external_syntax_results->new_obj = generated_obj_str;
     998                     }
     999                     /**/
    1000                     result_from_RIPupd = send_object_db(generated_obj, NULL, "UPD");
    1001
    1002                                 if ( UP_remove_override_attr(object) )
    1003                                   arg2 = rpsl_object_get_text(object,0);
    1004                                         else
    1005                                         {
    1006                                           /* there was an override attr in this object and it has not been removed */
    1007                                           arg2 = (char *)malloc(2);
    1008                                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1009                                         }
    1010
    1011                     if (result_from_RIPupd->result == 0)
    1012                                         {
    1013                       AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
    1014                                     type, get_search_key(object, type));
    1015
    1016                       NT_write_all_ntfs(old_version, arg, external_syntax_results->new_obj, tmpdir, ntfy_hash, forw_hash, cross_hash,
    1017                                         credentials.from);
    1018
    1019                                       rpsl_object_delete(generated_obj);
    1020                                       rpsl_object_delete(old_obj);
    1021                                       rpsl_object_delete(external_syntax_obj);
    1022                       rpsl_object_delete(object);
    1023                                       free(result_from_RIPupd);
    1024                                           free(old_version);
    1025                                       free(external_syntax_results->new_obj);
    1026                                           free(external_syntax_results);
    1027                                       free(arg2);
    1028                       free(arg);
    1029                       return UP_OK;
    1030                     }
    1031                                         else
    1032                                         {
    1033                       AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n%s\n",
    1034                                     type, get_search_key(object, type),
    1035                                     arg2, result_from_RIPupd->error_str);
    1036
    1037                                       rpsl_object_delete(generated_obj);
    1038                                       rpsl_object_delete(old_obj);
    1039                                       rpsl_object_delete(external_syntax_obj);
    1040                       rpsl_object_delete(object);
    1041                                       free(result_from_RIPupd->error_str);
    1042                                       free(result_from_RIPupd);
    1043                                           free(old_version);
    1044                                       free(external_syntax_results->new_obj);
    1045                                           free(external_syntax_results);
    1046                                       free(arg2);
    1047                       free(arg);
    1048                       return UP_INT;
    1049                     }
    1050                   }
    1051                                   else if (result == UP_NAM)
    1052                                   {
    1053                     /* name of a person/role object cannot be changed */
    1054                     if (tracing)
    1055                                         {
    1056                       printf("TRACING: name of a person/role object cannot be changed\n");
    1057                     }
    1058
    1059                                 if ( UP_remove_override_attr(object) )
    1060                                   arg2 = rpsl_object_get_text(object,0);
    1061                                         else
    1062                                         {
    1063                                           /* there was an override attr in this object and it has not been removed */
    1064                                           arg2 = (char *)malloc(2);
    1065                                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1066                                         }
    1067
    1068                     AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n***Error: Name of a person or role object cannot be changed.\n",
    1069                                   type, get_search_key(object, type), arg2);
    1070
    1071                                     rpsl_object_delete(old_obj);
    1072                                     rpsl_object_delete(external_syntax_obj);
    1073                     rpsl_object_delete(object);
    1074                                         free(old_version);
    1075                                     free(external_syntax_results->new_obj);
    1076                                         free(external_syntax_results);
    1077                                     free(arg2);
    1078                     free(arg);
    1079                     return UP_NAM; /* name of a person/role object cannot be changed */
    1080
    1081
    1082                   }
    1083                   else
    1084                                   {
    1085                     /* auth failed ! */
    1086                     if (tracing)
    1087                                         {
    1088                       printf("TRACING: Auth failed\n");
    1089                     }
    1090
    1091                                 if ( UP_remove_override_attr(object) )
    1092                                   arg2 = rpsl_object_get_text(object,0);
    1093                                         else
    1094                                         {
    1095                                           /* there was an override attr in this object and it has not been removed */
    1096                                           arg2 = (char *)malloc(2);
    1097                                           strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1098                                         }
    1099
    1100                     AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
    1101                                   type, get_search_key(object, type), arg2);
    1102
    1103                     NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
    1104
    1105                                     rpsl_object_delete(old_obj);
    1106                                     rpsl_object_delete(external_syntax_obj);
    1107                     rpsl_object_delete(object);
    1108                                         free(old_version);
    1109                                     free(external_syntax_results->new_obj);
    1110                                         free(external_syntax_results);
    1111                                     free(arg2);
    1112                     free(arg);
    1113                     return UP_AUF; /* Auth failed */
    1114                   }
    1115
    1116                 }
    1117                                 else
    1118                                 { /* if the old and new versions of the object are the same */
    1119                   if (tracing)
    1120                                   {
    1121                       printf("TRACING: The obj sent is identical to the one in the DB (NOOP)\n");
    1122                   }
    1123
    1124                   AK_add_to_ack(ack_file_name, "\nUpdate NOOP: [%s] %s\n",
    1125                                     type, get_search_key(object, type));
    1126
    1127                                   rpsl_object_delete(external_syntax_obj);
    1128                   rpsl_object_delete(object);
    1129                               free(old_version);
    1130                                   free(external_syntax_results->new_obj);
    1131                               free(external_syntax_results);
    1132                   free(arg);
    1133                   return UP_OK;
    1134                 }
    1135               }
    1136                           else
    1137                           { /* if there is an error in external syntax checks */
    1138                         if ( UP_remove_override_attr(object) )
    1139                            arg2 = rpsl_object_get_text(object,0);
    1140                                 else
    1141                                 {
    1142                                   /* there was an override attr in this object and it has not been removed */
    1143                                   arg2 = (char *)malloc(2);
    1144                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1145                                 }
    1146
    1147                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s%s\n",
    1148                      type, get_search_key(object, type),
    1149                      arg2, external_syntax_results->error_str);
    1150
    1151                                 rpsl_object_delete(external_syntax_obj);
    1152                 rpsl_object_delete(object);
    1153                             free(old_version);
    1154                                 free(external_syntax_results->new_obj);
    1155                             free(external_syntax_results);
    1156                 free(arg2);
    1157                 free(arg);
    1158                 return UP_SYN;
    1159               }
    1160             }
    1161                         else
    1162                         { /* if the user enforced creation (using NEW keyword) in the subject line */
    1163                   if ( UP_remove_override_attr(object) )
    1164                         arg2 = rpsl_object_get_text(object,0);
    1165                           else
    1166                           {
    1167                                 /* there was an override attr in this object and it has not been removed */
    1168                                 arg2 = (char *)malloc(2);
    1169                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
    1170                           }
    1171
    1172               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\n%s\n"
    1173                    "***Error:  Object already exists\n",
    1174                    type, get_search_key(object, type), arg2),
    1175
    1176               rpsl_object_delete(object);
    1177                           free(old_version);
    1178               free(arg2);
    1179               free(arg);
    1180               return UP_INT;
    1181
    1182             }
    1183           }  /* end of this is an update operation */
    1184                   else
    1185                   { /* old_version  == NULL, so, creation */
    1186                     external_syntax_obj = rpsl_object_copy(object);
    1187             external_syntax_results = UP_check_external_syntax(external_syntax_obj);
    1188             if (    external_syntax_results->result != UP_EXTSYN_ERR
    1189                  && external_syntax_results->result != UP_EXTSYN_ERR_WARN)
    1190                         {
    1191                           /* if there is no error */
    1192               result = check_auth(object, NULL, type, credentials);
    1193               if (result == UP_AUTH_OK)
    1194                           {
    1195                 if (tracing)
    1196                                 {
    1197                   printf("TRACING: Will send the obj to be added\n");
    1198                 }
    1199                  /* if the object is a key-cert object, then we must import the PGP key */
    1200                 if ( strcmp(type, "key-cert") == 0 )
    1201                                 {
    1202                   result_from_import_key = import_key(object);
    1203                 }
    1204                                 else
    1205                                 {
    1206                   result_from_import_key = NULL;
    1207                 }
    1208                 if (result_from_import_key == NULL)
    1209                                 {
    1210                                   /* no PGP problem */
    1211                                   generated_obj = rpsl_object_copy(external_syntax_obj);
    1212                   if (strcasecmp(type, "key-cert") == 0)
    1213                                   {
    1214                                     /* if the object is a key-cert object */
    1215                     generated_obj_str = UP_generate_kc_attrs(generated_obj);
    1216                                     free(external_syntax_results->new_obj);
    1217                     external_syntax_results->new_obj = generated_obj_str;
    1218                   }
    1219                   else if(strcasecmp(type, "inet6num") == 0)
    1220                                   {
    1221                                     /* if the object is an inet6num object */
    1222                     generated_obj_str = UP_generate_i6_attrs(generated_obj);
    1223                                     free(external_syntax_results->new_obj);
    1224                     external_syntax_results->new_obj = generated_obj_str;
    1225                   }
    1226                   result_from_RIPupd = send_object_db(generated_obj, NULL, "ADD");
    1227
    1228                   if (result_from_RIPupd->result == 0)
    1229                                   {
    1230                                     /* if there was no problem */
    1231                     AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n",
    1232                                   type, get_search_key(object, type));
    1233
    1234                      NT_write_all_ntfs(NULL, arg, external_syntax_results->new_obj, tmpdir,
    1235                                                            ntfy_hash, forw_hash, cross_hash, credentials.from);
    1236
    1237                                     rpsl_object_delete(generated_obj);
    1238                                     rpsl_object_delete(external_syntax_obj);
    1239                     rpsl_object_delete(object);
    1240                                     free(result_from_RIPupd);
    1241                                     free(external_syntax_results->new_obj);
    1242                                         free(external_syntax_results);
    1243                     free(arg);
    1244                     return UP_OK;
    1245
    1246                   }
    1247                                   else
    1248                                   {
    1249                     AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
    1250                                   type, get_search_key(object, type),
    1251                                   result_from_RIPupd->error_str);
    1252
    1253                                     rpsl_object_delete(generated_obj);
    1254                                     rpsl_object_delete(external_syntax_obj);
    1255                     rpsl_object_delete(object);
    1256                                     free(result_from_RIPupd->error_str);
    1257                                     free(result_from_RIPupd);
    1258                                     free(external_syntax_results->new_obj);
    1259                                         free(external_syntax_results);
    1260                     free(arg);
    1261                     return UP_INT;
    1262                   }
    1263                 }
    1264                                 else
    1265                                 {
    1266                                   /* there was a problem with PGP key import */
    1267                   AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n",
    1268                                   type, get_search_key(object, type),
    1269                                   result_from_import_key);
    1270
    1271                                   rpsl_object_delete(external_syntax_obj);
    1272                   rpsl_object_delete(object);
    1273                   free(result_from_import_key);
    1274                                   free(external_syntax_results->new_obj);
    1275                                   free(external_syntax_results);
    1276                   free(arg);
    1277                   return UP_INT;
    1278                 }
    1279               }
    1280                           else if (result == UP_FWD)
    1281                           {
    1282                             /* this was a maintainer or as-block creation request, so
    1283                    forward it to <HUMAILBOX> */
    1284                 if (tracing)
    1285                                 {
    1286                   printf("TRACING: Maintainer or as-block or irt request will be forwarded to <HUMAILBOX>\n");
    1287                 }
    1288
    1289                         if ( UP_remove_override_attr(object) )
    1290                           arg2 = rpsl_object_get_text(object,0);
    1291                                 else
    1292                                 {
    1293                                   /* there was an override attr in this object and it has not been removed */
    1294                                   arg2 = (char *)malloc(2);
    1295                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1296                                 }
    1297
    1298                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s\n"
    1299                               "***Error:     %s objects cannot be created automatically\n"
    1300                               "***Error:     This object has been forwarded to %s\n"
    1301                               "***Error:     for authorisation.\n"
    1302                               "***Error:     No further action from your part is required\n",
    1303                               type, get_search_key(object, type),
    1304                               arg2, type, humailbox);
    1305
    1306                 if ( ! strcmp(type, "mntner") )
    1307                 {
    1308                   header_type = strdup("Maintainer");
    1309                   text_type = strdup("maintainer");
    1310                 }
    1311                 else if ( ! strcmp(type, "as-block") )
    1312                 {
    1313                   header_type = strdup("as-block");
    1314                   text_type = strdup("as-block");
    1315                 }
    1316                 else if ( ! strcmp(type, "irt") )
    1317                 {
    1318                   header_type = strdup("irt");
    1319                   text_type = strdup("irt");
    1320                 }
    1321                 else
    1322                 {
    1323                   header_type = strdup("");
    1324                   text_type = strdup("");
    1325                 }
    1326
    1327                 /* and forward this creation request to <HUMAILBOX> */
    1328                 NT_forw_create_req(external_syntax_results->new_obj);
    1329
    1330                                 rpsl_object_delete(external_syntax_obj);
    1331                 rpsl_object_delete(object);
    1332                                 free(external_syntax_results->new_obj);
    1333                                 free(external_syntax_results);
    1334                                 free(arg2);
    1335                 free(arg);
    1336                 free(header_type);
    1337                 free(text_type);
    1338                 return UP_AUF;
    1339               }
    1340                           else if (result == UP_HOF)
    1341                           {
    1342                             /* hierarchical authorisation failed */
    1343                 if (tracing)
    1344                                 {
    1345                   printf("TRACING: Auth failed\n");
    1346                 }
    1347
    1348                         if ( UP_remove_override_attr(object) )
    1349                           arg2 = rpsl_object_get_text(object,0);
    1350                                 else
    1351                                 {
    1352                                   /* there was an override attr in this object and it has not been removed */
    1353                                   arg2 = (char *)malloc(2);
    1354                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1355                                 }
    1356
    1357                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nHierarchical authorisation failed, request forwarded to maintainer.\n%s\n",
    1358                               type, get_search_key(object, type), arg2);
    1359
    1360                 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
    1361
    1362                                 rpsl_object_delete(external_syntax_obj);
    1363                 rpsl_object_delete(object);
    1364                                 free(external_syntax_results->new_obj);
    1365                                 free(external_syntax_results);
    1366                                 free(arg2);
    1367                 free(arg);
    1368                 return UP_AUF;
    1369               }
    1370                           else
    1371                           {
    1372                 /* auth failed ! */
    1373                 if (tracing)
    1374                                 {
    1375                   printf("TRACING: Auth failed\n");
    1376                 }
    1377
    1378                         if ( UP_remove_override_attr(object) )
    1379                           arg2 = rpsl_object_get_text(object,0);
    1380                                 else
    1381                                 {
    1382                                   /* there was an override attr in this object and it has not been removed */
    1383                                   arg2 = (char *)malloc(2);
    1384                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1385                                 }
    1386
    1387                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
    1388                               type, get_search_key(object, type), arg2);
    1389
    1390                 NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
    1391
    1392                                 rpsl_object_delete(external_syntax_obj);
    1393                 rpsl_object_delete(object);
    1394                                 free(external_syntax_results->new_obj);
    1395                                 free(external_syntax_results);
    1396                                 free(arg2);
    1397                 free(arg);
    1398                 return UP_AUF; /* Auth failed */
    1399               }
    1400             }
    1401                         else
    1402                         {
    1403                   if ( UP_remove_override_attr(object) )
    1404                         arg2 = rpsl_object_get_text(object,0);
    1405                           else
    1406                           {
    1407                                 /* there was an override attr in this object and it has not been removed */
    1408                                 arg2 = (char *)malloc(2);
    1409                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
    1410                           }
    1411
    1412               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\n%s%s\n",
    1413                               type, get_search_key(object, type),
    1414                               arg2, external_syntax_results->error_str);
    1415
    1416                           rpsl_object_delete(external_syntax_obj);
    1417               rpsl_object_delete(object);
    1418                           free(external_syntax_results->new_obj);
    1419                           free(external_syntax_results);
    1420                           free(arg2);
    1421               free(arg);
    1422               return UP_SYN;
    1423             }
    1424           }  /* end of creation */
    1425         }  /* end of process object without an AUTO NIC hdl */
    1426       }  /* end of the object is _not_ to be deleted */
    1427     }  /* end of parsed with no systax errors */
    1428         else
    1429         {
    1430             /* even if obj doesn't parse properly, it may be a legacy object
    1431             which the user wants to delete... */
    1432        if (tracing)
    1433            {
    1434          printf("TRACING: Object didn't parse, check for legacy object deletion\n");
    1435        }
    1436        /* if it is for deletion */
    1437        if (rpsl_object_is_deleted(object))
    1438            {
    1439          /* here delete it */
    1440          type = rpsl_object_get_class(object);
    1441          old_version = get_old_version(object, arg);
    1442
    1443                  if (tracing)
    1444                  {
    1445            printf("TRACING: old_version: [\n%s]\n arg: [\n%s]\n", old_version, arg);
    1446                  }
    1447
    1448          if (old_version == NULL)
    1449                  {
    1450                    /* the object doesn't exist in the db! */
    1451                    free(arg);
    1452            if ( UP_remove_override_attr(object) )
    1453                  arg = rpsl_object_get_text(object,0);
    1454                    else
    1455                    {
    1456                          /* there was an override attr in this object and it has not been removed */
    1457                          arg = (char *)malloc(2);
    1458                          strcpy(arg, "");       /* Don't include object in ack/notif msgs */
    1459                    }
    1460
    1461            AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n***Error: Entry not found\n\n%s\n",
    1462                           type, get_search_key(object, type), arg);
    1463
    1464            rpsl_object_delete(object);
    1465            free(arg);
    1466            return UP_NSO; /* no such object */
    1467          }
    1468                  else
    1469                  {
    1470
    1471                         if (tracing)
    1472                         {
    1473                   printf("TRACING: legacy object is in the database\n");
    1474                         }
    1475
    1476                     /* the object is in the db */
    1477             if ( identical(old_version, object) )
    1478                         {
    1479                           /* if the old & new versions are identical */
    1480
    1481                           if (tracing)
    1482                           {
    1483                         printf("TRACING: old & new versions are identical\n");
    1484                           }
    1485               result = check_auth(NULL, object, type, credentials);
    1486               if (result == UP_AUTH_OK)
    1487                           {
    1488                 if (tracing)
    1489                                 {
    1490                   printf("TRACING: Will send the obj to be deleted\n");
    1491                 }
    1492                 if (strcmp(type, "key-cert") == 0)
    1493                                 {
    1494                   result_from_delete_key = delete_key(object);
    1495                 }
    1496                                 else
    1497                                 {
    1498                   result_from_delete_key = NULL;
    1499                 }
    1500                 /* if there was no problem with key deletion from the key-ring */
    1501                 if (result_from_delete_key == NULL)
    1502                                 {
    1503                   result_from_RIPupd = send_object_db(object, NULL, "DEL");
    1504                   if (result_from_RIPupd->result == 0)
    1505                                   {
    1506                     AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n",
    1507                                   type, get_search_key(object, type));
    1508                     NT_write_all_ntfs(old_version, NULL, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash,
    1509                                       credentials.from);
    1510
    1511                         rpsl_object_delete(object);
    1512                                         free(result_from_RIPupd);
    1513                         free(arg);
    1514                                 free(old_version);
    1515                     return UP_OK;
    1516                   }
    1517                                   else
    1518                                   {
    1519                     AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
    1520                                   type, get_search_key(object, type),
    1521                                   result_from_RIPupd->error_str);
    1522
    1523                         rpsl_object_delete(object);
    1524                                     free(result_from_RIPupd->error_str);
    1525                                         free(result_from_RIPupd);
    1526                         free(arg);
    1527                                 free(old_version);
    1528                     return UP_INT;
    1529                   }
    1530                 }
    1531                                 else
    1532                                 {
    1533                    AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\n%s\n",
    1534                                   type, get_search_key(object, type), result_from_delete_key);
    1535
    1536                    rpsl_object_delete(object);
    1537                    free(arg);
    1538                            free(old_version);
    1539                    free(result_from_delete_key);
    1540                    return UP_INT;
    1541                 }
    1542               }
    1543                           else
    1544                           { /* auth failed */
    1545                 if (tracing)
    1546                                 {
    1547                   printf("TRACING: Auth failed\n");
    1548                 }
    1549
    1550                         if ( UP_remove_override_attr(object) )
    1551                           arg2 = rpsl_object_get_text(object,0);
    1552                                 else
    1553                                 {
    1554                                   /* there was an override attr in this object and it has not been removed */
    1555                                   arg2 = (char *)malloc(2);
    1556                                   strcpy(arg2, "");     /* Don't include object in ack/notif msgs */
    1557                                 }
    1558
    1559                 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuthorisation failed, request forwarded to maintainer.\n%s\n",
    1560                               type, get_search_key(object, type), arg2);
    1561                 NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
    1562
    1563                 rpsl_object_delete(object);
    1564                 free(arg2);
    1565                 free(arg);
    1566                         free(old_version);
    1567                 return UP_AUF; /* Auth failed */
    1568               }
    1569             }  /* end of identical match */
    1570                         else
    1571                         {
    1572                           /* the new & old versions do not match */
    1573                   if ( UP_remove_override_attr(object) )
    1574                         arg2 = rpsl_object_get_text(object,0);
    1575                           else
    1576                           {
    1577                                 /* there was an override attr in this object and it has not been removed */
    1578                                 arg2 = (char *)malloc(2);
    1579                                 strcpy(arg2, "");       /* Don't include object in ack/notif msgs */
    1580                           }
    1581
    1582               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s \n***Error: new & old versions do not match\n%s\n",
    1583                               type, get_search_key(object, type), arg2);
    1584
    1585               rpsl_object_delete(object);
    1586               free(arg2);
    1587                       free(arg);
    1588                       free(old_version);
    1589               return UP_NOM; /* new & old versions do not match */
    1590             }
    1591           }  /* end of the object is in the db */
    1592        } /* end of the object is to be deleted */
    1593            else
    1594            {
    1595              /* syntax error AND not deletion */
    1596                  noclass = 0;
    1597                  for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
    1598                  {
    1599                    ecode = ((rpsl_error_t *)(error_list_item->data))->code;
    1600            if ( ecode == RPSL_ERR_ONLYCOMMENTS || ecode == RPSL_ERR_BADCLASS
    1601                          || ecode == RPSL_ERR_BADCLASS )
    1602                    {
    1603                      noclass = 1;
    1604                          break;
    1605                    }
    1606                  }
    1607          if ( UP_remove_override_attr(object) )
    1608            arg2 = rpsl_object_get_text(object,0);
    1609                  else
    1610                  {
    1611                    /* there was an override attr in this object and it has not been removed */
    1612                    arg2 = (char *)malloc(2);
    1613                    strcpy(arg2, "");    /* Don't include object in ack/notif msgs */
    1614                  }
    1615
    1616 /*               if ( ! noclass )
    1617                  {
    1618            type = rpsl_object_get_class(object);
    1619                    key = get_search_key(object, type);
    1620            AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s \n***Error: Syntax error in object\n",
    1621                               type, key ? key : "" );
    1622                  }
    1623                  else */
    1624            AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
    1625
    1626          if ( rpsl_object_has_error(object, RPSL_ERRLVL_CRIT) )
    1627                  {
    1628                    /* object not parsed so print out text version of object rather than attributes */
    1629                    AK_add_to_ack(ack_file_name, "%s\n", arg);
    1630          }
    1631          else
    1632                  {
    1633                    /* add attributes along with any attribute error messages */
    1634                    attr_list = rpsl_object_get_all_attr(object);
    1635                    for ( attr_list_item = attr_list; attr_list_item != NULL; attr_list_item = g_list_next(attr_list_item) )
    1636                    {
    1637                          name = rpsl_attr_get_name( (rpsl_attr_t *)(attr_list_item->data) );
    1638                          if ( strcasecmp(name, "override") != 0 )
    1639                          {
    1640                        /* don't include the override attibute, but still include override error messages */
    1641                        value = rpsl_attr_get_value( (rpsl_attr_t *)(attr_list_item->data) );
    1642                        attribute = (char *)malloc( strlen(name) + strlen(value) + 3);
    1643                        sprintf(attribute, "%s: %s", name, value);
    1644                AK_add_to_ack(ack_file_name, "%s\n", attribute);
    1645                        free(attribute);
    1646                          }
    1647                          attr_error_list = rpsl_attr_errors( (rpsl_attr_t *)(attr_list_item->data) );
    1648                          for ( attr_error_list_item = attr_error_list; attr_error_list_item != NULL; attr_error_list_item = g_list_next(attr_error_list_item) )
    1649                          {
    1650                        if ( ((rpsl_error_t *)(attr_error_list_item->data))->level > RPSL_ERRLVL_DEBUG )
    1651                  AK_add_to_ack(ack_file_name, "***Error: %s\n", ((rpsl_error_t *)(attr_error_list_item->data))->descr);
    1652                          }
    1653                    }
    1654          }
    1655
    1656          /* now add any object level error messages */
    1657                  error_list = rpsl_object_errors(object);
    1658                  for ( error_list_item = error_list; error_list_item != NULL; error_list_item = g_list_next(error_list_item) )
    1659                  {
    1660                    if ( ((rpsl_error_t *)(error_list_item->data))->level > RPSL_ERRLVL_DEBUG &&
    1661                          ((rpsl_error_t *)(error_list_item->data))->code != RPSL_ERR_BADATTR )
    1662                    {
    1663              AK_add_to_ack(ack_file_name, "***Error: %s\n", ((rpsl_error_t *)(error_list_item->data))->descr);
    1664                    }
    1665                  }
    1666
    1667          AK_add_to_ack(ack_file_name, "\n");
    1668
    1669          rpsl_object_delete(object);
    1670                  free(arg);
    1671          return UP_SYN; /* syntax error */
    1672        }
    1673     }
    1674 }
    1675
    1676
    1677
    1678
    1679
    1680 /* processes the objects in the given file */
    1681 void process_file(char * filename, credentials_struct credentials,
         /* [<][>][^][v][top][bottom][index][help] */
    1682                   GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name,
    1683                   GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash)
    1684 {
    1685 FILE * input_file;
    1686 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;
    1687 GSList *next = NULL;
    1688 int object_count = 0;
    1689 char *object = NULL;
    1690 char * line;
    1691 char * lwrcase_line;
    1692 int result = 0;
    1693 rpsl_object_t *obj = NULL;
    1694 const GList * error_list = NULL;
    1695
    1696
    1697     line = (char *)malloc(1024);
    1698
    1699     if ((input_file = fopen(filename, "r")) == NULL)
    1700         {
    1701         ER_perror(FAC_UP, UP_CANTOPEN, "Couldn't open the file %s: %s\n", filename, strerror(errno));
    1702         exit(1);
    1703     }
    1704
    1705     while (fgets(line, 1024, input_file) != NULL)
    1706         {
    1707       /* first, if it is a pasword, save it, but do not regard it as an attrib */
    1708       lwrcase_line = strdup(line);
    1709       g_strdown(lwrcase_line);
    1710       if (strstr(lwrcase_line, "password:") == lwrcase_line)
    1711           {
    1712         if (tracing)
    1713                 {
    1714           printf("TRACING: This is a password\n");
    1715         }
    1716         credentials.password_list = g_slist_append(credentials.password_list,
    1717                                       g_strstrip(strdup(line + strlen("password:"))));
    1718         free(lwrcase_line);
    1719         continue;
    1720       }
    1721       free(lwrcase_line);
    1722
    1723       line = UP_remove_EOLs(line); /* remove '\n's and '\r' first */
    1724       /* remove trailing white space */
    1725       line = g_strchomp(line);
    1726       if (strlen(line) == 0)
    1727           {
    1728             /* then, this was an empty line */
    1729         if (object != NULL)
    1730                 {
    1731            list_of_objects = g_slist_append(list_of_objects, object);
    1732            if (tracing)
    1733                    {
    1734              printf("TRACING: added an object: [%s]\n", object);
    1735            }
    1736            object = NULL;
    1737         }
    1738       }
    1739           else
    1740           {
    1741         if (object == NULL && strlen(line) != 0)
    1742                 {
    1743           object = (char *)malloc(strlen(line) + 2);
    1744           object = strcpy(object, line);
    1745           object = strcat(object, "\n"); /* add EOL again (we removed it before) */
    1746         }
    1747         else
    1748                 {
    1749           object = (char *)realloc(object, strlen(object) + strlen(line) + 2);
    1750           object = strcat(object, line);
    1751           object = strcat(object, "\n");
    1752         }
    1753       }
    1754
    1755     }
    1756     fclose(input_file);
    1757         free(line);
    1758
    1759     /* now, if at the very and of the input file there wasn't an
    1760        empty line, we have to add the remaining object in the 'object'
    1761        variable */
    1762     if (object != NULL)
    1763         {
    1764        list_of_objects = g_slist_append(list_of_objects, object);
    1765        object = NULL;
    1766     }
    1767
    1768
    1769     if (tracing)
    1770         {
    1771        printf("TRACING: Will process the objects in the list\n");
    1772     }
    1773     next = list_of_objects;
    1774     object_count = 0;
    1775     for ( next = list_of_objects; next != NULL ; next = g_slist_next(next) )
    1776         {
    1777       if (UP_is_object((char *)next->data))
    1778           {
    1779             /* if this looks like an object */
    1780
    1781         object_count++;
    1782         if(tracing)
    1783                 {
    1784           printf("TRACING: Got an object from the list\n");
    1785           printf("[%s]\n", (char *)next->data );
    1786         }
    1787
    1788             obj = rpsl_object_init( (char *)next->data );
    1789             error_list = rpsl_object_errors(obj);
    1790
    1791         if ( ! rpsl_object_has_error(obj, RPSL_ERRLVL_ERROR) && has_ref_to_AUTO_nic_hdl(obj) )
    1792                 {
    1793                   /* if object has a reference to an auto- nichdl and no syntax errors
    1794                      then defer the processing to allow the auto- nichdl to be created first */
    1795           if(tracing)
    1796                   {
    1797             printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
    1798           }
    1799           list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
    1800         }
    1801                 else
    1802                 {
    1803           result = 0;
    1804           result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
    1805                                    ntfy_hash, forw_hash, cross_hash);
    1806           /* keep a tally */
    1807           if (result == UP_NOOBJECT)
    1808                   {
    1809                     /* do nothing and don't increment any counts */
    1810                   }
    1811           else if (result == UP_OK)
    1812                   {
    1813             count_successful++;
    1814           }
    1815                   else
    1816                   {
    1817             count_unsuccessful++;
    1818           }
    1819          }
    1820
    1821         rpsl_object_delete(obj);
    1822       }
    1823           else
    1824           {
    1825             /* this does not look like an object (a signature? some other text?) */
    1826
    1827         AK_add_to_ack(ack_file_name, "\nThe following paragraph does not look like an object,\n"
    1828                                      "so ignoring it:\n%s\n", (char *)next->data);
    1829       }
    1830     }
    1831
    1832
    1833     if (tracing)
    1834         {
    1835       printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
    1836       printf("TRACING: will start to process the second list\n");
    1837     }
    1838
    1839     for ( next = list_of_objects2; next != NULL ; next = g_slist_next(next) )
    1840         {
    1841       if (tracing)
    1842           {
    1843         printf("TRACING: Will process object: %s\n", (char *)next->data);
    1844       }
    1845       result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
    1846                                ntfy_hash, forw_hash, cross_hash);
    1847       /* keep a tally */
    1848       if (result == UP_NOOBJECT)
    1849           {
    1850                 /* do nothing and don't increment any counts */
    1851           }
    1852       else if (result == UP_OK)
    1853           {
    1854         count_successful++;
    1855       }
    1856           else
    1857           {
    1858         count_unsuccessful++;
    1859       }
    1860     }
    1861 }/* process_file */
    1862
    1863
    1864
    1865
    1866 /*  Generates a unique file name and returns the full path of the filename
    1867     for storing notification message.  */
    1868
    1869 char * generate_upd_file()
         /* [<][>][^][v][top][bottom][index][help] */
    1870 {
    1871    char * name;
    1872
    1873    /* allocate space for name.  32 should be enough for PID */
    1874    name = (char*)malloc(strlen(tmpdir) + strlen("/dbupdate-tmp.") + 34 );
    1875
    1876    sprintf(name, "%s/dbupdate-tmp.%i", tmpdir, pid /*getpid()*/);
    1877
    1878    return name;
    1879 }
    1880
    1881
    1882 /* create_lock_file: creates a lock file in lockdir and locks it. This is a
    1883    part of crash recovery. Must be called in the beginning of the run. At the
    1884    end, the file must be removed. */
    1885 /* The idea: Create the "lock" file, and lock it. When another process starts
    1886    running, it checks the existing lock files. If some exists, then it checks
    1887    if it is locked or not. It not locked, then assumes that the corresponding
    1888    dbupdate is alredy running. If not locked, assumes that it has crashed.
    1889    (note: when a process crashes, the kernel releases all the files locked by
    1890    this process [by the OS])
    1891    Problem: locking doesn't work properly on some NFS implementations. */
    1892
    1893 lockfilestruct create_lock_file(){
         /* [<][>][^][v][top][bottom][index][help] */
    1894
    1895   lockfilestruct lock;
    1896   int file;
    1897   int length;
    1898
    1899   /* allocate space for file name */
    1900   length = strlen(lockdir) +  strlen(hostname) + 32;
    1901   lock.lockname = (char *)malloc(length + 1);
    1902
    1903   snprintf(lock.lockname, length, "%s/dbupdate.%s.%ld", lockdir, hostname, pid /*getpid()*/);
    1904
    1905   /* we will lock the file, so we have to use open(), but not fopen() (see man
    1906      page of lockf(3C)) */
    1907   if(( file = open(lock.lockname, O_RDWR|O_CREAT)) == -1){
    1908     ER_perror(FAC_UP, UP_CANTOPEN, "Can't open lock file, %s", lock.lockname);
    1909     exit(1);
    1910   }
    1911
    1912   if(lockf(file, F_LOCK, 0) == -1){
    1913     ER_perror(FAC_UP, UP_CANTLOCK, "Can't lock the file, %s", lock.lockname);
    1914     exit(1);
    1915   };
    1916
    1917   lock.filedes = file;
    1918
    1919   return lock;
    1920
    1921 }
    1922
    1923
    1924
    1925
    1926
    1927 /* remove_lock_file(): unlocks and removes the file  */
    1928 void remove_lock_file(lockfilestruct lockfile){
         /* [<][>][^][v][top][bottom][index][help] */
    1929
    1930   close(lockfile.filedes); /* this will remove the lock at the same time */
    1931   unlink(lockfile.lockname);
    1932
    1933 }
    1934
    1935
    1936
    1937 /* writes the checkpoint file with the specified state */
    1938 void write_checkpoint(int state){
         /* [<][>][^][v][top][bottom][index][help] */
    1939
    1940   char * filename;
    1941   char * tmpfilename;
    1942   int length;
    1943   FILE * file;
    1944
    1945   if(tracing){
    1946     printf("TRACING: write_checkpoint, state=[%i]\n", state);
    1947   }
    1948   length = strlen(lockdir) +  strlen(hostname) + 64;
    1949   filename    = (char *)malloc(length + 1);
    1950   tmpfilename = (char *)malloc(length + 5);
    1951
    1952   snprintf(filename,    length, "%s/dbupdate.checkpoint.%s.%ld",     lockdir, hostname, pid );
    1953   snprintf(tmpfilename, length, "%s/dbupdate.checkpoint.%s.%ld.tmp", lockdir, hostname, pid );
    1954
    1955   if(( file = fopen(tmpfilename, "w")) == NULL){
    1956     /* fprintf(stderr, "Can't open temp checkpoint file, %s", tmpfilename); */
    1957     ER_perror(FAC_UP, UP_CANTOPEN, "Can't open temp checkpoint file, %s", tmpfilename);
    1958     exit(1);
    1959   }
    1960
    1961   fprintf(file, "[STATE]\n%i\n", state);
    1962
    1963   fprintf(file, "[FLAGS]\n");
    1964   /* should print the flags here */
    1965
    1966   fprintf(file, "[PARTS]\n");
    1967   /* should print the parts (filenames) here */
    1968
    1969   fprintf(file, "[OBJECTS1]\n");
    1970
    1971   fprintf(file, "[OBJECTS2]\n");
    1972
    1973   fprintf(file, "[ACKFILE]\n");
    1974
    1975   fprintf(file, "[NOTIFFILES]\n");
    1976
    1977   fprintf(file, "[TIDS1]\n");
    1978
    1979   fprintf(file, "[TIDS2]\n");
    1980
    1981   fprintf(file, "[NICHDLHASH]\n");
    1982
    1983   fprintf(file, "[CURRENTOBJECT]\n");
    1984
    1985   fprintf(file, "[CURRENTPART]\n");
    1986
    1987
    1988   fclose(file);
    1989
    1990   rename(tmpfilename, filename);
    1991
    1992   /* free the char *'s */
    1993   free(tmpfilename);
    1994   free(filename);
    1995
    1996 }
    1997
    1998
    1999
    2000
    2001 /* removes check point file */
    2002 void remove_checkpoint(){
         /* [<][>][^][v][top][bottom][index][help] */
    2003
    2004   char * filename;
    2005   int length;
    2006
    2007   if(tracing){
    2008     printf("TRACING: remove_checkpoint\n");
    2009   }
    2010
    2011   length = strlen(lockdir) +  strlen(hostname) + 64;
    2012   filename    = (char *)malloc(length + 1);
    2013
    2014   snprintf(filename,    length, "%s/dbupdate.checkpoint.%s.%ld",     lockdir, hostname, pid );
    2015
    2016   unlink(filename);
    2017
    2018   /* free the char * */
    2019   free(filename);
    2020
    2021 }
    2022
    2023
    2024
    2025
    2026 /* main */
    2027 int main(int argc, char **argv, char **envp){
         /* [<][>][^][v][top][bottom][index][help] */
    2028   /* init_and_set_options(argc, argv, envp); */
    2029
    2030   int i,j;
    2031   char ** temp_vector;
    2032   char * temp;
    2033   char * temp_upd_file = NULL;
    2034   char *input_file_name = NULL;
    2035   GHashTable *AUTO_NIC_hdl_hash;
    2036   credentials_struct credentials;
    2037   FILE * upd_file;
    2038   char c;
    2039   char * mheader_replaced = NULL;
    2040   char * mailtxt_replaced = NULL;
    2041
    2042   /* temp variables to read from conf */
    2043   ca_updDbSource_t *upd_source_hdl;
    2044
    2045   GHashTable *ntfy_hash, *forw_hash, *cross_hash;
    2046
    2047
    2048   char * ack_file_name;
    2049   char *config_file_name = NULL;
    2050
    2051
    2052   /* to use EP module */
    2053   EP_Mail_DescrPtr p;
    2054   EPTokenPtr pt;
    2055   EPTokenPtr list_item;
    2056   EPTokenKeysPtr ptk;
    2057
    2058   char * temp_keyid;
    2059
    2060   /* a variable to be used to know if the part is pgp_signed or not */
    2061   int pgp_signed = 0;
    2062
    2063   int ch;
    2064   char * to_address = NULL;
    2065   char * subject = NULL;
    2066   char * reply_to = NULL;
    2067
    2068
    2069   /* create notification hashes */
    2070   ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
    2071   forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
    2072   cross_hash = g_hash_table_new(g_str_hash, g_str_equal);
    2073
    2074   credentials.password_list = NULL;
    2075   credentials.from = NULL;
    2076
    2077   AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);
    2078
    2079   /* initialise the rpsl dictionary */
    2080   rpsl_load_dictionary(RPSL_DICT_FRONT_END);
    2081
    2082   while ((ch = getopt(argc, argv, "MtSTf:c:sn")) != -1){
    2083           switch(ch) {
    2084           case 'M':
    2085                   reading_from_mail = 1;
    2086                   break;
    2087           case 'f':
    2088                   input_file_name = strdup(optarg);
    2089                   break;
    2090           case 'c':
    2091                   config_file_name = strdup(optarg);
    2092                   break;
    2093           case 't':
    2094                   tracing = 1;
    2095                   break;
    2096           /* Test mode? In test mode, creation of mntners and as-blocks is possible, without overriding */
    2097           case 'T':
    2098                   test_mode = 1;
    2099                   break;
    2100           /* Supress acks and notifications? If yes, the acks and notifs will go to DEFMAIL config var */
    2101           case 'S':
    2102                   supress_ack_notif = 1;
    2103                   break;
    2104           /* Print out the ack to stdout? */
    2105           case 's':
    2106                   print_out_ack = 1;
    2107                   break;
    2108           /* are we processing networkupdate? (invoked via inetd) */
    2109           case 'n':
    2110                   networkupdate = 1;
    2111                   break;
    2112           case '?':
    2113           default:
    2114                   printf("Unknown option\n"); exit(1);
    2115           }
    2116   }
    2117
    2118
    2119   /* config stuff */
    2120   /* if -c flag is given, use the named file as config file, otherwise use
    2121      default filename */
    2122   if ( config_file_name != NULL)
    2123   {
    2124     /*ca_readConfig(config_file_name, confVars, VARS);*/
    2125     ca_init(config_file_name);
    2126         free(config_file_name);
    2127   }
    2128   else
    2129   {
    2130     /*ca_readConfig("dbupdate.conf", confVars, VARS);*/
    2131     ca_init("dbupdate.conf");
    2132   }
    2133
    2134   error_init(argc, argv);
    2135
    2136
    2137   tmpdir = ca_get_tmpdir;
    2138   tmpdir = g_strstrip(tmpdir);
    2139   lockdir = ca_get_lockdir;
    2140   mailcmd = ca_get_mailcmd;
    2141   mailcmd = g_strstrip(mailcmd);
    2142   notitxt = ca_get_notitxt;
    2143   mailtxt = ca_get_mailtxt;
    2144   successtxt = ca_get_successtxt;
    2145   failuretxt = ca_get_failuretxt;
    2146   helpheader = ca_get_helpheader;
    2147   defmail = ca_get_defmail; defmail = UP_remove_EOLs(defmail);
    2148   crosslog = ca_get_crosslog;
    2149   fwtxt = ca_get_fwtxt;
    2150   acksig = ca_get_acksig;
    2151   humailbox = ca_get_humailbox;
    2152   humailbox = g_strstrip(humailbox);
    2153   autobox = ca_get_autobox;
    2154   overridecryptedpw = ca_get_overridecryptedpw;
    2155   overridecryptedpw = g_strstrip(overridecryptedpw);
    2156   updlog = ca_get_updlog;
    2157   acklog = ca_get_acklog;
    2158   notiflog = ca_get_notiflog;
    2159   notimailtxt = ca_get_notimailtxt;
    2160   notinetworktxt = ca_get_notinetworktxt;
    2161   forwlog = ca_get_forwlog;
    2162   fwmailtxt = ca_get_fwmailtxt;
    2163   mtfwheader = ca_get_mtfwheader;
    2164   mtfwtxt = ca_get_mtfwtxt;
    2165   country = ca_get_country;
    2166   pgppath = ca_get_pgppath;
    2167   gpgcmd = ca_get_gpgcmd;
    2168   autodbmhelp = ca_get_autodbmhelp;
    2169   allocmnt = ca_get_allocmnt; allocmnt = UP_remove_EOLs(allocmnt);
    2170   /* convert all '\t's, '\n's and '\r's in allocmnt to white spaces */
    2171   for(i=0;i<strlen(allocmnt);i++){
    2172     if(allocmnt[i] == '\r' || allocmnt[i] == '\n' || allocmnt[i] == '\t'){
    2173       allocmnt[i] = ' ';
    2174     }
    2175   }
    2176   cn_subject_add = ca_get_cn_subject_add; cn_subject_add = UP_remove_EOLs(cn_subject_add);
    2177   cn_subject_del = ca_get_cn_subject_del; cn_subject_del = UP_remove_EOLs(cn_subject_del);
    2178   cn_explain_add = ca_get_cn_explain_add;
    2179   cn_explain_del = ca_get_cn_explain_del;
    2180   cn_overlap_add = ca_get_cn_overlap_add;
    2181   cn_overlap_del = ca_get_cn_overlap_del;
    2182   cno_subject_add = ca_get_cno_subject_add; cno_subject_add = UP_remove_EOLs(cno_subject_add);
    2183   cno_subject_del = ca_get_cno_subject_del; cno_subject_del = UP_remove_EOLs(cno_subject_del);
    2184   cno_explain_add = ca_get_cno_explain_add;
    2185   cno_explain_del = ca_get_cno_explain_del;
    2186   cno_overlap_add = ca_get_cno_overlap_add;
    2187   cno_overlap_del = ca_get_cno_overlap_del;
    2188   copyright_notice = ca_get_pw_resp_header;
    2189   mheader = ca_get_mheader;
    2190   pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
    2191   sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
    2192   if(test_mode != 1){/* if it is not already set to 1 (from command line), read from config */
    2193
    2194     test_mode = ca_get_testmode;
    2195   }
    2196   /* retrieve source variables */
    2197   upd_source_hdl = ca_get_UpdSourceHandle(CA_UPDSOURCE);
    2198
    2199   if(upd_source_hdl == NULL){
    2200     printf("There must be one updateable source in the config file. Exiting.\n");
    2201     ER_perror(FAC_UP, UP_CONFERR, "There must be one updateable source in"
    2202                                   " the config file. Exiting.");
    2203     exit(1);
    2204   }else{
    2205     if(tracing){
    2206       printf("\nTRACING: The upd_source_hdl is: %s\n", upd_source_hdl->name);
    2207     }
    2208     sources[0] = strdup(upd_source_hdl->name);
    2209     update_host = upd_source_hdl->whoisd_host;
    2210     query_host = strdup(update_host);
    2211     update_port = upd_source_hdl->updPort;
    2212     query_port = upd_source_hdl->qryPort;
    2213     DBhost = upd_source_hdl->updDb.host;
    2214     DBport = upd_source_hdl->updDb.port;
    2215     DBname = upd_source_hdl->updDb.dbName;
    2216     DBuser = upd_source_hdl->updDb.user;
    2217     DBpasswd = upd_source_hdl->updDb.password;
    2218   }
    2219
    2220
    2221   /* construct country array from country string variable */
    2222
    2223   temp_vector = g_strsplit(country, "\n", 0);
    2224   for (i=0, j=0; temp_vector[i] != NULL; i++)
    2225   {
    2226     temp_vector[i] == g_strstrip(temp_vector[i]);
    2227     if (strlen(temp_vector[i]) > 0)
    2228         {
    2229       countries[j] = strdup(temp_vector[i]);
    2230       g_strup(countries[j++]);
    2231     }
    2232   }
    2233   countries[j] = NULL; /* mark the end of array */
    2234   g_strfreev(temp_vector);
    2235   if (tracing)
    2236   {
    2237     printf("TRACING: number of countries [%i]\n", j);
    2238   }
    2239
    2240   /* hard code the nicsuffixes for now, but should be a configurable variable */
    2241
    2242   nicsuffixes[0] = strdup("RIPE");
    2243   nicsuffixes[1] = strdup("ORG");
    2244   nicsuffixes[2] = strdup("ARIN");
    2245   nicsuffixes[3] = strdup("RADB");
    2246   nicsuffixes[4] = strdup("APNIC");
    2247   nicsuffixes[5] = strdup("RIPN");
    2248   nicsuffixes[6] = NULL;
    2249
    2250   if (tracing)
    2251   {
    2252     /* print out the config variables for debugging */
    2253     printf("TMPDIR is: [%s]\n", tmpdir);
    2254     printf("MAILCMD is: [%s]\n", mailcmd);
    2255     printf("NOTITXT is: [%s]\n", notitxt);
    2256     printf("CROSSLOG is: [%s]\n", crosslog);
    2257     printf("FWTXT is: [%s]\n", fwtxt);
    2258     printf("HUMAILBOX is: [%s]\n", humailbox);
    2259     printf("AUTOBOX is: [%s]\n", autobox);
    2260     printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
    2261     printf("ACKLOG is: [%s]\n", acklog);
    2262     printf("NOTIFLOG is: [%s]\n", notiflog);
    2263     printf("FORWLOG is: [%s]\n", forwlog);
    2264     printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
    2265     printf("FWMAILTXT is: [%s]\n", fwmailtxt);
    2266 /*   printf("COUNTRY is: [%s]\n", country); */
    2267     printf("PGPPATH is: [%s]\n", pgppath);
    2268     printf("UPDATE_HOST is: [%s]\n", update_host);
    2269     printf("UPDATE_PORT is: [%i]\n", update_port);
    2270     printf("QUERY_HOST is: [%s]\n",  query_host);
    2271     printf("QUERY_PORT is: [%i]\n",  query_port);
    2272     printf("LOCKDIR is: [%s]\n", lockdir);
    2273     printf("TESTMODE is: [%i]\n", test_mode);
    2274     printf("CNO_SUBJECT_ADD is: [%s]\n", cno_subject_add);
    2275     printf("CNO_SUBJECT_DEL is: [%s]\n", cno_subject_del);
    2276   }
    2277   /* end of config stuff */
    2278
    2279
    2280   /* set hostname global variable */
    2281   gethostname(hostname, MAXHOSTNAMELEN);
    2282
    2283   /* set pid global variable */
    2284   pid = getpid();
    2285
    2286   /* create the lock file and lock it */
    2287   /* lockfile = create_lock_file(); */
    2288
    2289   /* initialize the parser */
    2290 /*  schema.initialize(); */
    2291
    2292
    2293   /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
    2294       also creates it) */
    2295   ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
    2296
    2297   /* initialize credentials.pgp_key_list */
    2298   credentials.pgp_key_list = NULL;
    2299
    2300
    2301
    2302   if (reading_from_mail)
    2303   {
    2304     if (input_file_name != NULL)
    2305     {
    2306       temp_upd_file = generate_upd_file();
    2307       if (tracing)
    2308       {
    2309         printf("TRACING: temp_upd_file is [%s]\n", temp_upd_file);
    2310       }
    2311
    2312       /* first log the input in the upd log file */
    2313       UP_add_to_upd_log(input_file_name);
    2314
    2315
    2316       MM_store(input_file_name, temp_upd_file, 0);
    2317       p = EP_ParseMail(input_file_name, tmpdir, pgp_public_key_ring, gpgcmd);
    2318
    2319     }
    2320     else
    2321     { /* input_file_name == NULL */
    2322       temp_upd_file = generate_upd_file();
    2323       MM_store("-", temp_upd_file, 0);
    2324
    2325       /* first log the input in the upd log file */
    2326       UP_add_to_upd_log(temp_upd_file);
    2327
    2328       p = EP_ParseMail(temp_upd_file, tmpdir, pgp_public_key_ring, gpgcmd);
    2329
    2330     }
    2331
    2332     /* write off the checkpoint file */
    2333     write_checkpoint(1);
    2334
    2335     /* the new stuff using the EP module's interface */
    2336
    2337     if(p->from != NULL && p->from->field != NULL)
    2338     {
    2339       credentials.from = (char *)malloc(strlen(p->from->field) + strlen("From:") + 1);
    2340       sprintf(credentials.from, "From:%s", p->from->field);
    2341       credentials.from_email = strdup(p->from->field); /* This doesn't contain "From:" */
    2342       /* cut off the '\n's and '\r's at the end */
    2343       UP_remove_EOLs(credentials.from);
    2344       UP_remove_EOLs(credentials.from_email);
    2345
    2346       /* now, there is a problem with EP module (or c-client): the p->from->field
    2347          would contain only the first line if the "From" field has multiple lines.
    2348          As a temp solution, we will add the second line (if it exists) explicitely */
    2349       /* This is not a problem, it is the way the imap is written.
    2350          It returns multiple lines as a linked list, so loop for all the lines */
    2351       while ( (p->from = p->from->next) != NULL && p->from->field != NULL)
    2352       { /* there is another line */
    2353         credentials.from = (char *)realloc(credentials.from, strlen(credentials.from) + strlen(p->from->field) + 1);
    2354         strcat(credentials.from, p->from->field);
    2355         credentials.from_email = (char *)realloc(credentials.from_email, strlen(credentials.from_email) + strlen(p->from->field) + 1);
    2356         strcat(credentials.from_email, p->from->field);
    2357         UP_remove_EOLs(credentials.from);
    2358         UP_remove_EOLs(credentials.from_email);
    2359       }
    2360     }
    2361     else
    2362     {
    2363       credentials.from = strdup("");
    2364       credentials.from_email = strdup("");
    2365     }
    2366
    2367     update_mail_sender = strdup(credentials.from_email);
    2368
    2369     if (tracing)
    2370     {
    2371       printf("TRACING: From field is: [%s]\n", credentials.from);
    2372       printf("TRACING: update_mail_sender is: [%s]\n", update_mail_sender);
    2373     }
    2374
    2375
    2376     if(p->cc != NULL && p->cc->field != NULL)
    2377     {
    2378       update_mail_cc = strdup(p->cc->field);
    2379       /* cut off the '\n's and '\r's at the end */
    2380       UP_remove_EOLs(update_mail_cc);
    2381
    2382       /* loop for all multiple lines */
    2383       while ( (p->cc = p->cc->next) != NULL && p->cc->field != NULL)
    2384       { /* there is another line */
    2385         update_mail_cc = (char *)realloc(update_mail_cc, strlen(update_mail_cc) + strlen(p->cc->field) + 1);
    2386         strcat(update_mail_cc, p->cc->field);
    2387         UP_remove_EOLs(update_mail_cc);
    2388       }
    2389     }
    2390     else
    2391       update_mail_cc = strdup("");
    2392
    2393     if (tracing)
    2394     {
    2395       printf("TRACING: Cc field is: [%s]\n", update_mail_cc);
    2396     }
    2397
    2398
    2399     if(p->subject != NULL && p->subject->field != NULL)
    2400     {
    2401       subject = strdup(p->subject->field);
    2402       /* cut off the '\n' and '\r' from the end */
    2403       UP_remove_EOLs(subject);
    2404
    2405       /* loop for all multiple lines */
    2406       while ( (p->subject = p->subject->next) != NULL && p->subject->field != NULL)
    2407       { /* there is another line */
    2408         subject = (char *)realloc(subject, strlen(subject) + strlen(p->subject->field) + 1);
    2409         strcat(subject, p->subject->field);
    2410         UP_remove_EOLs(subject);
    2411       }
    2412     }
    2413     else
    2414       subject = strdup("");
    2415
    2416     update_mail_subject = strdup(subject);
    2417
    2418     /* parse the subject line */
    2419     subject_result = UP_subject_process(update_mail_subject);
    2420
    2421
    2422     if(p->reply_to != NULL && p->reply_to->field != NULL)
    2423     {
    2424       reply_to = strdup(p->reply_to->field);
    2425       /* cut off the '\n' and '\r' from the end */
    2426       UP_remove_EOLs(reply_to);
    2427
    2428       /* loop for all multiple lines */
    2429       while ( (p->reply_to = p->reply_to->next) != NULL && p->reply_to->field != NULL)
    2430       { /* there is another line */
    2431         reply_to = (char *)realloc(reply_to, strlen(reply_to) + strlen(p->reply_to->field) + 1);
    2432         strcat(reply_to, p->reply_to->field);
    2433         UP_remove_EOLs(reply_to);
    2434       }
    2435     }
    2436     else
    2437       reply_to = strdup("");
    2438
    2439
    2440     to_address = find_email_address(credentials.from);
    2441
    2442     /* if Reply_To was available in the incoming header, then use it */
    2443     if (strlen(reply_to) > 0)
    2444     {
    2445       to_address = (char *)realloc(to_address, strlen(reply_to) + 1);
    2446       to_address = strcpy(to_address, reply_to);
    2447       to_address = find_email_address(to_address); /* so that we take only the email address */
    2448     }
    2449
    2450     if (p->message_id != NULL && p->message_id->field != NULL)
    2451     {
    2452       update_mail_ID = strdup(p->message_id->field);
    2453       /* cut off the '\n' and '\r' from the end */
    2454       UP_remove_EOLs(update_mail_ID);
    2455
    2456       /* loop for all multiple lines */
    2457       while ( (p->message_id = p->message_id->next) != NULL && p->message_id->field != NULL)
    2458       { /* there is another line */
    2459         update_mail_ID = (char *)realloc(update_mail_ID, strlen(update_mail_ID) + strlen(p->message_id->field) + 1);
    2460         strcat(update_mail_ID, p->message_id->field);
    2461         UP_remove_EOLs(update_mail_ID);
    2462       }
    2463     }
    2464     else
    2465       update_mail_ID = strdup("");
    2466
    2467
    2468     if(p->date != NULL && p->date->field != NULL)
    2469     {
    2470       update_mail_date = strdup(p->date->field);
    2471       /* cut off the '\n' and '\r' from the end  */
    2472       UP_remove_EOLs(update_mail_date);
    2473
    2474       /* loop for all multiple lines */
    2475       while ( (p->date = p->date->next) != NULL && p->date->field != NULL)
    2476       { /* there is another line */
    2477         update_mail_date = (char *)realloc(update_mail_date, strlen(update_mail_date) + strlen(p->date->field) + 1);
    2478         strcat(update_mail_date, p->date->field);
    2479         UP_remove_EOLs(update_mail_date);
    2480       }
    2481     }
    2482     else
    2483       update_mail_date = strdup("");
    2484
    2485     if (tracing)
    2486     {
    2487       printf("\nEP_ShowTree outputs:\n");
    2488       EP_ShowTree(p->tree);
    2489     }
    2490
    2491     pt = EP_GetTokens(p->tree, NULL, NULL);
    2492
    2493     if(tracing){
    2494       /* Print the list out (debugging) */
    2495       printf("\nEP_PrintTokens outputs:\n");
    2496       EP_PrintTokens(pt);
    2497     }
    2498
    2499     /* replace the global variables in mheader */
    2500     mheader_replaced = UP_replace_globals(mheader);
    2501     /* replace the global variables in mailtxt */
    2502     mailtxt_replaced = UP_replace_globals(mailtxt);
    2503
    2504     /* If this wasn't only a help request, then we need to process the input */
    2505     if(subject_result.result != UP_SUBJ_HELP_REQ){
    2506
    2507       /* ... and now process the items in the list */
    2508       list_item = pt;
    2509       while (list_item != NULL) {
    2510         if(tracing){
    2511           printf("\n\nWill process: %s, MIMEtype: %d\n", list_item->file, list_item->MIMEContentType);
    2512         }
    2513         /* initialize pgp_key_list (XXX This should be a proper freeing of the list) */
    2514         credentials.pgp_key_list = NULL;
    2515         ptk = list_item->keys;
    2516         if(ptk != NULL){
    2517           AK_add_to_ack(ack_file_name, "==== BEGIN PGP SIGNED PART (keyID(s):");
    2518           pgp_signed = 1;
    2519           while (ptk != NULL) {
    2520             if(tracing){
    2521               printf("TRACING:     key: %.8X, isValid: %i\n",
    2522                    ptk->keyID, ptk->isValidPGPSignature);
    2523             }
    2524             temp_keyid = (char *)malloc(10);
    2525             sprintf(temp_keyid, "%.8X", ptk->keyID);
    2526             if(tracing){
    2527               printf("TRACING: This key will be added to the list: [%s]\n", temp_keyid);
    2528             }
    2529             AK_add_to_ack(ack_file_name, " %s", temp_keyid);
    2530             credentials.pgp_key_list = g_slist_append (credentials.pgp_key_list, temp_keyid);
    2531             ptk = ptk->next;
    2532             if(ptk != NULL){
    2533               AK_add_to_ack(ack_file_name, ",");
    2534             }else{
    2535               AK_add_to_ack(ack_file_name, ") ====\n");
    2536             }
    2537           }
    2538         }
    2539         process_file(list_item->file, credentials,
    2540                      AUTO_NIC_hdl_hash, ack_file_name,
    2541                      ntfy_hash, forw_hash, cross_hash);
    2542         if(pgp_signed){
    2543           AK_add_to_ack(ack_file_name, "==== END PGP SIGNED PART ====\n\n");
    2544           pgp_signed = 0;
    2545         }
    2546         list_item = list_item->next;
    2547       }
    2548
    2549     }else{/* this was only a help request (inferred from the "Subject" line of the upd message) */
    2550
    2551       /* Print out the header of the acknowledgement */
    2552 /*      AK_add_to_ack(ack_file_name, "To: %s\n%s\n\nHelp file requested so body of message ignored.\n\n\n"
    2553           "============================================================\n\n",
    2554           to_address, mheader_replaced);  */
    2555       AK_add_to_ack(ack_file_name, "\n============================================================\n\n");
    2556
    2557       AK_add_file_to_ack(ack_file_name, autodbmhelp);
    2558       AK_add_to_ack(ack_file_name, "\n============================================================\n\n");
    2559
    2560     }
    2561
    2562     EP_CleanTokens(pt);
    2563
    2564     EP_MailDescrCleanUp(p);
    2565
    2566     /* if we have created a temporary file for update, delete it */
    2567     if(temp_upd_file != NULL){
    2568
    2569       unlink(temp_upd_file);
    2570
    2571     }
    2572
    2573   }else if(networkupdate){
    2574
    2575     /* process networkupdate. Since we use inetd, we just process stdin */
    2576     process_networkupdate(credentials, AUTO_NIC_hdl_hash, ack_file_name,
    2577                           ntfy_hash, forw_hash, cross_hash);
    2578
    2579   }else{/* not reading from the mail message or from network */
    2580     if(input_file_name != NULL){
    2581
    2582       /* first log the input in the upd log file */
    2583       UP_add_to_upd_log(input_file_name);
    2584
    2585
    2586       write_checkpoint(1);
    2587       process_file(input_file_name, credentials,
    2588                   AUTO_NIC_hdl_hash, ack_file_name,
    2589                   ntfy_hash, forw_hash, cross_hash);
    2590     }else{/* the filename is not given, so we have to write
    2591              stdin to a temp file, and give it to process_file */
    2592        temp_upd_file = generate_upd_file();
    2593        if(tracing){
    2594          printf("TRACING: main: temp_upd_file=%s\n", temp_upd_file);
    2595        }
    2596        if(( upd_file = fopen(temp_upd_file, "a")) == NULL){
    2597          ER_perror(FAC_UP, UP_CANTOPENW, "Can't open ack file, %s", temp_upd_file);
    2598        }
    2599
    2600        while((c = getchar()) != EOF){
    2601          fprintf(upd_file, "%c",c);
    2602        }
    2603        fclose(upd_file);
    2604
    2605        write_checkpoint(1);
    2606        process_file(temp_upd_file, credentials,
    2607                   AUTO_NIC_hdl_hash, ack_file_name,
    2608                   ntfy_hash, forw_hash, cross_hash);
    2609        unlink(temp_upd_file);
    2610
    2611     }
    2612
    2613   }
    2614
    2615
    2616   /* post-process and send the ack */
    2617   if(reading_from_mail && to_address != NULL){
    2618     AK_send_ack(ack_file_name, to_address, mailcmd);
    2619   }
    2620
    2621   /* if our update wasn't a mail update OR we have been asked explicitely
    2622      to print out the ack to the stdout, print it */
    2623   if(!reading_from_mail || print_out_ack){
    2624     AK_print_ack(ack_file_name);
    2625   }
    2626
    2627   AK_log_ack(ack_file_name, acklog);
    2628   AK_delete_ack(ack_file_name);
    2629
    2630   NT_send_ntfy_list(ntfy_hash, mailcmd);
    2631   NT_log_ntfy_list(ntfy_hash, notiflog);
    2632   NT_delete_ntfy_list(ntfy_hash);
    2633
    2634   NT_send_ntfy_list(forw_hash, mailcmd);
    2635   NT_log_ntfy_list(forw_hash, forwlog);
    2636   NT_delete_ntfy_list(forw_hash);
    2637
    2638
    2639   NT_send_ntfy_list(cross_hash, mailcmd);
    2640   NT_log_ntfy_list(cross_hash, crosslog);
    2641   NT_delete_ntfy_list(cross_hash);
    2642
    2643   /* remove the lock file */
    2644   /* remove_lock_file(lockfile); */
    2645
    2646
    2647   /* remove checkpoint file */
    2648   remove_checkpoint();
    2649
    2650   free(ack_file_name);
    2651
    2652   if (tracing)
    2653   {
    2654     printf("TRACING: END\n");
    2655   }
    2656
    2657   return 0 ;
    2658 }

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