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] */