## bin/dbupdate/dbupdate.c

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

## DEFINITIONS

This source file includes following functions.

1. error_init
2. lockfilestruct
3. delete_key
4. import_key
5. get_keyowner_fingerpr
6. deprecated_mail_from
7. write_errors_to_ack
8. set_default_source_data
9. set_current_source_data
10. process_object
11. process_file
12. generate_upd_file
13. create_lock_file
14. remove_lock_file
15. write_checkpoint
16. remove_checkpoint
17. main

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

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