## bin/dbupdate/dbupdate.cc

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

## FUNCTIONS

This source file includes following functions.

1. error_init
2. process_object
3. scan_for_PGP
4. process_file
5. generate_upd_file
6. main

       1 /***************************************
       2   $Revision: 1.22 $
       3
       4   DBupdate
       5
       6   Status: NOT REVIEWED, NOT TESTED
       7
       8   Author(s):       Engin Gunduz
       9
      10   ******************/ /******************
      11   Modification History:
      12         engin (01/03/2000) Created.
      13   ******************/ /******************
      14   Copyright (c) 2000                              RIPE NCC
      15
      16   All Rights Reserved
      17
      18   Permission to use, copy, modify, and distribute this software and its
      19   documentation for any purpose and without fee is hereby granted,
      20   provided that the above copyright notice appear in all copies and that
      21   both that copyright notice and this permission notice appear in
      22   supporting documentation, and that the name of the author not be
      23   used in advertising or publicity pertaining to distribution of the
      24   software without specific, written prior permission.
      25
      26   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      27   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      28   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      29   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      30   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      31   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      32  ***************************************/
      33
      34
      35
      36
      37
      38 #include "dbupdate.h"
      39 #include "erroutines.h"
      40 #include "ca_configFns.h"
      41 #include "ca_dictSyms.h"
      42 #include "ca_macros.h"
      43 #include "ca_srcAttribs.h"
      44 #include "notification.h"
      45 #include "gpg.h"
      46
      47 int tracing = 0;
      48 int test_mode = 0;
      49 int reading_from_mail = 0;
      50
      51 /* required configuration variables */
      52 char *tmpdir = NULL;
      53 char *mailcmd = NULL;
      54 char *notitxt = NULL;
      55 char *notimailtxt = NULL;
      56 char *fwtxt   = NULL;
      57 char *fwmailtxt = NULL;
      58 char *mailtxt = NULL;
      59 char *notiflog = NULL;
      60 char *crosslog = NULL;
      61 char *acklog = NULL;
      62 char *forwlog = NULL;
      63 char *humailbox = NULL;
      64 char *overridecryptedpw = NULL;
      65 int *testmode = NULL;
      66 char *country = NULL;
      67 char    *countries[400];
      68 char *pgppath = NULL;
      69 char *pgp_public_key_ring = NULL;
      70 /* end of config variables */
      71
      72 void error_init(int argc, char ** argv) {
         /* [<][>][^][v][top][bottom][index][help] */
      73   er_path_t erlogstr;
      74
      75   ER_init(argc, argv);
      76
      77   erlogstr.fdes = stderr;
      78   erlogstr.asp  = 0;
      79   erlogstr.sev  = ER_SEV_W;
      80   erlogstr.mode = ER_M_SEVCHAR | ER_M_TEXTLONG;
      81
      82   ER_setpath(& erlogstr);
      83
      84 } /* error_init() */
      85
      86
      87
      88 /* Checks the object's syntax, retrives the old version of it from the db,
      89    and checks auth2. If everything is OK, then sends it to RIPdb, where referential
      90    integrity is checked, and the object is really committed to the db.
      91
      92      Arguments:
      93         char * arg: The object,
      94         credentials_struct credentials: The struct containing the credentials, such as
      95           'From:' field of the e-mail update,
      96         GHashTable * NIC_hdl_hash: A hash containing
      97         char * ack_file_name:  The file name, to be used to store ACK message
      98 */
      99
     100
     101
     102 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name,
         /* [<][>][^][v][top][bottom][index][help] */
     103                    GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
     104     bool code = true;
     105     Object *o;
     106     char * old_version = NULL;
     107     o = new Object;
     108     int result = 0;
     109     int result_from_RIPupd = 0;
     110     char * auto_nic = NULL;
     111     char * changed_obj = NULL;
     112     char * obj_with_AUTO_NIC_hdl;
     113     char * assigned_NIC;
     114
     115     char * value = NULL;/* these two are for */
     116     Attr * attr;        /* ack messages only */
     117
     118     if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
     119        /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
     120        if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
     121          return UP_ANE; /* AUTO NIC hdl error */
     122        };
     123     }
     124
     125     code = o->scan(arg,strlen(arg));
     126     if(code){
     127       /* is the object to be deleted? */
     128       if(o->isDeleted){
     129         //printf("DEBUG: This object is to be deleted\n");
     130         old_version = get_old_version(arg);
     131         if(old_version == NULL){ /* the object doesn't exist in the db! */
     132           AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nEntry not found\n\n%s\n",
     133                         o->type->getName(), get_search_key(o, o->type->getName(), arg), arg);
     134           return UP_NSO; /* no such object */
     135         }else {/* the object is in the db */
     136           if(identical(old_version, arg)){/* if the old & new versions are identical */
     137             result = check_auth(NULL, old_version, o->type->getName(), credentials);
     138             if(result == UP_AUTH_OK){
     139               if(tracing) {
     140                 printf("TRACING: Will send the obj to be deleted\n");
     141               }
     142               result_from_RIPupd = send_object_db(arg, NULL, "DEL");
     143               if(result_from_RIPupd == 0){
     144                 AK_add_to_ack(ack_file_name, "\nDelete OK: [%s] %s\n",
     145                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
     146                 NT_write_all_ntfs(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     147               }else{
     148                 AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nReferential integrity failure\n",
     149                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
     150               }
     151               result_from_RIPupd = 0;
     152             }else{ /* auth failed */
     153               if(tracing) {
     154                 printf("TRACING: Auth failed\n");
     155               }
     156
     157               AK_add_to_ack(ack_file_name, "\nDelete FAILED: [%s] %s\nAuth failed\n",
     158                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
     159               NT_write_all_frwds(arg, NULL, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     160               return UP_AUF; /* Auth failed */
     161             }
     162           }else{/* the new & old versions do not match */
     163             AK_add_to_ack(ack_file_name, "\nDelete FAILED: new & old versions do not match\n");
     164             return UP_NOM; /* new & old versions do not match */
     165           }
     166         }
     167       }else {/* the object is _not_ to be deleted */
     168         if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
     169           /* then its nic-hdl attribute must be modified so that RIPupdate
     170              would understand that it must assign a NIC handle to it */
     171           /* but first check the auth */
     172           result = check_auth(arg, NULL, o->type->getName(), credentials);
     173           if(result == UP_AUTH_OK){
     174             if(tracing) {
     175                 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
     176             }
     177             auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
     178             obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
     179             if(tracing) {
     180               printf("TRACING:  Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
     181               printf("TRACING: Will send the obj to be added\n");
     182             }
     183             assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
     184             result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
     185             if(result_from_RIPupd == 0){
     186               AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n",
     187                             o->type->getName(), assigned_NIC);
     188               NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     189             }else{
     190               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
     191                             o->type->getName(), arg);
     192             }
     193             result_from_RIPupd = 0;
     194             if(tracing && assigned_NIC != NULL) {
     195               printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
     196             }
     197             if(assigned_NIC != NULL){
     198               printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
     199               g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
     200               printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
     201             }
     202
     203           }else{
     204             /* auth failed ! */
     205             if(tracing) {
     206               printf("TRACING: Auth failed\n");
     207             }
     208
     209             ER_perror(0, result, "");
     210             AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
     211                           o->type->getName(), get_search_key(o, o->type->getName(), arg));
     212             NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     213             return UP_AUF; /* Auth failed */
     214           }
     215         }
     216         else{
     217           old_version = get_old_version(arg);
     218           if(old_version != NULL){/* so, this is an update operation */
     219             result = check_auth(arg, old_version, o->type->getName(), credentials);
     220             if(result == UP_AUTH_OK){
     221               if(tracing) {
     222                 printf("TRACING: Will send the obj to be updated\n");
     223               }
     224               result_from_RIPupd = send_object_db(arg, NULL, "UPD");
     225               if(result_from_RIPupd == 0){
     226                 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
     227                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
     228                 NT_write_all_ntfs(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     229               }else{
     230                 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
     231                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
     232               }
     233               result_from_RIPupd = 0;
     234             }else{
     235               /* auth failed ! */
     236               if(tracing) {
     237                 printf("TRACING: Auth failed\n");
     238               }
     239
     240               AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
     241                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
     242               NT_write_all_frwds(old_version, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     243               return UP_AUF; /* Auth failed */
     244             }
     245           }else { /* old_version  == NULL, so, creation */
     246             result = check_auth(arg, NULL, o->type->getName(), credentials);
     247             if(result == UP_AUTH_OK){
     248               if(tracing) {
     249                 printf("TRACING: Will send the obj to be added\n");
     250               }
     251               result_from_RIPupd = send_object_db(arg, NULL, "ADD");
     252               if(result_from_RIPupd == 0){
     253                 AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
     254                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
     255                 NT_write_all_ntfs(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     256
     257               }else{
     258                 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
     259                               o->type->getName(), get_search_key(o, o->type->getName(), arg));
     260               }
     261               result_from_RIPupd = 0;
     262             }else{
     263               /* auth failed ! */
     264               if(tracing) {
     265                 printf("TRACING: Auth failed\n");
     266               }
     267
     268               ER_perror(0, result, "");
     269               AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
     270                             o->type->getName(), get_search_key(o, o->type->getName(), arg));
     271               NT_write_all_frwds(NULL, arg, tmpdir, ntfy_hash, forw_hash, cross_hash, credentials.from);
     272               return UP_AUF; /* Auth failed */
     273             }
     274           }
     275         }
     276       }
     277     }else{/* even if obj doesn't parse properly, it may be a legacy object
     278             which the user wants to delete... */
     279        if(tracing){
     280          printf("TRACING: Object didn't parse\n");
     281        }
     282        AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
     283        //////////////////////////////////
     284        if(o->attrs.head() != NULL){
     285          for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
     286            if(attr->len > 0){
     287              value = (char*)malloc(attr->len);
     288              strncpy(value, (char *)(arg+attr->offset) ,
     289                attr->len - 1);
     290              value[attr->len - 1] = '\0';
     291              AK_add_to_ack(ack_file_name, "%s\n", value);
     292              if(!attr->errors.empty()){
     293                AK_add_to_ack_string(ack_file_name, attr->errors);
     294              }
     295              free(value);
     296            }else{
     297              if(!attr->errors.empty()){
     298                AK_add_to_ack_string(ack_file_name, attr->errors);
     299              }
     300            }
     301          }
     302        }
     303        if(o->has_error){
     304          AK_add_to_ack_string(ack_file_name, o->errors);
     305        }
     306        AK_add_to_ack(ack_file_name, "\n");
     307        //////////////////////////////////
     308        return UP_NIY; /* Not implemented yet */
     309     }
     310 }
     311
     312
     313 /* A temporary function to test if there is a PGP signed portion in the file */
     314 int scan_for_PGP(const char * filename){
         /* [<][>][^][v][top][bottom][index][help] */
     315
     316   FILE *file;
     317   char *line;
     318
     319   line = (char *)malloc(1024);
     320   if((file = fopen(filename, "r")) == NULL){
     321     printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
     322     exit(1);
     323   }
     324   while(fgets(line, 1024, file) != NULL){
     325     if(strstr(line, "-----BEGIN PGP") == line){/* yes, we have a PGP signed portion, so return true */
     326       fclose(file);
     327       free(line);
     328       return 1;
     329     }
     330   }
     331   fclose(file);
     332   free(line);
     333   return 0; /* no, we din't have any PGP signed portions */
     334 }
     335
     336
     337
     338
     339
     340 /* processes the objects in the given file */
     341 void process_file(char * filename, credentials_struct credentials,
         /* [<][>][^][v][top][bottom][index][help] */
     342                   GHashTable * AUTO_NIC_hdl_hash, char * ack_file_name,
     343                   GHashTable * ntfy_hash, GHashTable * forw_hash, GHashTable * cross_hash){
     344
     345 FILE * input_file;
     346 GSList *list_of_objects = NULL, *list_of_objects2 = NULL;
     347 GSList *next = NULL;
     348 int object_count = 0;
     349 char *object = NULL;
     350 char *line;
     351 int result = 0;
     352 struct VerifySignObject vSO, *pvSO;
     353 //char keyring[100] = "/home/engin/.gnupg/pubring.gpg";
     354
     355
     356   /* allocate space for pgp_struct, it will be set to pgp key ID when we encounter a pgp signed message */
     357   credentials.pgp_struct == (char *)malloc(10);
     358
     359   line = (char *)malloc(1024);
     360
     361   /* if we have PGP signed portions in the message */
     362   if(scan_for_PGP(filename)){
     363     strcpy(vSO.outputPath, "/tmp");
     364     strcpy(vSO.iDocSigFilename, filename);
     365     strcpy(vSO.iSigFilename, "");
     366     strcpy(vSO.keyRing, pgp_public_key_ring/*keyring*/);
     367
     368     PA_VerifySignature(&vSO);
     369
     370     pvSO = vSO.next;
     371     while (pvSO != NULL) {
     372       printf("isValid: %d\n", pvSO->isValid);
     373       printf("key ID: %x\n",  pvSO->keyID);
     374       printf("oStream is %s\n", pvSO->oStream);
     375
     376
     377       if(pvSO->isValid == 1){/* if this PGP signed portion is valid, read it */
     378         if((input_file = fopen( pvSO->oStream/*filename*/, "r")) == NULL){
     379            printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
     380            exit(1);
     381         }
     382         AK_add_to_ack(ack_file_name, "\n*** Beginning of PGP signed part from key ID %X\n", pvSO->keyID);
     383         sprintf(credentials.pgp_struct, "%.8X", pvSO->keyID);
     384         printf("DEBUG:  credentials.pgp_struct=[%s]\n", credentials.pgp_struct);
     385         while(fgets(line, 1024, input_file) != NULL){
     386           /* first, if it is a pasword, save it, but do not regard it as an attrib */
     387           if(strstr(line, "password:") == line){
     388             if(tracing){
     389               printf("DEBUG: This is a password\n");
     390             }
     391             credentials.password_list = g_slist_append(credentials.password_list,
     392                                           g_strstrip(strdup(line + strlen("password:"))));
     393             continue;
     394           }
     395           /* if the length of the line read is 2, then this is an empty line ("\n\r")*/
     396           if(strlen(line) == 2){
     397             if(object != NULL){
     398               list_of_objects = g_slist_append(list_of_objects, object);
     399               object = NULL;
     400             }
     401           }else{
     402             /* if the line contains only the EOL sequence "\n\r" */
     403             if(object == NULL && strlen(line) != 2){
     404               object = (char *)malloc(strlen(line));
     405               object = strdup(line);
     406             }
     407             else{
     408               object = (char *)realloc(object, strlen(object) + strlen(line));
     409               object = strcat(object, line);
     410             }
     411           }
     412
     413         }
     414         fclose(input_file);
     415
     416         /* now, if at the very and of the input file there wasn't an
     417            empty line, we have to add the remaining object in the 'object'
     418            variable */
     419         if(object != NULL){
     420            //cout << "The object was" << endl << object << endl;
     421            list_of_objects = g_slist_append(list_of_objects, object);
     422            object = NULL;
     423         }
     424
     425
     426
     427         if(tracing) {
     428            printf("TRACING: Will process the objects in the list\n");
     429         }
     430         next = list_of_objects;
     431         object_count = 0;
     432         for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
     433           object_count++;
     434
     435           if(tracing) {
     436             cout << "TRACING: Got an object from the list" << endl;
     437             cout << (char *)next->data << endl;
     438           }
     439
     440           if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
     441             if(tracing) {
     442               printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
     443             }
     444             list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
     445           }else{
     446             result = 0;
     447             result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
     448                                      ntfy_hash, forw_hash, cross_hash);
     449           }
     450         }
     451
     452         if(tracing) {
     453           printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
     454         }
     455
     456         if(tracing) {
     457           printf("TRACING: will start to process the second list\n");
     458         }
     459
     460         for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
     461           if(tracing) {
     462             printf("TRACING: Will process object: %s\n", (char *)next->data);
     463           }
     464           result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
     465                                    ntfy_hash, forw_hash, cross_hash);
     466         }
     467         /* empty the object lists (this must be done by properly freeing the memory taken by them!) */
     468         list_of_objects = NULL;
     469         list_of_objects2 = NULL;
     470         AK_add_to_ack(ack_file_name, "\n*** End of PGP signed part from key ID %X\n", pvSO->keyID);
     471
     472         }else{
     473           AK_add_to_ack(ack_file_name, "\n***  Ignoring PGP signed part from key ID %X", pvSO->keyID);
     474           AK_add_to_ack(ack_file_name, "\n***  Bad signature or key is not in public key ring or other error\n\n");
     475         }
     476
     477       pvSO = pvSO->next;
     478       /* empty out credentials.pgp_struct for the next loop  */
     479       strcpy(credentials.pgp_struct,"");
     480       }
     481
     482     }
     483     else{/* the file doesn't contain PGP signed portions */
     484      if((input_file = fopen(filename, "r")) == NULL){
     485          printf("Couldn't open the file %s: %s\n", filename, strerror(errno));
     486          exit(1);
     487      }
     488
     489
     490     while(fgets(line, 1024, input_file) != NULL){
     491       /* first, if it is a pasword, save it, but do not regard it as an attrib */
     492       if(strstr(line, "password:") == line){
     493         if(tracing){
     494           printf("DEBUG: This is a password\n");
     495         }
     496         credentials.password_list = g_slist_append(credentials.password_list,
     497                                       g_strstrip(strdup(line + strlen("password:"))));
     498         continue;
     499       }
     500       /* if the length of the line read is 2, then this is an empty line ("\n\r")*/
     501       if(strlen(line) == 2){
     502         if(object != NULL){
     503            list_of_objects = g_slist_append(list_of_objects, object);
     504            object = NULL;
     505         }
     506       }else{
     507         /* if the line contains only the EOL sequence "\n\r" */
     508         if(object == NULL && strlen(line) != 2){
     509           object = (char *)malloc(strlen(line));
     510           object = strdup(line);
     511         }
     512         else{
     513           object = (char *)realloc(object, strlen(object) + strlen(line));
     514           object = strcat(object, line);
     515         }
     516       }
     517
     518     }
     519     fclose(input_file);
     520
     521     /* now, if at the very and of the input file there wasn't an
     522        empty line, we have to add the remaining object in the 'object'
     523        variable */
     524     if(object != NULL){
     525        //cout << "The object was" << endl << object << endl;
     526        list_of_objects = g_slist_append(list_of_objects, object);
     527        object = NULL;
     528     }
     529
     530
     531
     532     if(tracing) {
     533        printf("TRACING: Will process the objects in the list\n");
     534     }
     535     next = list_of_objects;
     536     object_count = 0;
     537     for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
     538       object_count++;
     539
     540       if(tracing) {
     541         cout << "TRACING: Got an object from the list" << endl;
     542         cout << (char *)next->data << endl;
     543       }
     544
     545       if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
     546         if(tracing) {
     547           printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
     548         }
     549         list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
     550       }else{
     551         result = 0;
     552         result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
     553                                  ntfy_hash, forw_hash, cross_hash);
     554       }
     555     }
     556
     557     if(tracing) {
     558       printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
     559     }
     560
     561     if(tracing) {
     562       printf("TRACING: will start to process the second list\n");
     563     }
     564
     565     for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
     566       if(tracing) {
     567         printf("TRACING: Will process object: %s\n", (char *)next->data);
     568       }
     569       result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name,
     570                                ntfy_hash, forw_hash, cross_hash);
     571     }
     572
     573   }
     574
     575 }/* process_file */
     576
     577
     578
     579
     580
     581
     582 /*  Generates a unique file name and returns the full path of the filename
     583     for storing notification message.  */
     584
     585 char * generate_upd_file(){
         /* [<][>][^][v][top][bottom][index][help] */
     586
     587    char * name;
     588
     589    /* allocate space for name.  32 should be enough for PID */
     590    name = (char*)malloc(strlen("/tmp/dbupdate-tmp.") + strlen("notify") +32 );
     591
     592    sprintf(name, "/tmp/dbupdate-tmp.%i", getpid());
     593
     594
     595    return name;
     596
     597 }
     598
     599
     600
     601
     602
     603 /* main */
     604 void main(int argc, char **argv, char **envp){
         /* [<][>][^][v][top][bottom][index][help] */
     605   //init_and_set_options(argc, argv, envp);
     606
     607   int count = 0;
     608   int i,j;
     609
     610   char ** temp_vector;
     611   char * temp;
     612   char * temp_upd_file = NULL;
     613   char *input_file_name = NULL;
     614   GHashTable *AUTO_NIC_hdl_hash;
     615   credentials_struct credentials;
     616
     617
     618   GHashTable *ntfy_hash, *forw_hash, *cross_hash;
     619
     620
     621   char *mail_command_line, * ack_file_name;
     622   char *config_file_name = NULL;
     623
     624
     625   /* for using MM module */
     626   int retcode;
     627   MM_header *mail_header = NULL;
     628   MM_xmp_list *part_list;
     629   MM_xmp *partptr;
     630   long debug = 0;
     631
     632   /* optarg & optind are necessary to use getopt(3C) */
     633   extern char *optarg;
     634   extern int optind;
     635
     636
     637   /* create notification hashes */
     638   ntfy_hash = g_hash_table_new(g_str_hash, g_str_equal);
     639   forw_hash = g_hash_table_new(g_str_hash, g_str_equal);
     640
     641
     642   credentials.password_list = NULL;
     643   credentials.from = NULL;
     644   int ch;
     645   char * to_address = NULL;
     646
     647   AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);
     648   error_init(argc, argv);
     649
     650
     651   while ((ch = getopt(argc, argv, "MtTf:c:")) != -1){
     652           switch(ch) {
     653           case 'M':
     654                   reading_from_mail = 1;
     655                   break;
     656           case 'f':
     657                   input_file_name = strdup(optarg);
     658                   break;
     659           case 'c':
     660                   config_file_name = strdup(optarg);
     661                   break;
     662           case 't':
     663                   tracing = 1;
     664                   break;
     665           case 'T':
     666                   test_mode = 1;
     667                   break;
     668           case '?':
     669           default:
     670                   printf("Unknown option\n");exit(1);
     671           }
     672   }
     673
     674
     675
     676   /* config stuff */
     677   ca_populateDictionary(dictionary, VARS);
     678   /* if -c flag is given, use the named file as config file, otherwise use
     679      default filename */
     680   if( config_file_name != NULL){
     681     ca_readConfig(config_file_name, confVars, VARS);
     682   }else{
     683     ca_readConfig("dbupdate.conf", confVars, VARS);
     684   }
     685   tmpdir = ca_get_tmpdir;
     686   tmpdir = g_strstrip(tmpdir);
     687   mailcmd = ca_get_mailcmd;
     688   mailcmd = g_strstrip(mailcmd);
     689   notitxt = ca_get_notitxt;
     690   mailtxt = ca_get_mailtxt;
     691   crosslog = ca_get_crosslog;
     692   fwtxt = ca_get_fwtxt;
     693   humailbox = ca_get_humailbox;
     694   humailbox = g_strstrip(humailbox);
     695   overridecryptedpw = ca_get_overridecryptedpw;
     696   overridecryptedpw = g_strstrip(overridecryptedpw);
     697   acklog = ca_get_acklog;
     698   acklog = g_strstrip(acklog);
     699   notiflog = ca_get_notiflog;
     700   notiflog = g_strstrip(notiflog);
     701   notimailtxt = ca_get_notimailtxt;
     702   forwlog = ca_get_forwlog;
     703   forwlog = g_strstrip(forwlog);
     704   fwmailtxt = ca_get_fwmailtxt;
     705   country = ca_get_country;
     706   pgppath = ca_get_pgppath;
     707   pgppath = g_strstrip(pgppath);
     708   pgp_public_key_ring = (char *)malloc(strlen(pgppath) + strlen("/pubring.gpg") + 2);
     709   sprintf(pgp_public_key_ring ,"%s/pubring.gpg", pgppath);
     710   test_mode = ca_get_testmode;
     711   /* construct country array from country string variable */
     712
     713   temp_vector = g_strsplit(country, "\n", 0);
     714   for(i=0, j=0; temp_vector[i] != NULL; i++){
     715     temp_vector[i] == g_strstrip(temp_vector[i]);
     716     if(strlen(temp_vector[i]) > 0){
     717       countries[j] = strdup(temp_vector[i]);
     718       g_strup(countries[j]);
     719       printf("DEBUG: got a country country[%i] =.%s.,\n", j, countries[j]);
     720       j++;
     721     }
     722   }
     723   countries[j] = NULL; /* mark the end of array */
     724   printf("DEBUG: countries[%i] = NULL\n", j);
     725
     726
     727   //test_mode = ca_get_testmode;
     728
     729   printf("TMPDIR is: [%s]\n", tmpdir);
     730   printf("MAILCMD is: [%s]\n", mailcmd);
     731   printf("NOTITXT is: [%s]\n", notitxt);
     732   printf("CROSSLOG is: [%s]\n", crosslog);
     733   printf("FWTXT is: [%s]\n", fwtxt);
     734   printf("HUMAILBOX is: [%s]\n", humailbox);
     735   printf("OVERRIDECRYPTEDPW is: [%s]\n", overridecryptedpw);
     736   printf("ACKLOG is: [%s]\n", acklog);
     737   printf("NOTIFLOG is: [%s]\n", notiflog);
     738   printf("FORWLOG is: [%s]\n", forwlog);
     739   printf("NOTIMAILTXT is: [%s]\n", notimailtxt);
     740   printf("FWMAILTXT is: [%s]\n", fwmailtxt);
     741   printf("COUNTRY is: [%s]\n", country);
     742   printf("PGPPATH is: [%s]\n", pgppath);
     743
     744   printf("TESTMODE is: [%i]\n", test_mode);
     745   /* end of config stuff */
     746
     747
     748
     749   /* initialize the parser */
     750   schema.initialize();
     751
     752
     753   /* Generate a name for temporary file for storing acks (AK_ack_file_name_generate
     754       also creates it) */
     755   ack_file_name = AK_ack_file_name_generate(tmpdir, ACK_FILE_PREFIX);
     756
     757
     758   /* Allocate memory for the header */
     759   mail_header = (MM_header *)malloc(sizeof(MM_header));
     760
     761   /* Initialize the list of extracted MIME parts */
     762   part_list = (MM_xmp_list *)malloc(sizeof(MM_xmp_list));
     763   MM_xmp_list_init (part_list);
     764
     765
     766   if(reading_from_mail){
     767     if(input_file_name != NULL){
     768       if((retcode = MM_decode(input_file_name, mail_header, part_list, 1, 0)) != 0){
     769         printf("DEBUG: MM_decode returned %i\n", retcode);
     770         exit(retcode);
     771       }
     772
     773     }else{/* input_file_name == NULL */
     774       temp_upd_file = generate_upd_file();
     775       MM_store("-", temp_upd_file, 0);
     776       if((retcode = MM_decode(temp_upd_file, mail_header, part_list, 1, 0)) != 0){
     777         printf("DEBUG: MM_decode returned %i\n", retcode);
     778         exit(retcode);
     779       }
     780
     781     }
     782         unlink(temp_upd_file);
     783         printf ("Mail headers:\n\n");
     784         printf ("From - [%s]",mail_header->from);
     785         /* some MAIL-FROM's in mntner auths contain "From: " string too,
     786            so we have to have it in credential.from */
     787         temp = (char *)malloc(strlen(mail_header->from) + strlen("From: ") + 1);
     788         sprintf(temp, "From: %s", mail_header->from);
     789         temp[strlen(temp) - 4] = '\0'; /* cut two '\r\n's at the end */
     790         credentials.from = temp;
     791         printf ("credentials.from = [%s]\n", credentials.from );
     792         mail_header->subject[strlen(mail_header->subject) - 4] = '\0';
     793         printf ("Subject - [%s]",mail_header->subject);
     794         printf ("Date - [%s]",mail_header->date);
     795         printf ("Message-ID - [%s]",mail_header->message_id);
     796         printf ("Reply-To - [%s]",mail_header->reply_to);
     797         printf ("Cc - [%s]",mail_header->cc);
     798         to_address = find_to_address(credentials.from);
     799         AK_add_to_ack(ack_file_name, "To: %s\nFrom: %s\nSubject: Re: %s \nReply-To: %s\n\nAcknowledgement message from database software, beta version\n", to_address, humailbox, mail_header->subject, humailbox);
     800         if(credentials.from != NULL){
     801           AK_add_to_ack(ack_file_name, "\n[%s]\n", credentials.from);
     802         }
     803
     804         partptr = part_list->head;
     805         while (partptr != NULL){
     806
     807           printf("-----------------------------------------\n");
     808           printf ("Section: %s\n",partptr->number);
     809           printf ("Content-type: %s\n",partptr->type);
     810           if (partptr->supported){
     811             printf ("Supported\n");
     812             printf ("Filename is [%s]\n", partptr->file);
     813             process_file(partptr->file, credentials,
     814                   AUTO_NIC_hdl_hash, ack_file_name,
     815                   ntfy_hash, forw_hash, cross_hash);
     816           }
     817           else
     818             printf ("Unsupported\n");
     819           printf ("\n\n");
     820           partptr = partptr->next;
     821         }
     822
     823
     824       /* Clean up the temporary files */
     825       MM_cleanup(part_list, 0);
     826
     827
     828   }else{/* not reading from the mail message */
     829     if(input_file_name != NULL){
     830       process_file(input_file_name, credentials,
     831                   AUTO_NIC_hdl_hash, ack_file_name,
     832                   ntfy_hash, forw_hash, cross_hash);
     833     }
     834
     835   }
     836
     837
     838   if(reading_from_mail && to_address != NULL){
     839     AK_send_ack(ack_file_name, to_address, mailcmd);
     840   }
     841   AK_log_ack(ack_file_name, acklog);
     842   AK_delete_ack(ack_file_name);
     843
     844   NT_send_ntfy_list(ntfy_hash, mailcmd);
     845   NT_log_ntfy_list(ntfy_hash, notiflog);
     846   NT_delete_ntfy_list(ntfy_hash);
     847
     848   NT_send_ntfy_list(forw_hash, mailcmd);
     849   NT_log_ntfy_list(forw_hash, forwlog);
     850   //NT_delete_ntfy_list(forw_hash);
     851
     852
     853
     854   if(tracing) {
     855     printf("TRACING: END\n");
     856   }
     857
     858
     859 }

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