## 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_gather_ntfy_addresses
24. NT_gather_frwd_addresses
25. get_overlapping_routes_list
26. NT_write_all_ntfs
27. NT_write_all_frwds

       1 /***************************************
       2   $Revision: 1.10 $
       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
      41
      42 /*  Generates a unique file name and returns the full path of the filename
      43     for storing notification message.  Creates the file at the same time.
      44     May use PID or time or both to ensure uniqueness.  */
      45
      46 char * NT_ntfy_filename_generate( const char * tmpdir, const char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
      47
      48    FILE * ntfy_file;
      49    char * name;
      50
      51    /* allocate space for name.  32 should be enough for PID */
      52    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("notify") +32 );
      53
      54    sprintf(name, "%s/%s-%s.%i", tmpdir, "notify", e_mail, getpid());
      55
      56    /* create the file */
      57    if(( ntfy_file = fopen(name, "w")) == NULL){
      58      fprintf(stderr, "Can't open notification file for creating, %s", name);
      59    }
      60
      61    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);
      62    if(reading_from_mail){
      63      fprintf(ntfy_file, "%s\n\n", notimailtxt);
      64    }
      65    /* close it */
      66    fclose(ntfy_file);
      67
      68    return name;
      69
      70 }
      71
      72
      73
      74
      75
      76 /* Generates a unique file name and returns the full path of the filename
      77    for storing forwarded message. Creates the file at the same time.  */
      78 char * NT_forwd_filename_generate( const char * tmpdir, const char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
      79
      80    FILE * forwd_file;
      81    char * name;
      82
      83    /* allocate space for name.  32 should be enough for PID */
      84    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("forwd") +32 );
      85
      86    sprintf(name, "%s/%s-%s.%i", tmpdir, "forwd", e_mail, getpid());
      87    //printf("DEBUG: NT_forwd_filename_generate: will generate %s\n", name);
      88    /* create the file */
      89    if(( forwd_file = fopen(name, "w")) == NULL){
      90      fprintf(stderr, "Can't open forward file, %s", name);
      91    }
      92
      93    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);
      94    if(reading_from_mail){
      95      fprintf(forwd_file, "\n%s\n", fwmailtxt);
      96    }
      97
      98    /* close it */
      99    fclose(forwd_file);
     100
     101    return name;
     102
     103 }
     104
     105
     106
     107
     108
     109 /* Generates a unique file name and returns the full path of the filename
     110    for storing cross notification message. Creates the file at the same time.  */
     111 char * NT_cross_filename_generate( const char * tmpdir, const char * e_mail, int mode){
         /* [<][>][^][v][top][bottom][index][help] */
     112
     113    FILE * cross_file;
     114    char * name;
     115
     116    /* allocate space for name.  32 should be enough for PID */
     117    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +32 );
     118
     119    sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, getpid());
     120    //printf("DEBUG: NT_cross_filename_generate: will generate %s\n", name);
     121    /* create the file */
     122    if(( cross_file = fopen(name, "w")) == NULL){
     123      fprintf(stderr, "Can't open cross notif file, %s", name);
     124    }
     125
     126    //printf("DEBUG: NT_cross_filename_generate: e_mail=[%s], humailbox=[%s]\n", e_mail, humailbox);
     127    if(mode == ADDITION){
     128      fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_add, humailbox);
     129    }else{
     130      fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_del, humailbox);
     131    }
     132
     133    /* close it */
     134    fclose(cross_file);
     135
     136    return name;
     137
     138 }
     139
     140
     141
     142
     143
     144
     145
     146 /* Generates a unique file name and returns the full path of the filename for
     147    storing notification message. Creates the file at the same time.  */
     148 char * NT_crossntfy_filename_generate( const char * tmpdir, const char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
     149    FILE * cross_file;
     150    char * name;
     151
     152    /* allocate space for name.  32 should be enough for PID */
     153    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +32 );
     154
     155    sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, getpid());
     156
     157    /* create the file */
     158    if(( cross_file = fopen(name, "w")) == NULL){
     159      fprintf(stderr, "Can't open cross file, %s", name);
     160    }
     161
     162    /* close it */
     163    fclose(cross_file);
     164
     165    return name;
     166
     167 }
     168
     169
     170
     171
     172
     173 /* Adds the e-mail to the notify hash, generating appropriate temp files */
     174 void NT_add_to_ntfy_hash(GHashTable * ntfy_hash, char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
     175
     176   if(g_hash_table_lookup(ntfy_hash ,e_mail) == NULL){/* there is no such entry, so create it */
     177     g_hash_table_insert(ntfy_hash, strdup(e_mail), NT_ntfy_filename_generate(tmpdir, e_mail));
     178   }
     179
     180 }
     181
     182
     183
     184
     185 /* Adds the e-mail to the forw hash, generating appropriate temp files */
     186 void NT_add_to_frwd_hash(GHashTable * frwd_hash, char * e_mail){
         /* [<][>][^][v][top][bottom][index][help] */
     187
     188   if(g_hash_table_lookup(frwd_hash ,e_mail) == NULL){/* there is no such entry, so create it */
     189     g_hash_table_insert(frwd_hash, strdup(e_mail), NT_forwd_filename_generate(tmpdir, e_mail));
     190   }
     191
     192 }
     193
     194
     195
     196
     197
     198 /* Adds the e-mail to the cross hash, generating appropriate temp files */
     199 void NT_add_to_cross_hash(GHashTable * cross_hash, const char * e_mail, int mode){
         /* [<][>][^][v][top][bottom][index][help] */
     200
     201   if(g_hash_table_lookup(cross_hash ,e_mail) == NULL){/* there is no such entry, so create it */
     202     g_hash_table_insert(cross_hash, strdup(e_mail), NT_cross_filename_generate(tmpdir, e_mail, mode));
     203   }
     204
     205 }
     206
     207
     208
     209
     210
     211 /* Adds the e-mails in a linked list to the hash */
     212 void NT_add_to_ntfy_hash_list(GHashTable * ntfy_hash, GSList * e_mail_list){
         /* [<][>][^][v][top][bottom][index][help] */
     213
     214    GSList * temp = NULL;
     215
     216    for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
     217      NT_add_to_ntfy_hash(ntfy_hash, (char *)temp->data);
     218    }
     219
     220 }
     221
     222
     223
     224
     225 /* Adds the e-mails in a linked list to the hash */
     226 void NT_add_to_frwd_hash_list(GHashTable * frwd_hash, GSList * e_mail_list){
         /* [<][>][^][v][top][bottom][index][help] */
     227
     228    GSList * temp = NULL;
     229
     230    for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
     231      NT_add_to_frwd_hash(frwd_hash, (char *)temp->data);
     232    }
     233
     234 }
     235
     236
     237
     238 /* Adds the e-mails in a linked list to the hash */
     239 void NT_add_to_cross_hash_list(GHashTable * cross_hash, GSList * e_mail_list, int mode){
         /* [<][>][^][v][top][bottom][index][help] */
     240
     241    GSList * temp = NULL;
     242
     243    for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
     244      NT_add_to_cross_hash(cross_hash, (char *)temp->data, mode);
     245    }
     246
     247 }
     248
     249
     250
     251
     252
     253
     254 /* Appends the argument strings to the file.  */
     255 void NT_add_to_ntfy( char * filename, char * fmt, ... ){
         /* [<][>][^][v][top][bottom][index][help] */
     256   va_list ap;  /* points to each unnamed arg in turn */
     257   FILE * ntfy_file;
     258
     259   if(tracing){
     260     printf("TRACING: NT_add_to_ntfy\n");
     261   }
     262   if(( ntfy_file = fopen(filename, "a")) == NULL){
     263     fprintf(stderr, "Can't open notification file for writing, %s\n", filename);
     264     return;
     265   }
     266
     267   va_start(ap, fmt);
     268   vfprintf(ntfy_file, fmt, ap);
     269
     270   va_end(ap); /* clean up */
     271   fclose(ntfy_file);
     272 }
     273
     274
     275
     276 /* Appends the argument strings to the file.  */
     277 void NT_add_to_cross(const char * e_mail, GHashTable * hash, char * fmt, ...){
         /* [<][>][^][v][top][bottom][index][help] */
     278   //va_list ap;  /* points to each unnamed arg in turn */
     279   //FILE * cross_file;
     280
     281   //if(tracing){
     282   //  printf("TRACING: NT_add_to_cross\n");
     283   //}
     284   //if(( ack_file = fopen(filename, "a")) == NULL){
     285   //  fprintf(stderr, "Can't open cross notification file, %s\n", filename);
     286   //}
     287
     288   //va_start(ap, fmt);
     289   //vfprintf(ack_file, fmt, ap);
     290
     291   //va_end(ap); /* clean up */
     292   //fclose(ack_file);
     293
     294   //printf("DEBUG: NT_add_to_cross: will now call NT_add_to_ntfy: e_mail=[%s], arg=[%s]\n", e_mail, arg);
     295   //NT_add_to_ntfy((char *)g_hash_table_lookup(hash, find_email_address(e_mail)), arg);
     296
     297   va_list ap;  /* points to each unnamed arg in turn */
     298   FILE * cross_file;
     299   char * filename;
     300
     301   if(g_hash_table_lookup(hash, find_email_address(e_mail)) != NULL){
     302     filename = (char *)g_hash_table_lookup(hash, find_email_address(e_mail));
     303   }else{
     304     fprintf(stderr, "Can't find a cross notification file for e-mail %s\n", e_mail);
     305     return;
     306   }
     307
     308   if(( cross_file = fopen(filename, "a")) == NULL){
     309     fprintf(stderr, "Can't open cross notification file, %s\n", filename);
     310   }
     311
     312
     313
     314   if(tracing){
     315     printf("TRACING: NT_add_to_cross\n");
     316   }
     317   if(( cross_file = fopen(filename, "a")) == NULL){
     318     fprintf(stderr, "Can't open cross notification file for writing, %s\n", filename);
     319   }
     320
     321   va_start(ap, fmt);
     322   vfprintf(cross_file, fmt, ap);
     323
     324   va_end(ap); /* clean up */
     325   fclose(cross_file);
     326
     327
     328 }
     329
     330
     331
     332
     333
     334 /* Appends the argument string to the temp notif files in the list */
     335 void NT_add_to_ntfy_list(GSList * list, GHashTable * hash, char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
     336
     337   GSList * temp = NULL;
     338
     339   for(temp = list; temp != NULL; temp = g_slist_next(temp)){
     340     NT_add_to_ntfy((char *)g_hash_table_lookup(hash, ((char *)temp->data)), arg);
     341   }
     342 }
     343
     344
     345
     346
     347
     348
     349
     350
     351 /* Sends the notification message which is stored in the temporary filefilename.  */
     352 void NT_send_ntfy( const char * filename, const char * to_address, const char * mailercommand){
         /* [<][>][^][v][top][bottom][index][help] */
     353
     354     char * mail_command_line = NULL;
     355
     356     if(to_address != NULL){
     357       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
     358       sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
     359       system(mail_command_line);
     360     }
     361
     362 }
     363
     364
     365
     366 /* Adds the notification message which is in the filename into log_file. */
     367 void NT_log_ntfy( const char * filename, const char * logfilename){
         /* [<][>][^][v][top][bottom][index][help] */
     368
     369   FILE * notif_file, * log_file;
     370   char * buf;
     371   time_t cur_time;
     372   char * time_str;
     373
     374   buf = (char *)malloc(1024);
     375   if(( notif_file = fopen(filename, "r")) == NULL){
     376     fprintf(stderr, "Can't open notification file for reading, [%s]\n", filename);
     377     return;
     378   }
     379
     380   if(( log_file = fopen(logfilename, "a")) == NULL){
     381     fprintf(stderr, "Can't open log file, %s\n", logfilename);
     382     return;
     383   }
     384
     385   /* get time */
     386   cur_time = time(NULL);
     387   time_str = strdup(ctime(&cur_time));
     388   /* cut the '\n' at the end */
     389   time_str[strlen(time_str) - 1] = '\0';
     390
     391   fprintf(log_file, ">>> time: %s NOTIF <<<\n\n", time_str);
     392
     393
     394   while((buf=fgets(buf, 1023, notif_file)) > 0){
     395     fprintf(log_file, "%s", buf);
     396   }
     397
     398   fclose(notif_file);
     399   fclose(log_file);
     400
     401 }
     402
     403
     404 /* Deletes the temporary notification file. */
     405 void NT_delete_ntfy( const char * filename){
         /* [<][>][^][v][top][bottom][index][help] */
     406
     407    unlink(filename);
     408
     409 }
     410
     411
     412 /* The function required for NT_send_ntfy_list */
     413 void  nt_gfunc_send(gpointer key, gpointer value, gpointer user_data){
         /* [<][>][^][v][top][bottom][index][help] */
     414   NT_send_ntfy((char *)value, (char *)key, (char *)user_data);
     415 }
     416
     417
     418
     419 /* Sends the notification messages whose temp files are stored in filehash. */
     420 void NT_send_ntfy_list( GHashTable * filehash, char * mailercommand){
         /* [<][>][^][v][top][bottom][index][help] */
     421
     422   g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_send, mailercommand);
     423
     424 }
     425
     426
     427
     428
     429 /* The function required for NT_log_ntfy_list */
     430 void  nt_gfunc_log(gpointer key, gpointer value, gpointer user_data){
         /* [<][>][^][v][top][bottom][index][help] */
     431   NT_log_ntfy((char *)value, (char *)user_data);
     432 }
     433
     434
     435
     436
     437 /* Logs the notification whose temp files are in filehash to log_file. */
     438 void NT_log_ntfy_list( GHashTable * filehash, char * log_file){
         /* [<][>][^][v][top][bottom][index][help] */
     439
     440    g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_log, log_file);
     441
     442 }
     443
     444
     445
     446 /* The function required for NT_delete_ntfy_list */
     447 void  nt_gfunc_delete(gpointer key, gpointer value, gpointer user_data){
         /* [<][>][^][v][top][bottom][index][help] */
     448   NT_delete_ntfy((char *)value);
     449 }
     450
     451
     452
     453 /* Deletes the temporary notification messages in the filehash. Empties and frees
     454    the hash too.  */
     455 void NT_delete_ntfy_list( GHashTable * filehash){
         /* [<][>][^][v][top][bottom][index][help] */
     456
     457   g_hash_table_foreach(filehash, (GHFunc)nt_gfunc_delete, NULL);
     458   g_hash_table_destroy(filehash);
     459
     460 }
     461
     462
     463 /* Gathers e-mail boxes to which we will send normal notification messages. It
     464    takes old and new objects, looks up maintainers and less specific inetnums/domains/routes
     465    when necessary, finds the addresses (in mnt-nfy and notify attributes) and returns
     466    a list of them. */
     467 GSList * NT_gather_ntfy_addresses( char * old_object, char * new_object){
         /* [<][>][^][v][top][bottom][index][help] */
     468   GSList *temp = NULL;
     469   GSList * mntners = NULL;
     470
     471   if(old_object != NULL && new_object != NULL){/* it was an update */
     472     temp = get_attr_list(old_object, "notify");
     473     mntners = get_mntners(old_object);
     474     temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
     475   }else if(old_object == NULL && new_object != NULL){/* it was a creation */
     476     temp = get_attr_list(new_object, "notify");
     477     mntners = get_mntners(new_object);
     478     temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
     479   }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
     480     temp = get_attr_list(old_object, "notify");
     481     mntners = get_mntners(old_object);
     482     temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
     483   }
     484   return temp;
     485 }
     486
     487
     488
     489 /* Gathers e-mail boxes to which we will forward messages (or rather, objects). It
     490    an object, looks up maintainers, finds the addresses (in upd-to attributes) and returns
     491    a list of them. */
     492 GSList * NT_gather_frwd_addresses(char * object){
         /* [<][>][^][v][top][bottom][index][help] */
     493   GSList *temp = NULL;
     494   GSList * mntners = NULL;
     495
     496   mntners = get_mntners(object);
     497   temp = get_updto_vector(mntners);
     498   return temp;
     499 }
     500
     501
     502
     503
     504 /* Accepts a route object as a "* char" and returns a list of overlapping routes */
     505 overlap_routes get_overlapping_routes_list(char * object){
         /* [<][>][^][v][top][bottom][index][help] */
     506
     507   char * route_prefix = NULL;
     508   GSList * tmp_list;
     509   char * result;
     510   char * query_string;
     511   overlap_routes result_routes;
     512
     513   result_routes.less_spec = NULL;
     514   result_routes.exact_match = NULL;
     515   result_routes.more_spec = NULL;
     516
     517   tmp_list = get_attr_list(object, "route");
     518
     519   if(tmp_list != NULL && tmp_list->data != NULL){
     520     route_prefix = strdup((char *)(tmp_list->data));
     521   }else{
     522     return result_routes; /* then, this wasn't a route object */
     523   }
     524
     525   /* get the less specific route objects */
     526   /* form the query string */
     527   query_string = (char *)malloc(strlen("-Troute -r -L ") + strlen(route_prefix) + 2);
     528   sprintf(query_string, "-Troute -r -L %s", route_prefix);
     529
     530   /* get the results */
     531   result = send_and_get(query_host, query_port, query_string);
     532   free(query_string);
     533
     534   /* and fill in the result field  */
     535   result_routes.less_spec = take_objects(result);
     536
     537   /* get the exact match route objects */
     538   /* form the query string */
     539   query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(route_prefix) + 2);
     540   sprintf(query_string, "-Troute -r -x %s", route_prefix);
     541
     542   /* get the results */
     543   result = send_and_get(query_host, query_port, query_string);
     544   free(query_string);
     545
     546   /* and fill in the result field  */
     547   result_routes.exact_match = take_objects(result);
     548
     549   /* get the more specific route objects */
     550   /* form the query string */
     551   query_string = (char *)malloc(strlen("-Troute -r -M ") + strlen(route_prefix) + 2);
     552   sprintf(query_string, "-Troute -r -M %s", route_prefix);
     553
     554   /* get the results */
     555   result = send_and_get(query_host, query_port, query_string);
     556   free(query_string);
     557
     558   /* and fill in the result field  */
     559   result_routes.more_spec = take_objects(result);
     560
     561   /* Return the results */
     562   return result_routes;
     563
     564 }
     565
     566
     567
     568
     569
     570 /* Gets old and new versions of the object, and creates temporary notification
     571    files when necessary, and then writes appropriate strings into those
     572    temporary files. */
     573 void NT_write_all_ntfs(char * old_object, char * new_object, /*const char * notif_log,
         /* [<][>][^][v][top][bottom][index][help] */
     574                        const char * forw_log,    const char * cross_log,*/ const char * tempdir,
     575                        GHashTable * ntfy_hash,  GHashTable * forwd_hash, GHashTable * cross_hash,
     576                        char * from_address){
     577
     578    GSList * e_mail_list = NULL;
     579    //GSList * cross_route_list = NULL;
     580    GSList * temp = NULL;
     581    char * e_mail_address;
     582    overlap_routes overlapping_routes;
     583
     584    /* from_address may contain also the name, like "Johnny Bravo <johnny@inter.net>",
     585       so extract the e-mail address from it */
     586    e_mail_address = find_email_address(from_address);
     587
     588
     589    if(tracing){
     590      printf("TRACING: NT_write_all_ntfs: from_address=[%s], e_mail_address=[%s]\n", from_address, e_mail_address);
     591    }
     592    if(old_object != NULL && new_object != NULL){/* it was an update */
     593      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
     594      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
     595      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nPREVIOUS OBJECT:\n\n");
     596      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
     597      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n\nREPLACED BY:\n\n");
     598      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, new_object);
     599      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
     600    }else if(old_object == NULL && new_object != NULL){/* it was a creation */
     601      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
     602      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
     603      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW CREATED:\n\n");
     604      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, new_object);
     605      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
     606      /* We'll deal with cross notifications only when we create or delete route objects */
     607      if(strcmp(get_class_type_char(new_object), "route") == 0){
     608        NT_add_to_cross_hash(cross_hash, e_mail_address, ADDITION);
     609        overlapping_routes = get_overlapping_routes_list(new_object);
     610        if(overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
     611           overlapping_routes.more_spec != NULL ){
     612          //printf("DEBUG: NT_write_all_ntfs: e_mail_address=[%s]\n", e_mail_address);
     613          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);
     614          if(overlapping_routes.less_spec != NULL){
     615            NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
     616            for(temp = overlapping_routes.less_spec; temp != NULL; temp = g_slist_next(temp)){
     617              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     618            }
     619          }
     620          if(overlapping_routes.exact_match != NULL){
     621            NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
     622            for(temp = overlapping_routes.exact_match; temp != NULL; temp = g_slist_next(temp)){
     623              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     624            }
     625          }
     626          if(overlapping_routes.more_spec != NULL){
     627            NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
     628            for(temp = overlapping_routes.more_spec; temp != NULL; temp = g_slist_next(temp)){
     629              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     630            }
     631          }
     632        }
     633      }
     634    }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
     635      old_object = delete_delete_attrib(old_object);
     636      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
     637      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
     638      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW DELETED:\n\n");
     639      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
     640      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
     641      /* We'll deal with cross notifications only when we create or delete route objects */
     642      if(strcmp(get_class_type_char(old_object), "route") == 0){
     643        NT_add_to_cross_hash(cross_hash, e_mail_address, DELETION);
     644        overlapping_routes = get_overlapping_routes_list(old_object);
     645        if(overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
     646           overlapping_routes.more_spec != NULL ){
     647          //printf("DEBUG: NT_write_all_ntfs: e_mail_address=[%s]\n", e_mail_address);
     648          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);
     649          if(overlapping_routes.less_spec != NULL){
     650            NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
     651            for(temp = overlapping_routes.less_spec; temp != NULL; temp = g_slist_next(temp)){
     652              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     653            }
     654          }
     655          if(overlapping_routes.exact_match != NULL){
     656            NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
     657            for(temp = overlapping_routes.exact_match; temp != NULL; temp = g_slist_next(temp)){
     658              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     659            }
     660          }
     661          if(overlapping_routes.more_spec != NULL){
     662            NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
     663            for(temp = overlapping_routes.more_spec; temp != NULL; temp = g_slist_next(temp)){
     664              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
     665            }
     666          }
     667        }
     668      }
     669    }
     670 }
     671
     672
     673
     674
     675
     676 /* Gets old and new versions of the object, and creates temporary notification
     677    files when necessary, and then writes appropriate strings into those
     678    temporary files. */
     679 void NT_write_all_frwds(char * old_object, char * new_object, /*const char * notif_log,
         /* [<][>][^][v][top][bottom][index][help] */
     680                        const char * forw_log,    const char * cross_log,*/ const char * tempdir,
     681                        GHashTable * ntfy_hash,  GHashTable * forwd_hash, GHashTable * cross_hash,
     682                        const char * from_address){
     683
     684    GSList * e_mail_list = NULL;
     685
     686
     687    if(tracing){
     688      printf("TRACING: NT_write_all_frwds\n");
     689    }
     690    if(old_object != NULL && new_object != NULL){/* it was an update */
     691      e_mail_list = NT_gather_frwd_addresses(old_object);
     692      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
     693      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nUPDATE REQUESTED FOR:\n\n");
     694      //NT_add_to_ntfy_list(e_mail_list, forwd_hash, old_object);
     695      //NT_add_to_ntfy_list(e_mail_list, forwd_hash, "\n\n");
     696      NT_add_to_ntfy_list(e_mail_list, forwd_hash, new_object);
     697    }else if(old_object == NULL && new_object != NULL){/* it was a creation */
     698      e_mail_list = NT_gather_frwd_addresses(new_object);
     699      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
     700      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nADDITION REQUESTED FOR:\n\n");
     701      NT_add_to_ntfy_list(e_mail_list, forwd_hash, new_object);
     702    }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
     703      e_mail_list = NT_gather_frwd_addresses(old_object);
     704      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
     705      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nDELETION REQUESTED FOR:\n\n");
     706      NT_add_to_ntfy_list(e_mail_list, forwd_hash, old_object);
     707    }
     708 }
     709

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