## modules/nt/notification.c

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

## DEFINITIONS

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_free_list
24. NT_unify_list
25. NT_compare_lists

       1 /***************************************
       2   $Revision: 1.14 $
       3
       4   NT (Notifications) module
       5
       6   Status: REVIEWED, NOT TESTED
       7
       8   Author(s):       Engin Gunduz
       9
      10   ******************/ /******************
      11   Modification History:
      12         engin (06/07/2000) Created.
      13                 denis (25/09/2001) Modified for new API
      14   ******************/ /******************
      15   Copyright (c) 2000,2001,2002                    RIPE NCC
      16
      17   All Rights Reserved
      18
      19   Permission to use, copy, modify, and distribute this software and its
      20   documentation for any purpose and without fee is hereby granted,
      21   provided that the above copyright notice appear in all copies and that
      22   both that copyright notice and this permission notice appear in
      23   supporting documentation, and that the name of the author not be
      24   used in advertising or publicity pertaining to distribution of the
      25   software without specific, written prior permission.
      26
      27   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      28   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      29   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      30   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      31   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      32   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      33  ***************************************/
      34
      35
      36
      37
      38
      39
      40 #include "notification.h"
      41 extern int supress_ack_notif;
      42 extern char * defmail;
      43 extern int reading_from_mail;
      44 extern int webupdate;
      45 extern char * forwlog;
      46 extern char *netupdclientIP;
      47
      48 /*  Generates a unique file name and returns the full path of the filename
      49     for storing notification message.  Creates the file at the same time.
      50     May use PID or time or both to ensure uniqueness.  */
      51
      52 char * NT_ntfy_filename_generate( const char * tmpdir, const char * e_mail)
         /* [<][>][^][v][top][bottom][index][help] */
      53 {
      54    FILE * ntfy_file;
      55    char * name;
      56    char * replaced_notihdr;
      57    char * replaced_notimailtxt;
      58    char * replaced_notinetworktxt;
      59
      60    /* allocate space for name.  32 should be enough for PID */
      61    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("notify") +36 );
      62
      63    sprintf(name, "%s/%s-%s.%i", tmpdir, "notify", e_mail, (int)(getpid()) );
      64
      65    /* create the file */
      66    if (( ntfy_file = fopen(name, "w")) == NULL)
      67    {
      68      fprintf(stderr, "Can't open notification file for creating, %s", name);
      69    }
      70
      71    /* fprintf(ntfy_file, "To: %s\nFrom: %s\nSubject: Notification of RIPE Database changes\nReply-To: %s\n\n%s\n",
      72                      e_mail, humailbox, humailbox, notitxt);*/
      73
      74    fprintf(ntfy_file, "To: %s\n", e_mail);
      75    replaced_notihdr = UP_replace_globals(notihdr);
      76    fprintf(ntfy_file, "%s\n\n", replaced_notihdr);
      77    free(replaced_notihdr);
      78    fprintf(ntfy_file, "\n%s\n", notitxt);
      79    if (reading_from_mail)
      80    {
      81      replaced_notimailtxt = UP_replace_globals(notimailtxt);
      82      fprintf(ntfy_file, "%s\n\n", replaced_notimailtxt);
      83      free(replaced_notimailtxt);
      84    }
      85
      86    if (networkupdate || webupdate )
      87    {
      88      replaced_notinetworktxt = UP_replace_globals(notinetworktxt);
      89      fprintf(ntfy_file, "%s\n\n", replaced_notinetworktxt);
      90      free(replaced_notinetworktxt);
      91    }
      92
      93    /* close it */
      94    fclose(ntfy_file);
      95
      96    return name;
      97 }
      98
      99
     100
     101
     102 /* Generates a unique file name and returns the full path of the filename
     103    for storing forwarded message. Creates the file at the same time.  */
     104 char * NT_forwd_filename_generate( const char * tmpdir, const char * e_mail)
         /* [<][>][^][v][top][bottom][index][help] */
     105 {
     106    FILE * forwd_file;
     107    char * name;
     108    char * replaced_fwhdr;
     109    char * replaced_fwmailtxt;
     110    char * replaced_notinetworktxt;
     111
     112    /* allocate space for name.  32 should be enough for PID */
     113    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("forwd") +36 );
     114
     115    sprintf(name, "%s/%s-%s.%i", tmpdir, "forwd", e_mail, (int)(getpid()) );
     116    /* create the file */
     117    if (( forwd_file = fopen(name, "w")) == NULL)
     118    {
     119      fprintf(stderr, "Can't open forward file, %s", name);
     120    }
     121
     122    /* fprintf(forwd_file, "To: %s\nFrom: %s\nSubject:  Requested RIPE database object changes \nReply-To: %s\n\n%s\n",
     123                       e_mail, humailbox, humailbox, fwtxt);*/
     124
     125    fprintf(forwd_file, "To: %s\n", e_mail);
     126    replaced_fwhdr = UP_replace_globals(fwhdr);
     127    fprintf(forwd_file, "%s\n\n", replaced_fwhdr);
     128    free(replaced_fwhdr);
     129    fprintf(forwd_file, "\n%s\n", fwtxt);
     130
     131    if (reading_from_mail)
     132    {
     133      replaced_fwmailtxt = UP_replace_globals(fwmailtxt);
     134      fprintf(forwd_file, "\n%s\n", replaced_fwmailtxt);
     135      free(replaced_fwmailtxt);
     136    }
     137    else if (networkupdate || webupdate)
     138    {
     139      replaced_notinetworktxt = UP_replace_globals(notinetworktxt);
     140      fprintf(forwd_file, "\n%s\n", replaced_notinetworktxt);
     141      free(replaced_notinetworktxt);
     142    }
     143
     144    /* close it */
     145    fclose(forwd_file);
     146
     147    return name;
     148 }
     149
     150
     151
     152
     153 /* Generates a unique file name and returns the full path of the filename
     154    for storing cross notification message. Creates the file at the same time.  */
     155 char * NT_cross_filename_generate( const char * tmpdir, const char * e_mail, int mode)
         /* [<][>][^][v][top][bottom][index][help] */
     156 {
     157    FILE * cross_file;
     158    char * name;
     159
     160    /* allocate space for name.  32 should be enough for PID */
     161    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +36 );
     162
     163    sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, (int)(getpid()) );
     164    /* create the file */
     165    if (( cross_file = fopen(name, "w")) == NULL)
     166    {
     167      fprintf(stderr, "Can't open cross notif file, %s", name);
     168    }
     169
     170    if (mode == ADDITION)
     171    {
     172      fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_add, humailbox);
     173    }
     174    else
     175    {
     176      fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_del, humailbox);
     177    }
     178
     179    /* close it */
     180    fclose(cross_file);
     181
     182    return name;
     183 }
     184
     185
     186
     187
     188
     189 /* Generates a unique file name and returns the full path of the filename for
     190    storing notification message. Creates the file at the same time.  */
     191 char * NT_crossntfy_filename_generate( const char * tmpdir, const char * e_mail)
         /* [<][>][^][v][top][bottom][index][help] */
     192 {
     193    FILE * cross_file;
     194    char * name;
     195
     196    /* allocate space for name.  32 should be enough for PID */
     197    name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +36 );
     198
     199    sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, (int)(getpid()) );
     200
     201    /* create the file */
     202    if (( cross_file = fopen(name, "w")) == NULL)
     203    {
     204      fprintf(stderr, "Can't open cross file, %s", name);
     205    }
     206
     207    /* close it */
     208    fclose(cross_file);
     209
     210    return name;
     211 }
     212
     213
     214
     215 /* Adds the e-mail to the notify hash, generating appropriate temp files */
     216 void NT_add_to_ntfy_hash(GHashTable * ntfy_hash, char * e_mail)
         /* [<][>][^][v][top][bottom][index][help] */
     217 {
     218   if (g_hash_table_lookup(ntfy_hash ,e_mail) == NULL)
     219   { /* there is no such entry, so create it */
     220
     221     g_hash_table_insert(ntfy_hash, strdup(e_mail), NT_ntfy_filename_generate(tmpdir, e_mail));
     222   }
     223 }
     224
     225
     226
     227 /* Adds the e-mail to the forw hash, generating appropriate temp files */
     228 void NT_add_to_frwd_hash(GHashTable * frwd_hash, char * e_mail)
         /* [<][>][^][v][top][bottom][index][help] */
     229 {
     230   if (g_hash_table_lookup(frwd_hash ,e_mail) == NULL)
     231   { /* there is no such entry, so create it */
     232     g_hash_table_insert(frwd_hash, strdup(e_mail), NT_forwd_filename_generate(tmpdir, e_mail));
     233   }
     234
     235 }
     236
     237
     238
     239 /* Adds the e-mail to the cross hash, generating appropriate temp files */
     240 void NT_add_to_cross_hash(GHashTable * cross_hash, const char * e_mail, int mode)
         /* [<][>][^][v][top][bottom][index][help] */
     241 {
     242   /*  if e-mail is NULL, immediately return */
     243   if (e_mail == NULL)
     244   {
     245     return;
     246   }
     247
     248   if (g_hash_table_lookup(cross_hash ,e_mail) == NULL)
     249   { /* there is no such entry, so create it */
     250     g_hash_table_insert(cross_hash, strdup(e_mail), NT_cross_filename_generate(tmpdir, e_mail, mode));
     251   }
     252 }
     253
     254
     255
     256 /* Adds the e-mails in a linked list to the hash */
     257 void NT_add_to_ntfy_hash_list(GHashTable * ntfy_hash, GList * e_mail_list)
         /* [<][>][^][v][top][bottom][index][help] */
     258 {
     259    GList * temp = NULL;
     260
     261    for (temp = e_mail_list; temp != NULL; temp = g_list_next(temp))
     262    {
     263      NT_add_to_ntfy_hash( ntfy_hash, (char *)(temp->data) );
     264    }
     265 }
     266
     267
     268
     269 /* Adds the e-mails in a linked list to the hash */
     270 void NT_add_to_frwd_hash_list(GHashTable * frwd_hash, GList * e_mail_list)
         /* [<][>][^][v][top][bottom][index][help] */
     271 {
     272    GList * temp = NULL;
     273
     274    for (temp = e_mail_list; temp != NULL; temp = g_list_next(temp))
     275    {
     276      NT_add_to_frwd_hash(frwd_hash, (char *)temp->data);
     277    }
     278 }
     279
     280
     281
     282 /* Adds the e-mails in a linked list to the hash */
     283 void NT_add_to_cross_hash_list(GHashTable * cross_hash, GList * e_mail_list, int mode)
         /* [<][>][^][v][top][bottom][index][help] */
     284 {
     285    GList * temp = NULL;
     286
     287    for (temp = e_mail_list; temp != NULL; temp = g_list_next(temp))
     288    {
     289      NT_add_to_cross_hash(cross_hash, (char *)temp->data, mode);
     290    }
     291 }
     292
     293
     294
     295 /* Appends the argument strings to the file.  */
     296 void NT_add_to_ntfy( char * filename, char * fmt, ... )
         /* [<][>][^][v][top][bottom][index][help] */
     297 {
     298   va_list ap;  /* points to each unnamed arg in turn */
     299   FILE * ntfy_file;
     300
     301   if (tracing)
     302   {
     303     printf("TRACING: NT_add_to_ntfy\n");
     304   }
     305   if (( ntfy_file = fopen(filename, "a")) == NULL)
     306   {
     307     fprintf(stderr, "Can't open notification file for writing, %s\n", filename);
     308     return;
     309   }
     310
     311   va_start(ap, fmt);
     312   vfprintf(ntfy_file, fmt, ap);
     313
     314   va_end(ap); /* clean up */
     315   fclose(ntfy_file);
     316 }
     317
     318
     319
     320 /* Appends the argument strings to the file.  */
     321 void NT_add_to_cross(const char * e_mail, GHashTable * hash, char * fmt, ...)
         /* [<][>][^][v][top][bottom][index][help] */
     322 {
     323   va_list ap;  /* points to each unnamed arg in turn */
     324   FILE * cross_file = NULL;
     325   char * filename = NULL;
     326
     327   if (tracing)
     328   {
     329     printf("TRACING: NT_add_to_cross\n");
     330   }
     331
     332   /* if e-mail is NULL, immediately return */
     333   if(e_mail == NULL)
     334   {
     335     return;
     336   }
     337
     338   if ( (filename = (char *)g_hash_table_lookup(hash, find_email_address(e_mail))) == NULL )
     339   {
     340     fprintf(stderr, "Can't find a cross notification file for e-mail %s\n", e_mail);
     341     return;
     342   }
     343
     344   if ( ( cross_file = fopen(filename, "a")) == NULL )
     345   {
     346     fprintf(stderr, "Can't open cross notification file for writing, %s\n", filename);
     347   }
     348
     349   va_start(ap, fmt);
     350   vfprintf(cross_file, fmt, ap);
     351
     352   va_end(ap); /* clean up */
     353   fclose(cross_file);
     354 }
     355
     356
     357
     358
     359 /* Appends the argument string to the temp notif files in the list */
     360 void NT_add_to_ntfy_list(GList * list, GHashTable * hash, char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
     361 {
     362   GList * temp = NULL;
     363
     364   for(temp = list; temp != NULL; temp = g_list_next(temp))
     365   {
     366     NT_add_to_ntfy((char *)g_hash_table_lookup(hash, ((char *)temp->data)), "%s", arg);
     367   }
     368 }
     369
     370
     371
     372 /* Sends the notification message which is stored in the temporary filefilename.  */
     373 void NT_send_ntfy( const char * filename, const char * to_address, const char * mailercommand)
         /* [<][>][^][v][top][bottom][index][help] */
     374 {
     375     char * mail_command_line = NULL;
     376     char * supress_file = NULL;
     377     FILE * notif_file, * supr_file_hdl;
     378     char buf[1024];
     379
     380     /* if we are not supressing acks and notifs, send the notif */
     381     if (!supress_ack_notif)
     382         {
     383       if (to_address != NULL)
     384           {
     385         mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
     386         sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
     387         system(mail_command_line);
     388       }
     389     }
     390     /* if we are supressing acks and notifs, send notif to DEFMAIL  */
     391         else
     392         {
     393       supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2);
     394       sprintf(supress_file, "%s.supress", filename);
     395       if (( supr_file_hdl = fopen(supress_file, "w")) == NULL)
     396           {
     397         fprintf(stderr, "Can't open supress notif file, %s", supress_file);
     398       }
     399           else
     400           {
     401         fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed notif mail\n\n",
     402             humailbox, defmail);
     403         if (( notif_file = fopen(filename, "r")) == NULL)
     404                 {
     405           fprintf(stderr, "Can't open notif file for reading, %s", filename);
     406         }
     407                 else
     408                 {
     409           while (fgets(buf, 1023, notif_file) != NULL)
     410                   {
     411             fprintf(supr_file_hdl, buf);
     412           }
     413           fclose(notif_file);
     414         }
     415       }
     416       fclose(supr_file_hdl);
     417       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail)
     418             + strlen(supress_file) + 128);
     419       sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
     420       system(mail_command_line);
     421       unlink(supress_file);
     422       free(supress_file);
     423     }
     424 }
     425
     426
     427
     428 /* Adds the notification message which is in the filename into "logfilename.date". */
     429 void NT_log_ntfy( const char * filename, const char * logfilename)
         /* [<][>][^][v][top][bottom][index][help] */
     430 {
     431   FILE * notif_file, * log_file;
     432   char * buf;
     433   time_t cur_time;
     434   char * time_str;
     435   char * logfile_date;
     436   char * date;
     437
     438   if (tracing)
     439   {
     440     printf("TRACING: NT_log_ntfy is running: filename [%s]  logfilename [%s]\n", filename, logfilename);
     441   }
     442
     443   buf = (char *)malloc(1024);
     444   if (( notif_file = fopen(filename, "r")) == NULL)
     445   {
     446     fprintf(stderr, "NT_log_ntfy: Can't open notification file for reading, [%s]\n", filename);
     447     return;
     448   }
     449
     450   /* construct the "logfilename.date" string */
     451   logfile_date = (char *)malloc(strlen(logfilename) + 10);
     452   date = UP_get_current_date();
     453   snprintf(logfile_date, strlen(logfilename) + 10, "%s.%s", logfilename, date);
     454   free(date);
     455
     456   if (( log_file = fopen(logfile_date, "a")) == NULL)
     457   {
     458     fprintf(stderr, "NT_log_ntfy: Can't open log file, %s\n", logfilename);
     459     return;
     460   }
     461
     462   /* get time */
     463   cur_time = time(NULL);
     464   time_str = strdup(ctime(&cur_time));
     465   /* cut the '\n' at the end */
     466   time_str[strlen(time_str) - 1] = '\0';
     467
     468   if ( networkupdate )
     469     fprintf(log_file, ">>> time: %s NETWORKUPDATE NOTIF (%s) <<<\n\n",
     470                 time_str, netupdclientIP ? netupdclientIP : "NULL");
     471   else if ( webupdate )
     472     fprintf(log_file, ">>> time: %s WEB UPDATE NOTIF (%s) <<<\n\n",
     473                 time_str, netupdclientIP ? netupdclientIP : "NULL");
     474   else
     475     fprintf(log_file, ">>> time: %s NOTIF <<<\n\n", time_str);
     476
     477
     478   while ( (buf=fgets(buf, 1024, notif_file)) != NULL )
     479   {
     480     fprintf(log_file, "%s", buf);
     481   }
     482   free(buf);
     483
     484   fclose(notif_file);
     485   fclose(log_file);
     486 }
     487
     488
     489 /* Deletes the temporary notification file. */
     490 void NT_delete_ntfy( const char * filename)
         /* [<][>][^][v][top][bottom][index][help] */
     491 {
     492    unlink(filename);
     493 }
     494
     495
     496 /* The function required for NT_send_ntfy_list */
     497 void  nt_gfunc_send(gpointer key, gpointer value, gpointer user_data)
         /* [<][>][^][v][top][bottom][index][help] */
     498 {
     499   NT_send_ntfy((char *)value, (char *)key, (char *)user_data);
     500 }
     501
     502
     503
     504 /* Sends the notification messages whose temp files are stored in filehash. */
     505 void NT_send_ntfy_list( GHashTable * filehash, char * mailercommand)
         /* [<][>][^][v][top][bottom][index][help] */
     506 {
     507   g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_send, mailercommand);
     508 }
     509
     510
     511
     512
     513 /* The function required for NT_log_ntfy_list */
     514 void  nt_gfunc_log(gpointer key, gpointer value, gpointer user_data)
         /* [<][>][^][v][top][bottom][index][help] */
     515 {
     516   NT_log_ntfy((char *)value, (char *)user_data);
     517 }
     518
     519
     520
     521
     522 /* Logs the notification whose temp files are in filehash to log_file. */
     523 void NT_log_ntfy_list( GHashTable * filehash, char * log_file)
         /* [<][>][^][v][top][bottom][index][help] */
     524 {
     525    g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_log, log_file);
     526 }
     527
     528
     529
     530 /* The function required for NT_delete_ntfy_list */
     531 void  nt_gfunc_delete(gpointer key, gpointer value, gpointer user_data)
         /* [<][>][^][v][top][bottom][index][help] */
     532 {
     533   NT_delete_ntfy((char *)value);
     534 }
     535
     536
     537
     538 /* Deletes the temporary notification messages in the filehash. Empties and frees
     539    the hash too.  */
     540 void NT_delete_ntfy_list( GHashTable * filehash)
         /* [<][>][^][v][top][bottom][index][help] */
     541 {
     542   g_hash_table_foreach(filehash, (GHFunc)nt_gfunc_delete, NULL);
     543   g_hash_table_destroy(filehash);
     544 }
     545
     546
     547 /* to be used with g_hash_table_foreach in NT_unify_list.
     548    Adds the 'value' to the list (a GList) */
     549 /* void nt_add_to_list(char * key, rpsl_attr_t * value, GList ** list)
     550 {
     551   *list = g_list_append(*list, strdup(value));
     552 }
     553 */
     554
     555
     556 /* to be used with g_hash_table_foreach in NT_unify_list.
     557    frees the 'key' and 'value' in the list (a GList) */
     558 void nt_free_list(char * key, char * value, void *nothing)
         /* [<][>][^][v][top][bottom][index][help] */
     559 {
     560   if ( key != NULL )
     561     free(key);
     562   if ( value != NULL )
     563     free(value);
     564 }
     565
     566
     567
     568 /* "unifies" a list in a case insensitive manner */
     569 GList * NT_unify_list(GList * in_list)
         /* [<][>][^][v][top][bottom][index][help] */
     570 {
     571   GHashTable * unification_hash;
     572   GList ** out_list;
     573   GList * temp;
     574   GList *return_list = NULL;
     575   char * key, * value;
     576   int strcmp();
     577
     578   /* allocate space for out_list */
     579   out_list = (GList **)malloc(sizeof(GList *));
     580   *out_list = NULL;
     581
     582   /* initialize the hash to be used for unification process */
     583   unification_hash = g_hash_table_new(g_str_hash, g_str_equal);
     584
     585   /* first put the list elements into a hash, to unify them */
     586   for (temp = in_list; temp != NULL; temp = g_list_next(temp))
     587   {
     588     /* convert the email address into lowercase, for comparison reasons only */
     589     key = rpsl_attr_get_clean_value((rpsl_attr_t *)(temp->data));
     590     value = strdup(key);
     591     g_strdown(key);
     592
     593     if (g_hash_table_lookup(unification_hash, key) == NULL)
     594         { /* if it is not already in the hash table, add to the hash and append to new list */
     595       g_hash_table_insert(unification_hash, key, value);
     596       *out_list = g_list_insert_sorted( *out_list, strdup(value), strcmp );
     597 /*       *out_list = g_list_append( *out_list, strdup(value) ); */
     598     }
     599         else
     600         {  /* it is a duplicate email address, don't append to new list */
     601           free(key);
     602           free(value);
     603         }
     604   }
     605
     606   /* now, delete the elements in the hash */
     607   g_hash_table_foreach(unification_hash, (GHFunc)nt_free_list, NULL);
     608
     609   g_hash_table_destroy(unification_hash);
     610
     611   return_list = *out_list;
     612   free(out_list);
     613   return return_list;
     614 }
     615
     616
     617
     618 /* Gets GLists of irt atributes from old and new object. Compares these
     619    lists and returns a list of diferences */
     620
     621 /* if option==1, return list contains only newly deleted irts
     622    if option==2, return list contains only newly added irts
     623    if option==3, return list contains both */
     624
     625 GList *NT_compare_lists(GList *old_irts, GList *new_irts, int option)
         /* [<][>][^][v][top][bottom][index][help] */
     626 {
     627   typedef struct irt_details
     628   {
     629     gchar *irt_name;
     630         rpsl_attr_t *irts;
     631         gint   matched;
     632   } irt_details_t;
     633
     634   GList *old_irt_details = NULL;
     635   GList *new_irt_details = NULL;
     636   GList *old_irts_item = NULL;
     637   GList *new_irts_item = NULL;
     638   GList *return_list = NULL;
     639   irt_details_t *irt_details;
     640   char *irt_name;
     641
     642   if (tracing)
     643   {
     644     printf("TRACING: NT_compare_lists is running: option: [%d]\n", option);
     645   }
     646
     647   /* collect data from the old_irts */
     648   for ( old_irts_item = old_irts; old_irts_item != NULL; old_irts_item = g_list_next(old_irts_item) )
     649   {
     650     irt_details = (irt_details_t *)malloc(sizeof(irt_details_t));
     651         /* get irt name from attr */
     652         irt_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(old_irts_item->data) );
     653         /* enter details into irt_details structure */
     654         irt_details->irts = (rpsl_attr_t *)(old_irts_item->data);
     655         irt_details->irt_name = irt_name;
     656         irt_details->matched = 0;
     657         /* append irt_details structure to old_irt_details list */
     658         old_irt_details = g_list_append(old_irt_details, irt_details);
     659   }
     660
     661   /* collect data from the new_irts and compare with the old in the same loop */
     662   for ( new_irts_item = new_irts; new_irts_item != NULL; new_irts_item = g_list_next(new_irts_item) )
     663   {
     664     irt_details = (irt_details_t *)malloc(sizeof(irt_details_t));
     665         /* get irt name from attr */
     666         irt_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(new_irts_item->data) );
     667         /* enter details into irt_details structure */
     668         irt_details->irts = (rpsl_attr_t *)(new_irts_item->data);
     669         irt_details->irt_name = irt_name;
     670         irt_details->matched = 0;
     671
     672         /* compare the name with the names from the old list  */
     673         for ( old_irts_item = old_irt_details; old_irts_item != NULL; old_irts_item = g_list_next(old_irts_item) )
     674     {
     675           if ( ! strcmp(irt_name, ((irt_details_t *)(old_irts_item->data))->irt_name ) )
     676           {
     677             irt_details->matched = 1;
     678                 ((irt_details_t *)(old_irts_item->data))->matched = 1;
     679                 break;
     680           }
     681         }
     682
     683         /* append irt_details structure to new_irt_details list */
     684         new_irt_details = g_list_append(new_irt_details, irt_details);
     685   }
     686
     687   /* we now want a list of irts taken from the old and new irt_details lists
     688      where the matched flag is _NOT_ set. These will only exist in one list
     689          and have therefore just been added/deleted */
     690   /* if option==1, return list contains only newly deleted irts
     691      if option==2, return list contains only newly added irts
     692      if option==3, return list contains both */
     693   if ( option == 1 || option == 3 )
     694   {
     695     for ( old_irts_item = old_irt_details; old_irts_item != NULL; old_irts_item = g_list_next(old_irts_item) )
     696     {
     697       if ( ! ((irt_details_t *)(old_irts_item->data))->matched )
     698           {
     699         if (tracing)
     700         {
     701           printf("TRACING: NT_compare_lists: adding old irt to return list [%s]\n", ((irt_details_t *)(new_irts_item->data))->irt_name);
     702         }
     703
     704             return_list = g_list_append(return_list, ((irt_details_t *)(old_irts_item->data))->irts );
     705           }
     706           free ( ((irt_details_t *)(old_irts_item->data))->irt_name );
     707     }
     708   }
     709   g_list_free(old_irt_details);
     710   if ( option == 2 || option == 3 )
     711   {
     712     for ( new_irts_item = new_irt_details; new_irts_item != NULL; new_irts_item = g_list_next(new_irts_item) )
     713     {
     714       if ( ! ((irt_details_t *)(new_irts_item->data))->matched )
     715           {
     716         if (tracing)
     717         {
     718           printf("TRACING: NT_compare_lists: adding new irt to return list [%s]\n", ((irt_details_t *)(new_irts_item->data))->irt_name);
     719         }
     720
     721             return_list = g_list_append(return_list, ((irt_details_t *)(new_irts_item->data))->irts );
     722           }
     723           free ( ((irt_details_t *)(new_irts_item->data))->irt_name );
     724     }
     725   }
     726   g_list_free(new_irt_details);
     727
     728   return return_list;
     729 }
     730
     731
     732 /* Gets old and new objects supplied, forms lists of any irt objects referenced
     733    by these. Returns a GList of irt-nfy for any irt objects that heve been added
     734    or deleted.
     735 */
     736 GList *NT_check_irtnfy(rpsl_object_t *old_obj, rpsl_object_t *new_obj)
     737 {
     738   GList *old_irts = NULL;
     739   GList *new_irts = NULL;
     740   GList *changed_irts = NULL;
     741
     742   if (old_obj != NULL)
     743     old_irts = get_irts(old_obj);
     744   if (new_obj != NULL)
     745     new_irts = get_irts(new_obj);
     746
     747   if ( old_irts != NULL && new_irts!= NULL )
     748   {
     749     /* compare lists for additions and deletions */
     750         changed_irts = NT_compare_lists(old_irts, new_irts, 3);
     751         return get_irtnfy_vector(changed_irts);
     752   }
     753   else if ( old_irts != NULL )
     754   {
     755     /* these irts have been deleted */
     756         return get_irtnfy_vector(old_irts);
     757   }
     758   else if ( new_irts != NULL )
     759   {
     760     /* these irts have been added */
     761         return get_irtnfy_vector(new_irts);
     762   }
     763   else
     764     return NULL;  /* no irt objects at all */
     765 }
     766
     767
     768 /* Gathers e-mail boxes to which we will send normal notification messages. It
     769    takes old and new object strings, looks up maintainers and less specific inetnums/domains/routes
     770    when necessary, finds the addresses (in mnt-nfy and notify attributes) and returns
     771    a list of email addresses as strings.
     772    Also now checks for irt-nfy in any irt objects that have been added or deleted */
     773 GList * NT_gather_ntfy_addresses( const char * old_object_str, const char * new_object_str)
     774 {
     775   GList *return_list = NULL, *temp = NULL;
     776   GList *mntners = NULL;
     777   const GList *error_list = NULL;
     778   rpsl_object_t *old_obj = NULL;
     779   rpsl_object_t *new_obj = NULL;
     780
     781   if (tracing)
     782   {
     783     printf("TRACING: NT_gather_ntfy_addresses is running: old_object_str : [%s]; new_object_str: [%s]\n", old_object_str ? old_object_str : "", new_object_str ? new_object_str : "");
     784   }
     785
     786   if (old_object_str != NULL && new_object_str != NULL)
     787   { /* it was an update */
     788         old_obj = rpsl_object_init(old_object_str);
     789         error_list = rpsl_object_errors(old_obj);
     790         new_obj = rpsl_object_init(new_object_str);
     791         error_list = rpsl_object_errors(old_obj);
     792
     793     /* start with the 'notify' in the object itself */
     794     temp = get_attr_list(old_obj, "notify");
     795     mntners = get_mntners(old_obj);
     796         /* now add the 'mnt-by' from any of the mntners in the old object only */
     797     temp = g_list_concat(temp, get_mntnfy_vector(mntners));
     798         /* now add the 'irt-by' from any of the irts in the old and new objects
     799            if they have just been added or deleted */
     800         temp = g_list_concat(temp, NT_check_irtnfy(old_obj, new_obj));
     801   }
     802   else if (old_object_str == NULL && new_object_str != NULL)
     803   { /* it was a creation */
     804         new_obj = rpsl_object_init(new_object_str);
     805         error_list = rpsl_object_errors(new_obj);
     806
     807     if ( ! rpsl_object_has_error( new_obj, RPSL_ERRLVL_ERROR ) )
     808         {
     809       /* start with the 'notify' in the object itself */
     810       temp = get_attr_list(new_obj, "notify");
     811       mntners = get_mntners(new_obj);
     812           /* now add the 'mnt-by' from any of the mntners in the new object only */
     813       temp = g_list_concat(temp, get_mntnfy_vector(mntners));
     814           /* now add the 'irt-by' from any of the irts in the new object
     815                  as they have just been added */
     816           temp = g_list_concat(temp, NT_check_irtnfy(old_obj, new_obj));
     817         }
     818   }
     819   else if (old_object_str != NULL && new_object_str == NULL)
     820   { /* it was a deletion */
     821         old_obj = rpsl_object_init(old_object_str);
     822         error_list = rpsl_object_errors(old_obj);
     823
     824     /* start with the 'notify' in the object itself */
     825     temp = get_attr_list(old_obj, "notify");
     826     mntners = get_mntners(old_obj);
     827         /* now add the 'mnt-by' from any of the mntners in the old object only */
     828     temp = g_list_concat(temp, get_mntnfy_vector(mntners));
     829         /* now add the 'irt-by' from any of the irts in the old object
     830            as they have just been deleted */
     831         temp = g_list_concat(temp, NT_check_irtnfy(old_obj, new_obj));
     832   }
     833
     834   /* we have to 'unify' the list here!, return_list is now a list of malloc'd email address strings */
     835   return_list = NT_unify_list(temp);
     836   rpsl_attr_delete_list( temp );
     837   if ( old_obj )
     838     rpsl_object_delete(old_obj);
     839   if ( new_obj )
     840     rpsl_object_delete(new_obj);
     841
     842   if (tracing)
     843   {
     844     printf( "TRACING: notif email addresses\n" );
     845     for ( temp=return_list; temp!=NULL; temp=g_list_next(temp) )
     846       printf( "TRACING: [%s]\n", (char *)(temp->data) );
     847   }
     848
     849   return return_list;
     850 }
     851
     852
     853
     854 /* Gathers e-mail boxes to which we will forward messages (or rather, objects). It
     855    an object, looks up maintainers, finds the addresses (in upd-to attributes) and returns
     856    a list of them. */
     857 GList * NT_gather_frwd_addresses(char * object_str)
     858 {
     859   GList *temp = NULL;
     860   GList *attr_item = NULL;
     861   GList *email_list = NULL;
     862   char *email;
     863   const GList *error_list = NULL;
     864   rpsl_object_t *object;
     865   GList * mntners = NULL;
     866
     867   object = rpsl_object_init(object_str);
     868   error_list = rpsl_object_errors(object);
     869
     870   mntners = get_mntners(object);
     871   /* get a list of upd-to attributes */
     872   temp = get_updto_vector(mntners);
     873   /* now extract the email text strings from the values of these attributes */
     874   for ( attr_item = temp; attr_item != NULL ; attr_item = g_list_next(attr_item) )
     875   {
     876     email = rpsl_attr_get_clean_value((rpsl_attr_t *)(attr_item->data));
     877     if (tracing)
     878     {
     879       printf("NT_gather_frwd_addresses: email [%s]\n", email );
     880     }
     881     email_list = g_list_append(email_list, email );
     882   }
     883   return email_list;
     884 }
     885
     886
     887
     888 /* Accepts a parsed route object and returns a list of overlapping routes */
     889 overlap_routes get_overlapping_routes_list(rpsl_object_t * object)
     890 {
     891   char * route_prefix = NULL;
     892   GList * tmp_list;
     893   char * result;
     894   char * query_string;
     895   overlap_routes result_routes;
     896
     897   result_routes.less_spec = NULL;
     898   result_routes.exact_match = NULL;
     899   result_routes.more_spec = NULL;
     900
     901   tmp_list = rpsl_object_get_attr(object, "route");
     902
     903   if (tmp_list != NULL && tmp_list->data != NULL)
     904   {
     905     route_prefix = rpsl_attr_get_clean_value((rpsl_attr_t *)(tmp_list->data));
     906   }
     907   else
     908   {
     909     return result_routes; /* then, this wasn't a route object */
     910   }
     911
     912   /* get the less specific route objects */
     913   /* form the query string */
     914   query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(route_prefix) + 2);
     915   sprintf(query_string, "-Troute -r -l %s", route_prefix);
     916
     917   /* get the results */
     918   result = send_and_get(query_host, query_port, query_string);
     919   free(query_string);
     920
     921   /* and fill in the result field  */
     922   result_routes.less_spec = take_objects(result);
     923
     924   /* get the exact match route objects */
     925   /* form the query string */
     926   query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(route_prefix) + 2);
     927   sprintf(query_string, "-Troute -r -x %s", route_prefix);
     928
     929   /* get the results */
     930   result = send_and_get(query_host, query_port, query_string);
     931   free(query_string);
     932
     933
     934   /* filter out the route object itself */
     935   result = UP_filter_out_same_origins(result, object);
     936
     937   /* and fill in the result field  */
     938   if (result != NULL)
     939   {
     940     result_routes.exact_match = take_objects(result);
     941   }
     942
     943   /* get the more specific route objects */
     944   /* form the query string */
     945   query_string = (char *)malloc(strlen("-Troute -r -M ") + strlen(route_prefix) + 2);
     946   sprintf(query_string, "-Troute -r -M %s", route_prefix);
     947
     948   /* get the results */
     949   result = send_and_get(query_host, query_port, query_string);
     950   free(query_string);
     951
     952   /* and fill in the result field  */
     953   result_routes.more_spec = take_objects(result);
     954
     955   /* Return the results */
     956   return result_routes;
     957 }
     958
     959
     960
     961 /* Gets old and new versions of the object, and creates temporary notification
     962    files when necessary, and then writes appropriate strings into those
     963    temporary files. */
     964 void NT_write_all_ntfs(char * old_object, char * new_object, char * formatted_object,
     965                        const char * tempdir,
     966                        GHashTable * ntfy_hash,  GHashTable * forwd_hash, GHashTable * cross_hash,
     967                        char * from_address)
     968 {
     969    GList * e_mail_list = NULL;
     970    GList * temp = NULL;
     971    const GList *error_list = NULL;
     972    char * e_mail_address = NULL;
     973    overlap_routes overlapping_routes;
     974    rpsl_object_t *object;
     975    char *arg2;
     976
     977    if ( reading_from_mail )
     978    {
     979      /* from_address may contain also the name, like "Johnny Bravo <johnny@inter.net>",
     980         so extract the e-mail address from it */
     981      e_mail_address = find_email_address(from_address);
     982
     983      if (tracing)
     984      {
     985        printf("TRACING: NT_write_all_ntfs: from_address=[%s], e_mail_address=[%s]\n", from_address, e_mail_address);
     986      }
     987    }
     988    if (old_object != NULL && new_object != NULL)
     989    {
     990      /* it was an update */
     991          object = rpsl_object_init(formatted_object ? formatted_object : new_object);
     992          error_list = rpsl_object_errors(object);
     993
     994      if ( UP_remove_override_attr(object) )
     995        arg2 = rpsl_object_get_text(object, RPSL_STD_COLUMN);
     996          else
     997          {
     998            /* there was an override attr in this object and it has not been removed */
     999            arg2 = (char *)malloc(2);
    1000            strcpy(arg2, "");    /* Don't include object in ack/notif msgs */
    1001          }
    1002
    1003      rpsl_object_delete(object);
    1004
    1005      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
    1006      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
    1007      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nPREVIOUS OBJECT:\n\n");
    1008      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
    1009      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n\nREPLACED BY:\n\n");
    1010      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, arg2);
    1011      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
    1012    }
    1013    else if (old_object == NULL && new_object != NULL)
    1014    {
    1015      /* it was a creation */
    1016          object = rpsl_object_init(formatted_object ? formatted_object : new_object);
    1017          error_list = rpsl_object_errors(object);
    1018
    1019      if ( UP_remove_override_attr(object) )
    1020        arg2 = rpsl_object_get_text(object, RPSL_STD_COLUMN);
    1021          else
    1022          {
    1023            /* there was an override attr in this object and it has not been removed */
    1024            arg2 = (char *)malloc(2);
    1025            strcpy(arg2, "");    /* Don't include object in ack/notif msgs */
    1026          }
    1027
    1028      rpsl_object_delete(object);
    1029
    1030      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
    1031      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
    1032      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW CREATED:\n\n");
    1033      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, arg2);
    1034      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
    1035
    1036      /* We'll deal with cross notifications only when we create or delete route objects */
    1037          object = rpsl_object_init(new_object);
    1038          error_list = rpsl_object_errors(object);
    1039
    1040      if (strcmp(rpsl_object_get_class(object), "route") == 0)
    1041          {
    1042        overlapping_routes = get_overlapping_routes_list(object);
    1043        if (overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
    1044           overlapping_routes.more_spec != NULL )
    1045            {
    1046          NT_add_to_cross_hash(cross_hash, e_mail_address, ADDITION);
    1047          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);
    1048          if (overlapping_routes.less_spec != NULL)
    1049                  {
    1050            NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
    1051            for (temp = overlapping_routes.less_spec; temp != NULL; temp = g_list_next(temp))
    1052                    {
    1053              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
    1054            }
    1055          }
    1056          if (overlapping_routes.exact_match != NULL)
    1057                  {
    1058            NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
    1059            for (temp = overlapping_routes.exact_match; temp != NULL; temp = g_list_next(temp))
    1060                    {
    1061              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
    1062            }
    1063          }
    1064          if (overlapping_routes.more_spec != NULL)
    1065                  {
    1066            NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
    1067            for (temp = overlapping_routes.more_spec; temp != NULL; temp = g_list_next(temp))
    1068                    {
    1069              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
    1070            }
    1071          }
    1072        }
    1073      }
    1074          rpsl_object_delete(object);
    1075    }
    1076    else if (old_object != NULL && new_object == NULL)
    1077    { /* it was a deletion */
    1078      old_object = delete_delete_attrib(old_object);
    1079          object = rpsl_object_init(old_object);
    1080          error_list = rpsl_object_errors(object);
    1081
    1082      if ( UP_remove_override_attr(object) )
    1083        arg2 = rpsl_object_get_text(object, RPSL_STD_COLUMN);
    1084          else
    1085          {
    1086            /* there was an override attr in this object and it has not been removed */
    1087            arg2 = (char *)malloc(2);
    1088            strcpy(arg2, "");    /* Don't include object in ack/notif msgs */
    1089          }
    1090
    1091      e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
    1092      NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
    1093      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW DELETED:\n\n");
    1094      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, arg2);
    1095      NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
    1096
    1097      /* We'll deal with cross notifications only when we create or delete route objects */
    1098      if (strcmp(rpsl_object_get_class(object), "route") == 0)
    1099          {
    1100        overlapping_routes = get_overlapping_routes_list(object);
    1101        if (overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
    1102           overlapping_routes.more_spec != NULL )
    1103            {
    1104          NT_add_to_cross_hash(cross_hash, e_mail_address, DELETION);
    1105          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);
    1106          if (overlapping_routes.less_spec != NULL)
    1107                  {
    1108            NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
    1109            for (temp = overlapping_routes.less_spec; temp != NULL; temp = g_list_next(temp))
    1110                    {
    1111              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
    1112            }
    1113          }
    1114          if (overlapping_routes.exact_match != NULL)
    1115                  {
    1116            NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
    1117            for (temp = overlapping_routes.exact_match; temp != NULL; temp = g_list_next(temp))
    1118                    {
    1119              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
    1120            }
    1121          }
    1122          if (overlapping_routes.more_spec != NULL)
    1123                  {
    1124            NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
    1125            for (temp = overlapping_routes.more_spec; temp != NULL; temp = g_list_next(temp))
    1126                    {
    1127              NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
    1128            }
    1129          }
    1130        }
    1131      }
    1132          rpsl_object_delete(object);
    1133    }
    1134    free(arg2);
    1135 }
    1136
    1137
    1138
    1139 /* Gets old and new versions of the object, and creates temporary notification
    1140    files when necessary, and then writes appropriate strings into those
    1141    temporary files. */
    1142 void NT_write_all_frwds(char * old_object_str, char * new_object_str, const char * tempdir,
    1143                        GHashTable * ntfy_hash,  GHashTable * forwd_hash, GHashTable * cross_hash,
    1144                        const char * from_address)
    1145 {
    1146    GList *e_mail_list = NULL;
    1147    rpsl_object_t *object;
    1148    char *arg2;
    1149    const GList * error_list = NULL;
    1150
    1151    if (tracing)
    1152    {
    1153      printf("TRACING: NT_write_all_frwds is running\n");
    1154    }
    1155
    1156    if ( new_object_str )
    1157    {
    1158          object = rpsl_object_init(new_object_str);
    1159          error_list = rpsl_object_errors(object);
    1160
    1161      if ( UP_remove_override_attr(object) )
    1162        arg2 = rpsl_object_get_text(object, RPSL_STD_COLUMN);
    1163          else
    1164          {
    1165            /* there was an override attr in this object and it has not been removed */
    1166            arg2 = (char *)malloc(2);
    1167            strcpy(arg2, "");    /* Don't include object in ack/notif msgs */
    1168          }
    1169    }
    1170
    1171    if (old_object_str != NULL && new_object_str != NULL)
    1172    { /* it was an update */
    1173      e_mail_list = NT_gather_frwd_addresses(old_object_str);
    1174      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
    1175      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nUPDATE REQUESTED FOR:\n\n");
    1176      NT_add_to_ntfy_list(e_mail_list, forwd_hash, arg2);
    1177    }
    1178    else if (old_object_str == NULL && new_object_str != NULL)
    1179    { /* it was a creation */
    1180      e_mail_list = NT_gather_frwd_addresses(new_object_str);
    1181      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
    1182      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nADDITION REQUESTED FOR:\n\n");
    1183      NT_add_to_ntfy_list(e_mail_list, forwd_hash, arg2);
    1184    }
    1185    else if (old_object_str != NULL && new_object_str == NULL)
    1186    { /* it was a deletion */
    1187      e_mail_list = NT_gather_frwd_addresses(old_object_str);
    1188      NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
    1189      NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nDELETION REQUESTED FOR:\n\n");
    1190      NT_add_to_ntfy_list(e_mail_list, forwd_hash, old_object_str);
    1191    }
    1192 }
    1193
    1194
    1195
    1196 /* Sends the creation forward message which is stored in the temporary file filename.  */
    1197 void NT_send_forw_creation( const char * filename, const char * to_address, const char * mailercommand)
    1198 {
    1199     char * mail_command_line = NULL;
    1200     char * supress_file = NULL;
    1201     FILE * fc_file, * supr_file_hdl;
    1202     char buf[1024];
    1203
    1204     /* if we are not supressing acks and notifs, send the message */
    1205     if (!supress_ack_notif)
    1206         {
    1207       if (to_address != NULL)
    1208           {
    1209         mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
    1210         sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
    1211         system(mail_command_line);
    1212         free(mail_command_line);
    1213       }
    1214     }
    1215         else
    1216         {
    1217       /* if we are supressing acks and notifs, send the message to DEFMAIL  */
    1218       supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2);
    1219       sprintf(supress_file, "%s.supress", filename);
    1220       if (( supr_file_hdl = fopen(supress_file, "w")) == NULL)
    1221           {
    1222         fprintf(stderr, "Can't open supress forward creation file, %s", supress_file);
    1223       }
    1224           else
    1225           {
    1226         fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed forward creation mail\n\n",
    1227             humailbox, defmail);
    1228         if (( fc_file = fopen(filename, "r")) == NULL)
    1229                 {
    1230           fprintf(stderr, "Can't open forward creation file for reading, %s", filename);
    1231         }
    1232                 else
    1233                 {
    1234           while (fgets(buf, 1023, fc_file) != NULL)
    1235                   {
    1236             fprintf(supr_file_hdl, buf);
    1237           }
    1238           fclose(fc_file);
    1239         }
    1240       }
    1241       fclose(supr_file_hdl);
    1242       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail)
    1243             + strlen(supress_file) + 128);
    1244       sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
    1245       system(mail_command_line);
    1246       unlink(supress_file);
    1247       free(supress_file);
    1248     }
    1249 }
    1250
    1251
    1252 /* NT_forw_create_req forwards the maintainer, as-block and irt creation requests
    1253    to <HUMAILBOX> */
    1254 void NT_forw_create_req(const char * object_str)
    1255 {
    1256    FILE * forw_file;
    1257    char * filename;
    1258    char * replaced_mtfwheader;
    1259    char * replaced_mtfwtxt;
    1260
    1261    /* allocate space for name.  32 should be enough for PID */
    1262    filename = (char*)malloc(strlen(tmpdir) + strlen("creat-forw") +34 );
    1263
    1264    sprintf(filename, "%s/%s.%i", tmpdir, "creat-forw", (int)(getpid()) );
    1265
    1266    /* create the file */
    1267    if (( forw_file = fopen(filename, "w")) == NULL)
    1268    {
    1269      fprintf(stderr, "NT_forw_create_req: Can't open creation forward file for creating, %s", filename);
    1270    }
    1271
    1272    replaced_mtfwheader = UP_replace_globals(mtfwheader);
    1273    replaced_mtfwtxt = UP_replace_globals(mtfwtxt);
    1274
    1275    fprintf(forw_file, "%s\n\n", replaced_mtfwheader);
    1276
    1277    if (reading_from_mail)
    1278    {
    1279      fprintf(forw_file, "%s\n\n", replaced_mtfwtxt);
    1280    }
    1281
    1282    /* print the object */
    1283    fprintf(forw_file, "%s\n\n", object_str);
    1284
    1285    /* close it */
    1286    fclose(forw_file);
    1287
    1288    /* send it */
    1289    NT_send_forw_creation(filename, humailbox, mailcmd);
    1290
    1291    /* log it */
    1292    NT_log_ntfy(filename, forwlog);
    1293
    1294    /* delete it */
    1295    unlink(filename);
    1296
    1297    /* free the mem */
    1298    free(filename);
    1299    free(replaced_mtfwheader);
    1300    free(replaced_mtfwtxt);
    1301 }

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