## modules/nt/notification.cc

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

## FUNCTIONS

This source file includes following functions.

1. NT_ntfy_filename_generate
2. NT_forwd_filename_generate
3. NT_cross_filename_generate
4. NT_crossntfy_filename_generate
5. NT_add_to_ntfy_hash
6. NT_add_to_frwd_hash
7. NT_add_to_cross_hash
8. NT_add_to_ntfy_hash_list
9. NT_add_to_frwd_hash_list
10. NT_add_to_cross_hash_list
11. NT_add_to_ntfy
12. NT_add_to_cross
13. NT_add_to_ntfy_list
14. NT_send_ntfy
15. NT_log_ntfy
16. NT_delete_ntfy
17. nt_gfunc_send
18. NT_send_ntfy_list
19. nt_gfunc_log
20. NT_log_ntfy_list
21. nt_gfunc_delete
22. NT_delete_ntfy_list
23. nt_add_to_list
24. NT_unify_list
25. NT_gather_ntfy_addresses
26. NT_gather_frwd_addresses
27. get_overlapping_routes_list
28. NT_write_all_ntfs
29. NT_write_all_frwds
30. NT_send_forw_creation
31. NT_forw_create_req

       1 /***************************************
       2   $Revision: 1.20 $
       3
       4   NT (Notifications) module
       5
       6   Status: NOT REVIEWED, NOT TESTED
       7
       8   Author(s):       Engin Gunduz
       9
      10   ******************/ /******************
      11   Modification History:
      12         engin (06/07/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
      39 #include "notification.h"
      40 extern int supress_ack_notif;
      41 extern char * defmail;
      42 extern int reading_from_mail;
      43
      44 /*  Generates a unique file name and returns the full path of the filename
      45     for storing notification message.  Creates the file at the same time.
      46     May use PID or time or both to ensure uniqueness.  */
      47
      48 char * NT_ntfy_filename_generate( const char * tmpdir, const char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
      49
      50    FILE * ntfy_file;
      51    char * name;
      52    char * replaced_notimailtxt;
      53    char * replaced_notinetworktxt;
      54
      55    /* allocate space for name.  32 should be enough for PID */
      56    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("notify") +32 );
      57
      58    sprintf(name, "%s/%s-%s.%i", tmpdir, "notify", e_mail, getpid());
      59
      60    /* create the file */
      61    if(( ntfy_file = fopen(name, "w")) == NULL){
      62      fprintf(stderr, "Can't open notification file for creating, %s", name);
      63    }
      64
      65    fprintf(ntfy_file, "To: %s\nFrom: %s\nSubject: Notification of RIPE Database changes\nReply-To: %s\n\n%s\n", e_mail, humailbox, humailbox, notitxt);
      66    if(reading_from_mail){
      67      replaced_notimailtxt = UP_replace_globals(notimailtxt);
      68      fprintf(ntfy_file, "%s\n\n", replaced_notimailtxt);
      69      free(replaced_notimailtxt);
      70    }
      71
      72    if(networkupdate){
      73      replaced_notinetworktxt = UP_replace_globals(notinetworktxt);
      74      fprintf(ntfy_file, "%s\n\n", replaced_notinetworktxt);
      75      free(replaced_notinetworktxt);
      76    }
      77
      78    /* close it */
      79    fclose(ntfy_file);
      80
      81    return name;
      82
      83 }
      84
      85
      86
      87
      88
      89 /* Generates a unique file name and returns the full path of the filename
      90    for storing forwarded message. Creates the file at the same time.  */
      91 char * NT_forwd_filename_generate( const char * tmpdir, const char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
      92
      93    FILE * forwd_file;
      94    char * name;
      95    char * replaced_fwmailtxt;
      96
      97    /* allocate space for name.  32 should be enough for PID */
      98    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("forwd") +32 );
      99
     100    sprintf(name, "%s/%s-%s.%i", tmpdir, "forwd", e_mail, getpid());
     101    /* create the file */
     102    if(( forwd_file = fopen(name, "w")) == NULL){
     103      fprintf(stderr, "Can't open forward file, %s", name);
     104    }
     105
     106    fprintf(forwd_file, "To: %s\nFrom: %s\nSubject:  Requested RIPE database object changes \nReply-To: %s\n\n%s\n", e_mail, humailbox, humailbox, fwtxt);
     107    if(reading_from_mail){
     108      replaced_fwmailtxt = UP_replace_globals(fwmailtxt);
     109      fprintf(forwd_file, "\n%s\n", replaced_fwmailtxt);
     110      free(replaced_fwmailtxt);
     111    }
     112
     113    /* close it */
     114    fclose(forwd_file);
     115
     116    return name;
     117
     118 }
     119
     120
     121
     122
     123
     124 /* Generates a unique file name and returns the full path of the filename
     125    for storing cross notification message. Creates the file at the same time.  */
     126 char * NT_cross_filename_generate( const char * tmpdir, const char * e_mail, int mode){
         /* [<][>][^][v][top][bottom][index][help] */
     127
     128    FILE * cross_file;
     129    char * name;
     130
     131    /* allocate space for name.  32 should be enough for PID */
     132    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +32 );
     133
     134    sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, getpid());
     135    /* create the file */
     136    if(( cross_file = fopen(name, "w")) == NULL){
     137      fprintf(stderr, "Can't open cross notif file, %s", name);
     138    }
     139
     140    if(mode == ADDITION){
     141      fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_add, humailbox);
     142    }else{
     143      fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_del, humailbox);
     144    }
     145
     146    /* close it */
     147    fclose(cross_file);
     148
     149    return name;
     150
     151 }
     152
     153
     154
     155
     156
     157
     158
     159 /* Generates a unique file name and returns the full path of the filename for
     160    storing notification message. Creates the file at the same time.  */
     161 char * NT_crossntfy_filename_generate( const char * tmpdir, const char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
     162    FILE * cross_file;
     163    char * name;
     164
     165    /* allocate space for name.  32 should be enough for PID */
     166    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +32 );
     167
     168    sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, getpid());
     169
     170    /* create the file */
     171    if(( cross_file = fopen(name, "w")) == NULL){
     172      fprintf(stderr, "Can't open cross file, %s", name);
     173    }
     174
     175    /* close it */
     176    fclose(cross_file);
     177
     178    return name;
     179
     180 }
     181
     182
     183
     184
     185
     186 /* Adds the e-mail to the notify hash, generating appropriate temp files */
     187 void NT_add_to_ntfy_hash(GHashTable * ntfy_hash, char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
     188
     189   if(g_hash_table_lookup(ntfy_hash ,e_mail) == NULL){/* there is no such entry, so create it */
     190
     191     g_hash_table_insert(ntfy_hash, strdup(e_mail), NT_ntfy_filename_generate(tmpdir, e_mail));
     192
     193   }
     194
     195 }
     196
     197
     198
     199
     200 /* Adds the e-mail to the forw hash, generating appropriate temp files */
     201 void NT_add_to_frwd_hash(GHashTable * frwd_hash, char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
     202
     203   if(g_hash_table_lookup(frwd_hash ,e_mail) == NULL){/* there is no such entry, so create it */
     204     g_hash_table_insert(frwd_hash, strdup(e_mail), NT_forwd_filename_generate(tmpdir, e_mail));
     205   }
     206
     207 }
     208
     209
     210
     211
     212
     213 /* Adds the e-mail to the cross hash, generating appropriate temp files */
     214 void NT_add_to_cross_hash(GHashTable * cross_hash, const char * e_mail, int mode){
         /* [<][>][^][v][top][bottom][index][help] */
     215
     216   /*  if e-mail is NULL, immediately return */
     217   if(e_mail == NULL){
     218     return;
     219   }
     220
     221   if(g_hash_table_lookup(cross_hash ,e_mail) == NULL){/* there is no such entry, so create it */
     222     g_hash_table_insert(cross_hash, strdup(e_mail), NT_cross_filename_generate(tmpdir, e_mail, mode));
     223   }
     224
     225 }
     226
     227
     228
     229
     230
     231 /* Adds the e-mails in a linked list to the hash */
     232 void NT_add_to_ntfy_hash_list(GHashTable * ntfy_hash, GSList * e_mail_list){
         /* [<][>][^][v][top][bottom][index][help] */
     233
     234    GSList * temp = NULL;
     235
     236    for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
     237      NT_add_to_ntfy_hash(ntfy_hash, (char *)temp->data);
     238    }
     239
     240 }
     241
     242
     243
     244
     245 /* Adds the e-mails in a linked list to the hash */
     246 void NT_add_to_frwd_hash_list(GHashTable * frwd_hash, GSList * e_mail_list){
         /* [<][>][^][v][top][bottom][index][help] */
     247
     248    GSList * temp = NULL;
     249
     250    for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
     251      NT_add_to_frwd_hash(frwd_hash, (char *)temp->data);
     252    }
     253
     254 }
     255
     256
     257
     258 /* Adds the e-mails in a linked list to the hash */
     259 void NT_add_to_cross_hash_list(GHashTable * cross_hash, GSList * e_mail_list, int mode){
         /* [<][>][^][v][top][bottom][index][help] */
     260
     261    GSList * temp = NULL;
     262
     263    for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
     264      NT_add_to_cross_hash(cross_hash, (char *)temp->data, mode);
     265    }
     266
     267 }
     268
     269
     270
     271
     272
     273
     274 /* Appends the argument strings to the file.  */
     275 void NT_add_to_ntfy( char * filename, char * fmt, ... ){
         /* [<][>][^][v][top][bottom][index][help] */
     276   va_list ap;  /* points to each unnamed arg in turn */
     277   FILE * ntfy_file;
     278
     279   if(tracing){
     280     printf("TRACING: NT_add_to_ntfy\n");
     281   }
     282   if(( ntfy_file = fopen(filename, "a")) == NULL){
     283     fprintf(stderr, "Can't open notification file for writing, %s\n", filename);
     284     return;
     285   }
     286
     287   va_start(ap, fmt);
     288   vfprintf(ntfy_file, fmt, ap);
     289
     290   va_end(ap); /* clean up */
     291   fclose(ntfy_file);
     292 }
     293
     294
     295
     296 /* Appends the argument strings to the file.  */
     297 void NT_add_to_cross(const char * e_mail, GHashTable * hash, char * fmt, ...){
         /* [<][>][^][v][top][bottom][index][help] */
     298
     299   va_list ap;  /* points to each unnamed arg in turn */
     300   FILE * cross_file;
     301   char * filename;
     302
     303   /* if e-mail is NULL, immediately return */
     304   if(e_mail == NULL){
     305     return;
     306   }
     307
     308   if(g_hash_table_lookup(hash, find_email_address(e_mail)) != NULL){
     309     filename = (char *)g_hash_table_lookup(hash, find_email_address(e_mail));
     310   }else{
     311     fprintf(stderr, "Can't find a cross notification file for e-mail %s\n", e_mail);
     312     return;
     313   }
     314
     315   if(( cross_file = fopen(filename, "a")) == NULL){
     316     fprintf(stderr, "Can't open cross notification file, %s\n", filename);
     317   }
     318
     319
     320
     321   if(tracing){
     322     printf("TRACING: NT_add_to_cross\n");
     323   }
     324   if(( cross_file = fopen(filename, "a")) == NULL){
     325     fprintf(stderr, "Can't open cross notification file for writing, %s\n", filename);
     326   }
     327
     328   va_start(ap, fmt);
     329   vfprintf(cross_file, fmt, ap);
     330
     331   va_end(ap); /* clean up */
     332   fclose(cross_file);
     333
     334
     335 }
     336
     337
     338
     339
     340
     341 /* Appends the argument string to the temp notif files in the list */
     342 void NT_add_to_ntfy_list(GSList * list, GHashTable * hash, char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
     343
     344   GSList * temp = NULL;
     345
     346   for(temp = list; temp != NULL; temp = g_slist_next(temp)){
     347     NT_add_to_ntfy((char *)g_hash_table_lookup(hash, ((char *)temp->data)), arg);
     348   }
     349 }
     350
     351
     352
     353
     354
     355
     356
     357
     358 /* Sends the notification message which is stored in the temporary filefilename.  */
     359 void NT_send_ntfy( const char * filename, const char * to_address, const char * mailercommand){
         /* [<][>][^][v][top][bottom][index][help] */
     360
     361     char * mail_command_line = NULL;
     362     char * supress_file = NULL;
     363     FILE * notif_file, * supr_file_hdl;
     364     char buf[1024];
     365
     366
     367     /* if we are not supressing acks and notifs, send the notif */
     368     if(!supress_ack_notif){
     369       if(to_address != NULL){
     370         mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
     371         sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
     372         system(mail_command_line);
     373       }
     374     /* if we are supressing acks and notifs, send notif to DEFMAIL  */
     375     }else{
     376       supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2);
     377       sprintf(supress_file, "%s.supress", filename);
     378       if(( supr_file_hdl = fopen(supress_file, "w")) == NULL){
     379         fprintf(stderr, "Can't open supress notif file, %s", supress_file);
     380       }else{
     381         fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed notif mail\n\n",
     382             humailbox, defmail);
     383         if(( notif_file = fopen(filename, "r")) == NULL){
     384           fprintf(stderr, "Can't open notif file for reading, %s", filename);
     385         }else{
     386           while(fgets(buf, 1023, notif_file) != NULL){
     387             fprintf(supr_file_hdl, buf);
     388           }
     389           fclose(notif_file);
     390         }
     391       }
     392       fclose(supr_file_hdl);
     393       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail)
     394             + strlen(supress_file) + 128);
     395       sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
     396       system(mail_command_line);
     397       unlink(supress_file);
     398       free(supress_file);
     399     }
     400
     401
     402 }
     403
     404
     405
     406 /* Adds the notification message which is in the filename into "logfilename.date". */
     407 void NT_log_ntfy( const char * filename, const char * logfilename){
         /* [<][>][^][v][top][bottom][index][help] */
     408
     409   FILE * notif_file, * log_file;
     410   char * buf;
     411   time_t cur_time;
     412   char * time_str;
     413   char * logfile_date;
     414   char * date;
     415
     416   buf = (char *)malloc(1024);
     417   if(( notif_file = fopen(filename, "r")) == NULL){
     418     fprintf(stderr, "Can't open notification file for reading, [%s]\n", filename);
     419     return;
     420   }
     421
     422   /* construct the "logfilename.date" string */
     423   logfile_date = (char *)malloc(strlen(logfilename) + 10);
     424   date = UP_get_current_date();
     425   snprintf(logfile_date, strlen(logfilename) + 10, "%s.%s", logfilename, date);
     426   free(date);
     427
     428   if(( log_file = fopen(logfile_date, "a")) == NULL){
     429     fprintf(stderr, "Can't open log file, %s\n", logfilename);
     430     return;
     431   }
     432
     433   /* get time */
     434   cur_time = time(NULL);
     435   time_str = strdup(ctime(&cur_time));
     436   /* cut the '\n' at the end */
     437   time_str[strlen(time_str) - 1] = '\0';
     438
     439   fprintf(log_file, ">>> time: %s NOTIF <<<\n\n", time_str);
     440
     441
     442   while((buf=fgets(buf, 1023, notif_file)) > 0){
     443     fprintf(log_file, "%s", buf);
     444   }
     445   free(buf);
     446
     447   fclose(notif_file);
     448   fclose(log_file);
     449
     450 }
     451
     452
     453 /* Deletes the temporary notification file. */
     454 void NT_delete_ntfy( const char * filename){
         /* [<][>][^][v][top][bottom][index][help] */
     455
     456    unlink(filename);
     457
     458 }
     459
     460
     461 /* The function required for NT_send_ntfy_list */
     462 void  nt_gfunc_send(gpointer key, gpointer value, gpointer user_data){
         /* [<][>][^][v][top][bottom][index][help] */
     463   NT_send_ntfy((char *)value, (char *)key, (char *)user_data);
     464 }
     465
     466
     467
     468 /* Sends the notification messages whose temp files are stored in filehash. */
     469 void NT_send_ntfy_list( GHashTable * filehash, char * mailercommand){
         /* [<][>][^][v][top][bottom][index][help] */
     470
     471   g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_send, mailercommand);
     472
     473 }
     474
     475
     476
     477
     478 /* The function required for NT_log_ntfy_list */
     479 void  nt_gfunc_log(gpointer key, gpointer value, gpointer user_data){
         /* [<][>][^][v][top][bottom][index][help] */
     480   NT_log_ntfy((char *)value, (char *)user_data);
     481 }
     482
     483
     484
     485
     486 /* Logs the notification whose temp files are in filehash to log_file. */
     487 void NT_log_ntfy_list( GHashTable * filehash, char * log_file){
         /* [<][>][^][v][top][bottom][index][help] */
     488
     489    g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_log, log_file);
     490
     491 }
     492
     493
     494
     495 /* The function required for NT_delete_ntfy_list */
     496 void  nt_gfunc_delete(gpointer key, gpointer value, gpointer user_data){
         /* [<][>][^][v][top][bottom][index][help] */
     497   NT_delete_ntfy((char *)value);
     498 }
     499
     500
     501
     502 /* Deletes the temporary notification messages in the filehash. Empties and frees
     503    the hash too.  */
     504 void NT_delete_ntfy_list( GHashTable * filehash){
         /* [<][>][^][v][top][bottom][index][help] */
     505
     506   g_hash_table_foreach(filehash, (GHFunc)nt_gfunc_delete, NULL);
     507   g_hash_table_destroy(filehash);
     508
     509 }
     510
     511
     512 /* to be used with g_hash_table_foreach in NT_unify_list.
     513    Adds the 'key' to the list (a GSList) */
     514 void nt_add_to_list(char * key, char * value, GSList ** list){
         /* [<][>][^][v][top][bottom][index][help] */
     515
     516   *list = g_slist_append(*list, strdup(value));
     517
     518
     519 }
     520
     521
     522
     523 /* "unifies" a list in a case insensitive manner */
     524 GSList * NT_unify_list(GSList * in_list){
         /* [<][>][^][v][top][bottom][index][help] */
     525
     526   GHashTable * unification_hash;
     527   GSList ** out_list;
     528   GSList * temp;
     529   char * key, * value;
     530
     531   /* allocate space for out_list */
     532   out_list = (GSList **)malloc(sizeof(GSList *));
     533   *out_list = NULL;
     534
     535   /* initialize the hash to be used for unification process */
     536   unification_hash = g_hash_table_new(g_str_hash, g_str_equal);
     537
     538   /* first put the list elements into a hash, to unify them */
     539   for(temp = in_list; temp != NULL; temp = g_slist_next(temp)){
     540
     541     /* convert the string into lowercase */
     542     key = strdup((char *)(temp->data));
     543     g_strdown(key);
     544     value = strdup((char *)(temp->data));
     545
     546     if(g_hash_table_lookup(unification_hash, key) == NULL){/* if it is not there */
     547
     548       g_hash_table_insert(unification_hash, key, value);
     549
     550     }
     551   }
     552
     553   /* now, get the elements back from the hash into a list */
     554   g_hash_table_foreach(unification_hash, (GHFunc)nt_add_to_list, out_list);
     555
     556   g_slist_free(in_list);
     557   g_hash_table_destroy(unification_hash);
     558
     559   return *out_list;
     560
     561 }
     562
     563
     564
     565
     566
     567
     568
     569
     570 /* Gathers e-mail boxes to which we will send normal notification messages. It
     571    takes old and new objects, looks up maintainers and less specific inetnums/domains/routes
     572    when necessary, finds the addresses (in mnt-nfy and notify attributes) and returns
     573    a list of them. */
     574 GSList * NT_gather_ntfy_addresses( char * old_object, char * new_object){
         /* [<][>][^][v][top][bottom][index][help] */
     575   GSList * return_list = NULL, * temp = NULL;
     576   GSList * mntners = NULL;
     577
     578   if(old_object != NULL && new_object != NULL){/* it was an update */
     579     temp = get_attr_list(old_object, "notify");
     580     mntners = get_mntners(old_object);
     581     temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
     582   }else if(old_object == NULL && new_object != NULL){/* it was a creation */
     583     temp = get_attr_list(new_object, "notify");
     584     mntners = get_mntners(new_object);
     585     temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
     586   }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
     587     temp = get_attr_list(old_object, "notify");
     588     mntners = get_mntners(old_object);
     589     temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
     590   }
     591
     592   /* we have to 'unify' the list here! */
     593   return_list = NT_unify_list(temp);
     594
     595   return return_list;
     596 }
     597
     598
     599
     600 /* Gathers e-mail boxes to which we will forward messages (or rather, objects). It
     601    an object, looks up maintainers, finds the addresses (in upd-to attributes) and returns
     602    a list of them. */
     603 GSList * NT_gather_frwd_addresses(char * object){
         /* [<][>][^][v][top][bottom][index][help] */
     604   GSList *temp = NULL;
     605   GSList * mntners = NULL;
     606
     607   mntners = get_mntners(object);
     608   temp = get_updto_vector(mntners);
     609   return temp;
     610 }
     611
     612
     613
     614
     615 /* Accepts a route object as a "* char" and returns a list of overlapping routes */
     616 overlap_routes get_overlapping_routes_list(char * object){
         /* [<][>][^][v][top][bottom][index][help] */
     617
     618   char * route_prefix = NULL;
     619   GSList * tmp_list;
     620   char * result;
     621   char * query_string;
     622   overlap_routes result_routes;
     623   char * origin;
     624   bool code;
     625
     626
     627   result_routes.less_spec = NULL;
     628   result_routes.exact_match = NULL;
     629   result_routes.more_spec = NULL;
     630
     631   tmp_list = get_attr_list(object, "route");
     632
     633   if(tmp_list != NULL && tmp_list->data != NULL){
     634     route_prefix = strdup((char *)(tmp_list->data));
     635   }else{
     636     return result_routes; /* then, this wasn't a route object */
     637   }
     638
     639   /* get the less specific route objects */
     640   /* form the query string */
     641   query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(route_prefix) + 2);
     642   sprintf(query_string, "-Troute -r -l %s", route_prefix);
     643
     644   /* get the results */
     645   result = send_and_get(query_host, query_port, query_string);
     646   free(query_string);
     647
     648   /* and fill in the result field  */
     649   result_routes.less_spec = take_objects(result);
     650
     651   /* get the exact match route objects */
     652   /* form the query string */
     653   query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(route_prefix) + 2);
     654   sprintf(query_string, "-Troute -r -x %s", route_prefix);
     655
     656   /* get the results */
     657   result = send_and_get(query_host, query_port, query_string);
     658   free(query_string);
     659
     660
     661   /* filter out the route object itself */
     662   result = filter_out_same_origins(result, object);
     663
     664   /* and fill in the result field  */
     665   if(result != NULL){
     666     result_routes.exact_match = take_objects(result);
     667   }
     668
     669
     670   /* get the more specific route objects */
     671   /* form the query string */
     672   query_string = (char *)malloc(strlen("-Troute -r -M ") + strlen(route_prefix) + 2);
     673   sprintf(query_string, "-Troute -r -M %s", route_prefix);
     674
     675   /* get the results */
     676   result = send_and_get(query_host, query_port, query_string);
     677   free(query_string);
     678
     679   /* and fill in the result field  */
     680   result_routes.more_spec = take_objects(result);
     681
     682   /* Return the results */
     683   return result_routes;
     684
     685 }
     686
     687
     688
     689
     690
     691 /* Gets old and new versions of the object, and creates temporary notification
     692    files when necessary, and then writes appropriate strings into those
     693    temporary files. */
     694 void NT_write_all_ntfs(char * old_object, char * new_object, char * formatted_object,
         /* [<][>][^][v][top][bottom][index][help] */
     695                        const char * tempdir,
     696                        GHashTable * ntfy_hash,  GHashTable * forwd_hash, GHashTable * cross_hash,
     697                        char * from_address){
     698
     699    GSList * e_mail_list = NULL;
     700    GSList * temp = NULL;
     701    char * e_mail_address;
     702    overlap_routes overlapping_routes;
     703
     704    /* from_address may contain also the name, like "Johnny Bravo <johnny@inter.net>",
     705       so extract the e-mail address from it */
     706    e_mail_address = find_email_address(from_address);
     707
     708
     709    if(tracing && reading_from_mail){
     710      printf("TRACING: NT_write_all_ntfs: from_address=[%s], e_mail_address=[%s]\n", from_address, e_mail_address);
     711    }
     712    if(old_object != NULL && new_object != NULL){/* it was an update */
     713      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
     714      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
     715      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nPREVIOUS OBJECT:\n\n");
     716      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
     717      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n\nREPLACED BY:\n\n");
     718      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, new_object);
     719      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
     720    }else if(old_object == NULL && new_object != NULL){/* it was a creation */
     721      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
     722      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
     723      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW CREATED:\n\n");
     724      NT_add_to_ntfy_list(e_mail_list, ntfy_hash,
     725             formatted_object ? formatted_object : new_object);
     726      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
     727      /* We'll deal with cross notifications only when we create or delete route objects */
     728      if(strcmp(get_class_type_char(new_object), "route") == 0){
     729        overlapping_routes = get_overlapping_routes_list(new_object);
     730        if(overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
     731           overlapping_routes.more_spec != NULL ){
     732          NT_add_to_cross_hash(cross_hash, e_mail_address, ADDITION);
     733          NT_add_to_cross(e_mail_address, cross_hash, "%s\n\n%s\n\n%s\n\n", cno_explain_add, new_object, cno_overlap_add);
     734          if(overlapping_routes.less_spec != NULL){
     735            NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
     736            for(temp = overlapping_routes.less_spec; temp != NULL; temp = g_slist_next(temp)){
     737              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     738            }
     739          }
     740          if(overlapping_routes.exact_match != NULL){
     741            NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
     742            for(temp = overlapping_routes.exact_match; temp != NULL; temp = g_slist_next(temp)){
     743              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     744            }
     745          }
     746          if(overlapping_routes.more_spec != NULL){
     747            NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
     748            for(temp = overlapping_routes.more_spec; temp != NULL; temp = g_slist_next(temp)){
     749              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     750            }
     751          }
     752        }
     753      }
     754    }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
     755      old_object = delete_delete_attrib(old_object);
     756      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
     757      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
     758      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW DELETED:\n\n");
     759      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
     760      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
     761      /* We'll deal with cross notifications only when we create or delete route objects */
     762      if(strcmp(get_class_type_char(old_object), "route") == 0){
     763        overlapping_routes = get_overlapping_routes_list(old_object);
     764        if(overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
     765           overlapping_routes.more_spec != NULL ){
     766          NT_add_to_cross_hash(cross_hash, e_mail_address, DELETION);
     767          NT_add_to_cross(e_mail_address, cross_hash, "%s\n\n%s\n\n%s\n\n", cno_explain_del, old_object, cno_overlap_del);
     768          if(overlapping_routes.less_spec != NULL){
     769            NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
     770            for(temp = overlapping_routes.less_spec; temp != NULL; temp = g_slist_next(temp)){
     771              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     772            }
     773          }
     774          if(overlapping_routes.exact_match != NULL){
     775            NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
     776            for(temp = overlapping_routes.exact_match; temp != NULL; temp = g_slist_next(temp)){
     777              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     778            }
     779          }
     780          if(overlapping_routes.more_spec != NULL){
     781            NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
     782            for(temp = overlapping_routes.more_spec; temp != NULL; temp = g_slist_next(temp)){
     783              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     784            }
     785          }
     786        }
     787      }
     788    }
     789 }
     790
     791
     792
     793
     794
     795 /* Gets old and new versions of the object, and creates temporary notification
     796    files when necessary, and then writes appropriate strings into those
     797    temporary files. */
     798 void NT_write_all_frwds(char * old_object, char * new_object, const char * tempdir,
         /* [<][>][^][v][top][bottom][index][help] */
     799                        GHashTable * ntfy_hash,  GHashTable * forwd_hash, GHashTable * cross_hash,
     800                        const char * from_address){
     801
     802    GSList * e_mail_list = NULL;
     803
     804
     805    if(tracing){
     806      printf("TRACING: NT_write_all_frwds\n");
     807    }
     808    if(old_object != NULL && new_object != NULL){/* it was an update */
     809      e_mail_list = NT_gather_frwd_addresses(old_object);
     810      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
     811      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nUPDATE REQUESTED FOR:\n\n");
     812      NT_add_to_ntfy_list(e_mail_list, forwd_hash, new_object);
     813    }else if(old_object == NULL && new_object != NULL){/* it was a creation */
     814      e_mail_list = NT_gather_frwd_addresses(new_object);
     815      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
     816      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nADDITION REQUESTED FOR:\n\n");
     817      NT_add_to_ntfy_list(e_mail_list, forwd_hash, new_object);
     818    }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
     819      e_mail_list = NT_gather_frwd_addresses(old_object);
     820      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
     821      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nDELETION REQUESTED FOR:\n\n");
     822      NT_add_to_ntfy_list(e_mail_list, forwd_hash, old_object);
     823    }
     824 }
     825
     826
     827
     828 /* Sends the creation forward message which is stored in the temporary filefilename.  */
     829 void NT_send_forw_creation( const char * filename, const char * to_address, const char * mailercommand){
         /* [<][>][^][v][top][bottom][index][help] */
     830
     831     char * mail_command_line = NULL;
     832
     833
     834     if(to_address != NULL){
     835       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
     836       sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
     837       system(mail_command_line);
     838       free(mail_command_line);
     839     }
     840
     841 }
     842
     843
     844
     845
     846
     847 /* NT_forw_create_req forwards the maintainer and as-block creation requests
     848    to <HUMAILBOX> */
     849 void NT_forw_create_req(const char * object){
         /* [<][>][^][v][top][bottom][index][help] */
     850
     851    FILE * forw_file;
     852    char * name;
     853    char * replaced_mtfwheader;
     854    char * replaced_mtfwtxt;
     855
     856    /* allocate space for name.  32 should be enough for PID */
     857    name = (char*)malloc(strlen(tmpdir) + strlen("creat-forw") +32 );
     858
     859    sprintf(name, "%s/%s.%i", tmpdir, "creat-forw", getpid());
     860
     861    /* create the file */
     862    if(( forw_file = fopen(name, "w")) == NULL){
     863      fprintf(stderr, "Can't open creation forward file for creating, %s", name);
     864    }
     865
     866    replaced_mtfwheader = UP_replace_globals(mtfwheader);
     867    replaced_mtfwtxt = UP_replace_globals(mtfwtxt);
     868
     869    fprintf(forw_file, "%s\n\n", replaced_mtfwheader);
     870
     871    if(reading_from_mail){
     872      fprintf(forw_file, "%s\n\n", replaced_mtfwtxt);
     873    }
     874
     875    /* print the object */
     876    fprintf(forw_file, "%s\n\n", object);
     877
     878    /* close it */
     879    fclose(forw_file);
     880
     881    /* send it */
     882    NT_send_forw_creation(name, humailbox, mailcmd);
     883
     884    /* delete it */
     885    unlink(name);
     886
     887    /* free the mem */
     888    free(name);
     889    free(replaced_mtfwheader);
     890    free(replaced_mtfwtxt);
     891 }

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