/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- NT_ntfy_filename_generate
- NT_forwd_filename_generate
- NT_cross_filename_generate
- NT_crossntfy_filename_generate
- NT_add_to_ntfy_hash
- NT_add_to_frwd_hash
- NT_add_to_cross_hash
- NT_add_to_ntfy_hash_list
- NT_add_to_frwd_hash_list
- NT_add_to_cross_hash_list
- NT_add_to_ntfy
- NT_add_to_cross
- NT_add_to_ntfy_list
- NT_send_ntfy
- NT_log_ntfy
- NT_delete_ntfy
- nt_gfunc_send
- NT_send_ntfy_list
- nt_gfunc_log
- NT_log_ntfy_list
- nt_gfunc_delete
- NT_delete_ntfy_list
- nt_free_list
- NT_unify_list
- 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 }