modules/nt/notification.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
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_add_to_list
- NT_unify_list
- NT_gather_ntfy_addresses
- NT_gather_frwd_addresses
- get_overlapping_routes_list
- NT_write_all_ntfs
- NT_write_all_frwds
- NT_send_forw_creation
- NT_forw_create_req
1 /***************************************
2 $Revision: 1.15 $
3
4 NT (Notifications) module
5
6 Status: NOT REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (06/07/2000) Created.
13 ******************/ /******************
14 Copyright (c) 2000 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33
34
35
36
37
38
39 #include "notification.h"
40 extern int supress_ack_notif;
41 extern char * defmail;
42 extern int reading_from_mail;
43
44 /* Generates a unique file name and returns the full path of the filename
45 for storing notification message. Creates the file at the same time.
46 May use PID or time or both to ensure uniqueness. */
47
48 char * NT_ntfy_filename_generate( const char * tmpdir, const char * e_mail){
/* [<][>][^][v][top][bottom][index][help] */
49
50 FILE * ntfy_file;
51 char * name;
52 char * replaced_notimailtxt;
53
54 /* allocate space for name. 32 should be enough for PID */
55 name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("notify") +32 );
56
57 sprintf(name, "%s/%s-%s.%i", tmpdir, "notify", e_mail, getpid());
58
59 /* create the file */
60 if(( ntfy_file = fopen(name, "w")) == NULL){
61 fprintf(stderr, "Can't open notification file for creating, %s", name);
62 }
63
64 fprintf(ntfy_file, "To: %s\nFrom: %s\nSubject: Notification of RIPE Database changes\nReply-To: %s\n\n%s\n", e_mail, humailbox, humailbox, notitxt);
65 if(reading_from_mail){
66 replaced_notimailtxt = UP_replace_globals(notimailtxt);
67 fprintf(ntfy_file, "%s\n\n", replaced_notimailtxt);
68 free(replaced_notimailtxt);
69 }
70 /* close it */
71 fclose(ntfy_file);
72
73 return name;
74
75 }
76
77
78
79
80
81 /* Generates a unique file name and returns the full path of the filename
82 for storing forwarded message. Creates the file at the same time. */
83 char * NT_forwd_filename_generate( const char * tmpdir, const char * e_mail){
/* [<][>][^][v][top][bottom][index][help] */
84
85 FILE * forwd_file;
86 char * name;
87 char * replaced_fwmailtxt;
88
89 /* allocate space for name. 32 should be enough for PID */
90 name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("forwd") +32 );
91
92 sprintf(name, "%s/%s-%s.%i", tmpdir, "forwd", e_mail, getpid());
93 //printf("DEBUG: NT_forwd_filename_generate: will generate %s\n", name);
94 /* create the file */
95 if(( forwd_file = fopen(name, "w")) == NULL){
96 fprintf(stderr, "Can't open forward file, %s", name);
97 }
98
99 fprintf(forwd_file, "To: %s\nFrom: %s\nSubject: Requested RIPE database object changes \nReply-To: %s\n\n%s\n", e_mail, humailbox, humailbox, fwtxt);
100 if(reading_from_mail){
101 replaced_fwmailtxt = UP_replace_globals(fwmailtxt);
102 fprintf(forwd_file, "\n%s\n", replaced_fwmailtxt);
103 free(replaced_fwmailtxt);
104 }
105
106 /* close it */
107 fclose(forwd_file);
108
109 return name;
110
111 }
112
113
114
115
116
117 /* Generates a unique file name and returns the full path of the filename
118 for storing cross notification message. Creates the file at the same time. */
119 char * NT_cross_filename_generate( const char * tmpdir, const char * e_mail, int mode){
/* [<][>][^][v][top][bottom][index][help] */
120
121 FILE * cross_file;
122 char * name;
123
124 /* allocate space for name. 32 should be enough for PID */
125 name = (char*)malloc(strlen(tmpdir) + strlen(e_mail) + strlen("cross") +32 );
126
127 sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, getpid());
128 //printf("DEBUG: NT_cross_filename_generate: will generate %s\n", name);
129 /* create the file */
130 if(( cross_file = fopen(name, "w")) == NULL){
131 fprintf(stderr, "Can't open cross notif file, %s", name);
132 }
133
134 //printf("DEBUG: NT_cross_filename_generate: e_mail=[%s], humailbox=[%s]\n", e_mail, humailbox);
135 if(mode == ADDITION){
136 fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_add, humailbox);
137 }else{
138 fprintf(cross_file, "To: %s\nFrom: %s\n%s\nReply-To: %s\n\n", e_mail, humailbox, cno_subject_del, humailbox);
139 }
140
141 /* close it */
142 fclose(cross_file);
143
144 return name;
145
146 }
147
148
149
150
151
152
153
154 /* Generates a unique file name and returns the full path of the filename for
155 storing notification message. Creates the file at the same time. */
156 char * NT_crossntfy_filename_generate( const char * tmpdir, const char * e_mail){
/* [<][>][^][v][top][bottom][index][help] */
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") +32 );
162
163 sprintf(name, "%s/%s-%s.%i", tmpdir, "cross", e_mail, getpid());
164
165 /* create the file */
166 if(( cross_file = fopen(name, "w")) == NULL){
167 fprintf(stderr, "Can't open cross file, %s", name);
168 }
169
170 /* close it */
171 fclose(cross_file);
172
173 return name;
174
175 }
176
177
178
179
180
181 /* Adds the e-mail to the notify hash, generating appropriate temp files */
182 void NT_add_to_ntfy_hash(GHashTable * ntfy_hash, char * e_mail){
/* [<][>][^][v][top][bottom][index][help] */
183
184 if(g_hash_table_lookup(ntfy_hash ,e_mail) == NULL){/* there is no such entry, so create it */
185
186 g_hash_table_insert(ntfy_hash, strdup(e_mail), NT_ntfy_filename_generate(tmpdir, e_mail));
187
188 }
189
190 }
191
192
193
194
195 /* Adds the e-mail to the forw hash, generating appropriate temp files */
196 void NT_add_to_frwd_hash(GHashTable * frwd_hash, char * e_mail){
/* [<][>][^][v][top][bottom][index][help] */
197
198 if(g_hash_table_lookup(frwd_hash ,e_mail) == NULL){/* there is no such entry, so create it */
199 g_hash_table_insert(frwd_hash, strdup(e_mail), NT_forwd_filename_generate(tmpdir, e_mail));
200 }
201
202 }
203
204
205
206
207
208 /* Adds the e-mail to the cross hash, generating appropriate temp files */
209 void NT_add_to_cross_hash(GHashTable * cross_hash, const char * e_mail, int mode){
/* [<][>][^][v][top][bottom][index][help] */
210
211 if(g_hash_table_lookup(cross_hash ,e_mail) == NULL){/* there is no such entry, so create it */
212 g_hash_table_insert(cross_hash, strdup(e_mail), NT_cross_filename_generate(tmpdir, e_mail, mode));
213 }
214
215 }
216
217
218
219
220
221 /* Adds the e-mails in a linked list to the hash */
222 void NT_add_to_ntfy_hash_list(GHashTable * ntfy_hash, GSList * e_mail_list){
/* [<][>][^][v][top][bottom][index][help] */
223
224 GSList * temp = NULL;
225
226 for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
227 NT_add_to_ntfy_hash(ntfy_hash, (char *)temp->data);
228 }
229
230 }
231
232
233
234
235 /* Adds the e-mails in a linked list to the hash */
236 void NT_add_to_frwd_hash_list(GHashTable * frwd_hash, GSList * e_mail_list){
/* [<][>][^][v][top][bottom][index][help] */
237
238 GSList * temp = NULL;
239
240 for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
241 NT_add_to_frwd_hash(frwd_hash, (char *)temp->data);
242 }
243
244 }
245
246
247
248 /* Adds the e-mails in a linked list to the hash */
249 void NT_add_to_cross_hash_list(GHashTable * cross_hash, GSList * e_mail_list, int mode){
/* [<][>][^][v][top][bottom][index][help] */
250
251 GSList * temp = NULL;
252
253 for(temp = e_mail_list; temp != NULL; temp = g_slist_next(temp)){
254 NT_add_to_cross_hash(cross_hash, (char *)temp->data, mode);
255 }
256
257 }
258
259
260
261
262
263
264 /* Appends the argument strings to the file. */
265 void NT_add_to_ntfy( char * filename, char * fmt, ... ){
/* [<][>][^][v][top][bottom][index][help] */
266 va_list ap; /* points to each unnamed arg in turn */
267 FILE * ntfy_file;
268
269 if(tracing){
270 printf("TRACING: NT_add_to_ntfy\n");
271 }
272 if(( ntfy_file = fopen(filename, "a")) == NULL){
273 fprintf(stderr, "Can't open notification file for writing, %s\n", filename);
274 return;
275 }
276
277 va_start(ap, fmt);
278 vfprintf(ntfy_file, fmt, ap);
279
280 va_end(ap); /* clean up */
281 fclose(ntfy_file);
282 }
283
284
285
286 /* Appends the argument strings to the file. */
287 void NT_add_to_cross(const char * e_mail, GHashTable * hash, char * fmt, ...){
/* [<][>][^][v][top][bottom][index][help] */
288
289 va_list ap; /* points to each unnamed arg in turn */
290 FILE * cross_file;
291 char * filename;
292
293 if(g_hash_table_lookup(hash, find_email_address(e_mail)) != NULL){
294 filename = (char *)g_hash_table_lookup(hash, find_email_address(e_mail));
295 }else{
296 fprintf(stderr, "Can't find a cross notification file for e-mail %s\n", e_mail);
297 return;
298 }
299
300 if(( cross_file = fopen(filename, "a")) == NULL){
301 fprintf(stderr, "Can't open cross notification file, %s\n", filename);
302 }
303
304
305
306 if(tracing){
307 printf("TRACING: NT_add_to_cross\n");
308 }
309 if(( cross_file = fopen(filename, "a")) == NULL){
310 fprintf(stderr, "Can't open cross notification file for writing, %s\n", filename);
311 }
312
313 va_start(ap, fmt);
314 vfprintf(cross_file, fmt, ap);
315
316 va_end(ap); /* clean up */
317 fclose(cross_file);
318
319
320 }
321
322
323
324
325
326 /* Appends the argument string to the temp notif files in the list */
327 void NT_add_to_ntfy_list(GSList * list, GHashTable * hash, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
328
329 GSList * temp = NULL;
330
331 for(temp = list; temp != NULL; temp = g_slist_next(temp)){
332 NT_add_to_ntfy((char *)g_hash_table_lookup(hash, ((char *)temp->data)), arg);
333 }
334 }
335
336
337
338
339
340
341
342
343 /* Sends the notification message which is stored in the temporary filefilename. */
344 void NT_send_ntfy( const char * filename, const char * to_address, const char * mailercommand){
/* [<][>][^][v][top][bottom][index][help] */
345
346 char * mail_command_line = NULL;
347 char * supress_file = NULL;
348 FILE * notif_file, * supr_file_hdl;
349 char buf[1024];
350
351
352 /* if we are not supressing acks and notifs, send the notif */
353 if(!supress_ack_notif){
354 if(to_address != NULL){
355 mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
356 sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
357 system(mail_command_line);
358 }
359 /* if we are supressing acks and notifs, send notif to DEFMAIL */
360 }else{
361 supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2);
362 sprintf(supress_file, "%s.supress", filename);
363 if(( supr_file_hdl = fopen(supress_file, "w")) == NULL){
364 fprintf(stderr, "Can't open supress notif file, %s", supress_file);
365 }else{
366 fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed notif mail\n\n",
367 humailbox, defmail);
368 if(( notif_file = fopen(filename, "r")) == NULL){
369 fprintf(stderr, "Can't open notif file for reading, %s", filename);
370 }else{
371 while(fgets(buf, 1023, notif_file) != NULL){
372 fprintf(supr_file_hdl, buf);
373 }
374 fclose(notif_file);
375 }
376 }
377 fclose(supr_file_hdl);
378 mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail)
379 + strlen(supress_file) + 128);
380 sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
381 system(mail_command_line);
382 unlink(supress_file);
383 free(supress_file);
384 }
385
386
387 }
388
389
390
391 /* Adds the notification message which is in the filename into log_file. */
392 void NT_log_ntfy( const char * filename, const char * logfilename){
/* [<][>][^][v][top][bottom][index][help] */
393
394 FILE * notif_file, * log_file;
395 char * buf;
396 time_t cur_time;
397 char * time_str;
398
399 buf = (char *)malloc(1024);
400 if(( notif_file = fopen(filename, "r")) == NULL){
401 fprintf(stderr, "Can't open notification file for reading, [%s]\n", filename);
402 return;
403 }
404
405 if(( log_file = fopen(logfilename, "a")) == NULL){
406 fprintf(stderr, "Can't open log file, %s\n", logfilename);
407 return;
408 }
409
410 /* get time */
411 cur_time = time(NULL);
412 time_str = strdup(ctime(&cur_time));
413 /* cut the '\n' at the end */
414 time_str[strlen(time_str) - 1] = '\0';
415
416 fprintf(log_file, ">>> time: %s NOTIF <<<\n\n", time_str);
417
418
419 while((buf=fgets(buf, 1023, notif_file)) > 0){
420 fprintf(log_file, "%s", buf);
421 }
422 free(buf);
423
424 fclose(notif_file);
425 fclose(log_file);
426
427 }
428
429
430 /* Deletes the temporary notification file. */
431 void NT_delete_ntfy( const char * filename){
/* [<][>][^][v][top][bottom][index][help] */
432
433 unlink(filename);
434
435 }
436
437
438 /* The function required for NT_send_ntfy_list */
439 void nt_gfunc_send(gpointer key, gpointer value, gpointer user_data){
/* [<][>][^][v][top][bottom][index][help] */
440 NT_send_ntfy((char *)value, (char *)key, (char *)user_data);
441 }
442
443
444
445 /* Sends the notification messages whose temp files are stored in filehash. */
446 void NT_send_ntfy_list( GHashTable * filehash, char * mailercommand){
/* [<][>][^][v][top][bottom][index][help] */
447
448 g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_send, mailercommand);
449
450 }
451
452
453
454
455 /* The function required for NT_log_ntfy_list */
456 void nt_gfunc_log(gpointer key, gpointer value, gpointer user_data){
/* [<][>][^][v][top][bottom][index][help] */
457 NT_log_ntfy((char *)value, (char *)user_data);
458 }
459
460
461
462
463 /* Logs the notification whose temp files are in filehash to log_file. */
464 void NT_log_ntfy_list( GHashTable * filehash, char * log_file){
/* [<][>][^][v][top][bottom][index][help] */
465
466 g_hash_table_foreach( filehash, (GHFunc)nt_gfunc_log, log_file);
467
468 }
469
470
471
472 /* The function required for NT_delete_ntfy_list */
473 void nt_gfunc_delete(gpointer key, gpointer value, gpointer user_data){
/* [<][>][^][v][top][bottom][index][help] */
474 NT_delete_ntfy((char *)value);
475 }
476
477
478
479 /* Deletes the temporary notification messages in the filehash. Empties and frees
480 the hash too. */
481 void NT_delete_ntfy_list( GHashTable * filehash){
/* [<][>][^][v][top][bottom][index][help] */
482
483 g_hash_table_foreach(filehash, (GHFunc)nt_gfunc_delete, NULL);
484 g_hash_table_destroy(filehash);
485
486 }
487
488
489 /* to be used with g_hash_table_foreach in NT_unify_list.
490 Adds the 'key' to the list (a GSList) */
491 void nt_add_to_list(char * key, char * value, GSList ** list){
/* [<][>][^][v][top][bottom][index][help] */
492
493 *list = g_slist_append(*list, strdup(value));
494
495
496 }
497
498
499
500 /* "unifies" a list in a case insensitive manner */
501 GSList * NT_unify_list(GSList * in_list){
/* [<][>][^][v][top][bottom][index][help] */
502
503 GHashTable * unification_hash;
504 GSList ** out_list;
505 GSList * temp;
506 char * key, * value;
507
508 /* allocate space for out_list */
509 out_list = (GSList **)malloc(sizeof(GSList *));
510 *out_list = NULL;
511
512 /* initialize the hash to be used for unification process */
513 unification_hash = g_hash_table_new(g_str_hash, g_str_equal);
514
515 /* first put the list elements into a hash, to unify them */
516 for(temp = in_list; temp != NULL; temp = g_slist_next(temp)){
517
518 /* convert the string into lowercase */
519 key = strdup((char *)(temp->data));
520 g_strdown(key);
521 value = strdup((char *)(temp->data));
522
523 if(g_hash_table_lookup(unification_hash, key) == NULL){/* if it is not there */
524
525 g_hash_table_insert(unification_hash, key, value);
526
527 }
528 }
529
530 /* now, get the elements back from the hash into a list */
531 g_hash_table_foreach(unification_hash, (GHFunc)nt_add_to_list, out_list);
532
533 g_slist_free(in_list);
534 g_hash_table_destroy(unification_hash);
535
536 return *out_list;
537
538 }
539
540
541
542
543
544
545
546
547 /* Gathers e-mail boxes to which we will send normal notification messages. It
548 takes old and new objects, looks up maintainers and less specific inetnums/domains/routes
549 when necessary, finds the addresses (in mnt-nfy and notify attributes) and returns
550 a list of them. */
551 GSList * NT_gather_ntfy_addresses( char * old_object, char * new_object){
/* [<][>][^][v][top][bottom][index][help] */
552 GSList * return_list = NULL, * temp = NULL;
553 GSList * mntners = NULL;
554
555 if(old_object != NULL && new_object != NULL){/* it was an update */
556 temp = get_attr_list(old_object, "notify");
557 mntners = get_mntners(old_object);
558 temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
559 }else if(old_object == NULL && new_object != NULL){/* it was a creation */
560 temp = get_attr_list(new_object, "notify");
561 mntners = get_mntners(new_object);
562 temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
563 }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
564 temp = get_attr_list(old_object, "notify");
565 mntners = get_mntners(old_object);
566 temp = g_slist_concat(temp, get_mntnfy_vector(mntners));
567 }
568
569 /* we have to 'unify' the list here! */
570 return_list = NT_unify_list(temp);
571
572 return return_list;
573 }
574
575
576
577 /* Gathers e-mail boxes to which we will forward messages (or rather, objects). It
578 an object, looks up maintainers, finds the addresses (in upd-to attributes) and returns
579 a list of them. */
580 GSList * NT_gather_frwd_addresses(char * object){
/* [<][>][^][v][top][bottom][index][help] */
581 GSList *temp = NULL;
582 GSList * mntners = NULL;
583
584 mntners = get_mntners(object);
585 temp = get_updto_vector(mntners);
586 return temp;
587 }
588
589
590
591
592 /* Accepts a route object as a "* char" and returns a list of overlapping routes */
593 overlap_routes get_overlapping_routes_list(char * object){
/* [<][>][^][v][top][bottom][index][help] */
594
595 char * route_prefix = NULL;
596 GSList * tmp_list;
597 char * result;
598 char * query_string;
599 overlap_routes result_routes;
600
601 result_routes.less_spec = NULL;
602 result_routes.exact_match = NULL;
603 result_routes.more_spec = NULL;
604
605 tmp_list = get_attr_list(object, "route");
606
607 if(tmp_list != NULL && tmp_list->data != NULL){
608 route_prefix = strdup((char *)(tmp_list->data));
609 }else{
610 return result_routes; /* then, this wasn't a route object */
611 }
612
613 /* get the less specific route objects */
614 /* form the query string */
615 query_string = (char *)malloc(strlen("-Troute -r -L ") + strlen(route_prefix) + 2);
616 sprintf(query_string, "-Troute -r -L %s", route_prefix);
617
618 /* get the results */
619 result = send_and_get(query_host, query_port, query_string);
620 free(query_string);
621
622 /* and fill in the result field */
623 result_routes.less_spec = take_objects(result);
624
625 /* get the exact match route objects */
626 /* form the query string */
627 query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(route_prefix) + 2);
628 sprintf(query_string, "-Troute -r -x %s", route_prefix);
629
630 /* get the results */
631 result = send_and_get(query_host, query_port, query_string);
632 free(query_string);
633
634 /* and fill in the result field */
635 result_routes.exact_match = take_objects(result);
636
637 /* get the more specific route objects */
638 /* form the query string */
639 query_string = (char *)malloc(strlen("-Troute -r -M ") + strlen(route_prefix) + 2);
640 sprintf(query_string, "-Troute -r -M %s", route_prefix);
641
642 /* get the results */
643 result = send_and_get(query_host, query_port, query_string);
644 free(query_string);
645
646 /* and fill in the result field */
647 result_routes.more_spec = take_objects(result);
648
649 /* Return the results */
650 return result_routes;
651
652 }
653
654
655
656
657
658 /* Gets old and new versions of the object, and creates temporary notification
659 files when necessary, and then writes appropriate strings into those
660 temporary files. */
661 void NT_write_all_ntfs(char * old_object, char * new_object, /*const char * notif_log,
/* [<][>][^][v][top][bottom][index][help] */
662 const char * forw_log, const char * cross_log,*/ const char * tempdir,
663 GHashTable * ntfy_hash, GHashTable * forwd_hash, GHashTable * cross_hash,
664 char * from_address){
665
666 GSList * e_mail_list = NULL;
667 //GSList * cross_route_list = NULL;
668 GSList * temp = NULL;
669 char * e_mail_address;
670 overlap_routes overlapping_routes;
671
672 /* from_address may contain also the name, like "Johnny Bravo <johnny@inter.net>",
673 so extract the e-mail address from it */
674 e_mail_address = find_email_address(from_address);
675
676
677 if(tracing && reading_from_mail){
678 printf("TRACING: NT_write_all_ntfs: from_address=[%s], e_mail_address=[%s]\n", from_address, e_mail_address);
679 }
680 if(old_object != NULL && new_object != NULL){/* it was an update */
681 e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
682 NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
683 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nPREVIOUS OBJECT:\n\n");
684 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
685 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n\nREPLACED BY:\n\n");
686 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, new_object);
687 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
688 }else if(old_object == NULL && new_object != NULL){/* it was a creation */
689 e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
690 NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
691 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW CREATED:\n\n");
692 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, new_object);
693 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
694 /* We'll deal with cross notifications only when we create or delete route objects */
695 if(strcmp(get_class_type_char(new_object), "route") == 0){
696 NT_add_to_cross_hash(cross_hash, e_mail_address, ADDITION);
697 overlapping_routes = get_overlapping_routes_list(new_object);
698 if(overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
699 overlapping_routes.more_spec != NULL ){
700 //printf("DEBUG: NT_write_all_ntfs: e_mail_address=[%s]\n", e_mail_address);
701 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);
702 if(overlapping_routes.less_spec != NULL){
703 NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
704 for(temp = overlapping_routes.less_spec; temp != NULL; temp = g_slist_next(temp)){
705 NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
706 }
707 }
708 if(overlapping_routes.exact_match != NULL){
709 NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
710 for(temp = overlapping_routes.exact_match; temp != NULL; temp = g_slist_next(temp)){
711 NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
712 }
713 }
714 if(overlapping_routes.more_spec != NULL){
715 NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
716 for(temp = overlapping_routes.more_spec; temp != NULL; temp = g_slist_next(temp)){
717 NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
718 }
719 }
720 }
721 }
722 }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
723 old_object = delete_delete_attrib(old_object);
724 e_mail_list = NT_gather_ntfy_addresses(old_object, new_object);
725 NT_add_to_ntfy_hash_list(ntfy_hash, e_mail_list);
726 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "---\nOBJECT BELOW DELETED:\n\n");
727 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, old_object);
728 NT_add_to_ntfy_list(e_mail_list, ntfy_hash, "\n");
729 /* We'll deal with cross notifications only when we create or delete route objects */
730 if(strcmp(get_class_type_char(old_object), "route") == 0){
731 NT_add_to_cross_hash(cross_hash, e_mail_address, DELETION);
732 overlapping_routes = get_overlapping_routes_list(old_object);
733 if(overlapping_routes.less_spec != NULL || overlapping_routes.exact_match != NULL ||
734 overlapping_routes.more_spec != NULL ){
735 //printf("DEBUG: NT_write_all_ntfs: e_mail_address=[%s]\n", e_mail_address);
736 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);
737 if(overlapping_routes.less_spec != NULL){
738 NT_add_to_cross(from_address, cross_hash, "LESS SPECIFIC MATCHES\n\n");
739 for(temp = overlapping_routes.less_spec; temp != NULL; temp = g_slist_next(temp)){
740 NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
741 }
742 }
743 if(overlapping_routes.exact_match != NULL){
744 NT_add_to_cross(from_address, cross_hash, "EXACT MATCHES\n\n");
745 for(temp = overlapping_routes.exact_match; temp != NULL; temp = g_slist_next(temp)){
746 NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
747 }
748 }
749 if(overlapping_routes.more_spec != NULL){
750 NT_add_to_cross(from_address, cross_hash, "MORE SPECIFIC MATCHES\n\n");
751 for(temp = overlapping_routes.more_spec; temp != NULL; temp = g_slist_next(temp)){
752 NT_add_to_cross(from_address, cross_hash, "%s\n\n", (char *)temp->data);
753 }
754 }
755 }
756 }
757 }
758 }
759
760
761
762
763
764 /* Gets old and new versions of the object, and creates temporary notification
765 files when necessary, and then writes appropriate strings into those
766 temporary files. */
767 void NT_write_all_frwds(char * old_object, char * new_object, /*const char * notif_log,
/* [<][>][^][v][top][bottom][index][help] */
768 const char * forw_log, const char * cross_log,*/ const char * tempdir,
769 GHashTable * ntfy_hash, GHashTable * forwd_hash, GHashTable * cross_hash,
770 const char * from_address){
771
772 GSList * e_mail_list = NULL;
773
774
775 if(tracing){
776 printf("TRACING: NT_write_all_frwds\n");
777 }
778 if(old_object != NULL && new_object != NULL){/* it was an update */
779 e_mail_list = NT_gather_frwd_addresses(old_object);
780 NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
781 NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nUPDATE REQUESTED FOR:\n\n");
782 NT_add_to_ntfy_list(e_mail_list, forwd_hash, new_object);
783 }else if(old_object == NULL && new_object != NULL){/* it was a creation */
784 e_mail_list = NT_gather_frwd_addresses(new_object);
785 NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
786 NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nADDITION REQUESTED FOR:\n\n");
787 NT_add_to_ntfy_list(e_mail_list, forwd_hash, new_object);
788 }else if(old_object != NULL && new_object == NULL){/* it was a deletion */
789 e_mail_list = NT_gather_frwd_addresses(old_object);
790 NT_add_to_frwd_hash_list(forwd_hash, e_mail_list);
791 NT_add_to_ntfy_list(e_mail_list, forwd_hash, "----\nDELETION REQUESTED FOR:\n\n");
792 NT_add_to_ntfy_list(e_mail_list, forwd_hash, old_object);
793 }
794 }
795
796
797
798 /* Sends the creation forward message which is stored in the temporary filefilename. */
799 void NT_send_forw_creation( const char * filename, const char * to_address, const char * mailercommand){
/* [<][>][^][v][top][bottom][index][help] */
800
801 char * mail_command_line = NULL;
802
803
804 if(to_address != NULL){
805 mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(filename) + 128);
806 sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
807 system(mail_command_line);
808 free(mail_command_line);
809 }
810
811 }
812
813
814
815
816
817 /* NT_forw_create_req forwards the maintainer and as-block creation requests
818 to <HUMAILBOX> */
819 void NT_forw_create_req(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
820
821 FILE * forw_file;
822 char * name;
823 char * replaced_mtfwheader;
824 char * replaced_mtfwtxt;
825
826 /* allocate space for name. 32 should be enough for PID */
827 name = (char*)malloc(strlen(tmpdir) + strlen("creat-forw") +32 );
828
829 sprintf(name, "%s/%s.%i", tmpdir, "creat-forw", getpid());
830
831 /* create the file */
832 if(( forw_file = fopen(name, "w")) == NULL){
833 fprintf(stderr, "Can't open creation forward file for creating, %s", name);
834 }
835
836 replaced_mtfwheader = UP_replace_globals(mtfwheader);
837 replaced_mtfwtxt = UP_replace_globals(mtfwtxt);
838
839 fprintf(forw_file, "%s\n\n", replaced_mtfwheader);
840
841 if(reading_from_mail){
842 fprintf(forw_file, "%s\n\n", replaced_mtfwtxt);
843 }
844
845 /* print the object */
846 fprintf(forw_file, "%s\n\n", object);
847
848 /* close it */
849 fclose(forw_file);
850
851 /* send it */
852 NT_send_forw_creation(name, humailbox, mailcmd);
853
854 /* delete it */
855 unlink(name);
856
857 /* free the mem */
858 free(name);
859 free(replaced_mtfwheader);
860 free(replaced_mtfwtxt);
861 }