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