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 | }