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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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, ... )
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, ...)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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 | }