modules/ak/ack.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. AK_add_to_ack
  2. AK_add_to_ack_string
  3. AK_add_file_to_ack
  4. AK_ack_file_name_generate
  5. AK_send_ack
  6. AK_print_ack
  7. AK_delete_ack
  8. AK_log_ack

   1 /***************************************
   2   $Revision: 1.13 $
   3 
   4   AK (Acknowledgement) module
   5 
   6   Status: NOT REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (10/06/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 #include "ack.h"
  37 extern int supress_ack_notif;
  38 extern char * humailbox;
  39 extern char * defmail;
  40 extern char * acksig;
  41 extern int * reading_from_mail;
  42 extern int networkupdate;
  43 extern up_subject_struct subject_result;
  44 
  45 /*
  46 
  47   AK_add_to_ack: writes a message to the acknowledgement file.
  48     Also, prints it out to the stdout if it was a networkupdate
  49     (networkupdate is run through inetd, so stdout is our socket)
  50 
  51 */
  52 
  53 void AK_add_to_ack(const char * filename, char * fmt, ...){
     /* [<][>][^][v][top][bottom][index][help] */
  54 
  55   va_list ap;  /* points to each unnamed arg in turn */
  56   char *p, *sval;
  57   int ival;
  58   double dval;
  59   FILE * ack_file;
  60   
  61   if(( ack_file = fopen(filename, "a")) == NULL){
  62     fprintf(stderr, "Can't open ack file, %s", filename);
  63   }
  64 
  65     
  66   /* if this is a network update, print it out first to the 
  67      stdout (which is socket) */ 
  68   if(networkupdate){
  69     va_start(ap, fmt);
  70     vprintf(fmt, ap);
  71     fflush(stdout);
  72     va_end(ap); 
  73   }
  74 
  75   /* and then to the file */
  76   va_start(ap, fmt);
  77   
  78   for(p = fmt; *p; p++){
  79     if (*p != '%') {
  80       fprintf(ack_file, "%c", *p);
  81       continue;
  82     }
  83     switch(*++p) {
  84     case 'd':
  85       ival = va_arg(ap, int);
  86       fprintf(ack_file, "%d", ival);
  87       break;
  88     case 'f':
  89       dval = va_arg(ap, double);  
  90       fprintf(ack_file, "%f", dval);
  91       break;
  92     case 'X':
  93       ival = va_arg(ap, int);
  94       fprintf(ack_file, "%X", ival);
  95       break;
  96     case 'x':
  97       ival = va_arg(ap, int);
  98       fprintf(ack_file, "%x", ival);
  99       break;
 100     case 's':
 101       sval = va_arg(ap, char *);
 102       fprintf(ack_file, "%s", sval);
 103       break;
 104     default:
 105       putchar(*p);
 106       break;
 107     }
 108   }
 109 
 110   va_end(ap); /* clean up */
 111   fclose(ack_file);
 112 }
 113 
 114 
 115 
 116 /* Adds a C++ string to the filename */
 117 void AK_add_to_ack_string(const char * file_name, const string msg){
     /* [<][>][^][v][top][bottom][index][help] */
 118 
 119    ofstream ack_file(file_name, ios::app);
 120 
 121    if(!ack_file){
 122      cerr << "Couldn't open ack file" << endl;
 123      return;
 124    }
 125    ack_file << msg;
 126    ack_file.close();
 127 
 128    /* Print this also to the stdout (socket) if it was a
 129       networkupdate */
 130    if(networkupdate){
 131    cout << msg << flush;
 132    }
 133 }
 134 
 135 
 136 
 137 
 138 /* Adds a complete file to the ack file */
 139 
 140 void AK_add_file_to_ack(const char * ackfile, const char * filetoadd){
     /* [<][>][^][v][top][bottom][index][help] */
 141 
 142   FILE * ack_file, * file_to_add;
 143   char * buf;
 144 
 145   buf = (char *)malloc(1024);
 146   
 147   if(( ack_file = fopen(ackfile, "a")) == NULL){
 148     fprintf(stderr, "AK_add_file_to_ack: Can't open ack file, %s\n", ackfile);
 149   }
 150   
 151   if(( file_to_add = fopen(filetoadd, "r")) == NULL){
 152     
 153     fprintf(stderr, "AK_add_file_to_ack: Can't open file, %s\n", filetoadd);
 154     fprintf(ack_file, "\nHelp file could not be found.\nPlease notify the database administrator.\n");
 155     fclose(ack_file);
 156     free(buf);
 157 
 158   }else{
 159  
 160     while((buf=fgets(buf, 1023, file_to_add)) > 0){
 161       fprintf(ack_file, "%s", buf);
 162     }
 163 
 164     fclose(ack_file);
 165     fclose(file_to_add);
 166     free(buf);
 167   }
 168 }
 169 
 170 
 171 
 172 
 173 /*
 174 
 175   AK_ack_file_name_generate: Generates a unique name for temporary acknowledgement
 176      files, and also creates it. 
 177 
 178       tmpdir: temporary directory (without a trailing '/')
 179       prefix: prefix for the temp file
 180       
 181       returns: the generated name. 
 182      
 183 
 184 */
 185 
 186 char * AK_ack_file_name_generate( const char * tmpdir, const char * prefix){
     /* [<][>][^][v][top][bottom][index][help] */
 187 
 188    FILE * ack_file;
 189    char * name;
 190       
 191    /* allocate space for name. 32 should be enough for PID */
 192    name = (char*)malloc(strlen(tmpdir) + strlen(prefix) + 32); 
 193    
 194    sprintf(name, "%s/%s.%i", tmpdir, prefix, getpid());
 195 
 196    /* create the file */
 197    if(( ack_file = fopen(name, "w")) == NULL){
 198      fprintf(stderr, "Can't open ack file, %s", name);
 199    }
 200 
 201    /* close it */
 202    fclose(ack_file);
 203     
 204    return name;
 205 
 206 }
 207 
 208 
 209 /* 
 210 
 211 AK_send_ack: sends the ack message contained in the temp file.
 212  
 213    
 214 */
 215 
 216 void AK_send_ack( const char * filename, const char * to_address, const char * mailercommand){
     /* [<][>][^][v][top][bottom][index][help] */
 217 
 218     char * mail_command_line = NULL;
 219     char * supress_file = NULL;
 220     FILE * ack_file, * supr_file_hdl;
 221     char buf[1025];
 222 
 223 
 224     /* first check if we the user specified some non-keyword words in
 225        the subject line (in addition to some valid keywords) 
 226        If so, we will add a warning to the ack file */
 227     if(subject_result.result == UP_SUBJ_UNRECOG){
 228       
 229       if(( ack_file = fopen(filename, "a")) == NULL){
 230         
 231         fprintf(stderr, "Can't open ack file for appending, %s", filename);
 232         
 233       }else{
 234        
 235         fprintf(ack_file, "\nWarning: unknown keywords found in subject line:\n"
 236                    "%s\n"
 237                    "Thus, all keywords in subject line were ignored.\n",
 238                     subject_result.word_list ? subject_result.word_list : "" );
 239         fclose(ack_file);
 240         
 241       }
 242       
 243     /* and now check if the user specified an invalid combination of keywords
 244        in the subject line, and if so, print an appropriate warning to ack */
 245     }else if(subject_result.result == UP_SUBJ_INVALID_COMB){
 246       
 247       if(( ack_file = fopen(filename, "a")) == NULL){
 248         
 249         fprintf(stderr, "Can't open ack file for appending, %s", filename);
 250         
 251       }else{
 252        
 253         fprintf(ack_file, "\nWarning: This combination of keywords in subject line is not allowed.\n"
 254                    "Thus, all keywords in subject line were ignored.\n");
 255         fclose(ack_file);
 256         
 257       }
 258 
 259       
 260     }
 261 
 262 
 263     /* add the ACKSIG to the ack */
 264     AK_add_to_ack(filename ,"\n%s", acksig);
 265 
 266 
 267 
 268     /* if we are not supressing acks and notifs, send the ack */
 269     if(!supress_ack_notif){
 270       if(to_address != NULL){
 271         mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(to_address) 
 272             + strlen(filename) + 128);
 273         sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
 274         system(mail_command_line);
 275       }
 276     /* if we are supressing acks and notifs, send ack to DEFMAIL  */
 277     }else{
 278       supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2); 
 279       sprintf(supress_file, "%s.supress", filename);
 280       if(( supr_file_hdl = fopen(supress_file, "w")) == NULL){
 281         fprintf(stderr, "Can't open supress ack file, %s", supress_file);
 282       }else{
 283         fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed ack mail\n\n",
 284             humailbox, defmail);
 285         if(( ack_file = fopen(filename, "r")) == NULL){
 286           fprintf(stderr, "Can't open ack file for reading, %s", filename);
 287         }else{
 288           while(fgets(buf, 1024, ack_file) != NULL){
 289             fprintf(supr_file_hdl, buf);
 290           }
 291           fclose(ack_file);
 292         }
 293       }
 294       fclose(supr_file_hdl);
 295       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail) 
 296             + strlen(supress_file) + 128);
 297       sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
 298       system(mail_command_line);
 299       unlink(supress_file);
 300       free(supress_file);
 301     }
 302 
 303 
 304 }
 305 
 306 
 307 
 308 /*
 309 
 310   AK_print_ack: Prints out the given file (the ack file) to the standard output
 311 
 312 */
 313 void AK_print_ack( const char * filename ){
     /* [<][>][^][v][top][bottom][index][help] */
 314 
 315     FILE * ack_file;
 316     char buf[1025];
 317 
 318     if(( ack_file = fopen(filename, "r")) == NULL){
 319       fprintf(stderr, "Can't open ack file for reading, %s", filename);
 320     }else{
 321       while(fgets(buf, 1024, ack_file) != NULL){
 322         printf(buf);
 323       }
 324       fclose(ack_file);
 325     }
 326 
 327 }
 328 
 329 
 330 
 331 
 332 
 333 /*
 334 
 335   AK_delete_ack: deletes the temporary acknowledgement file.
 336 
 337 */
 338 
 339 void AK_delete_ack( const char * filename ){
     /* [<][>][^][v][top][bottom][index][help] */
 340 
 341    unlink(filename);   
 342 
 343 }
 344 
 345 /*
 346 
 347 AK_log_ack: logs the acknowledgements in the "logfilename.date".
 348 
 349 */
 350 
 351 void AK_log_ack(const char * filename, const char * logfilename){
     /* [<][>][^][v][top][bottom][index][help] */
 352 
 353   FILE * ack_file, * log_file;
 354   char * buf;
 355   time_t cur_time;
 356   char * time_str;
 357   char * logfile_date;
 358   char * date;
 359 
 360   if(( ack_file = fopen(filename, "r")) == NULL){
 361     fprintf(stderr, "Can't open ack file for reading, %s\n", filename);
 362     return;
 363   }
 364 
 365 
 366   /* construct the "logfilename.date" string */
 367   logfile_date = (char *)malloc(strlen(logfilename) + 10);
 368   date = UP_get_current_date();
 369   snprintf(logfile_date, strlen(logfilename) + 10, "%s.%s", logfilename, date);
 370   free(date);
 371 
 372 
 373 
 374   if(( log_file = fopen(logfile_date, "a")) == NULL){
 375     fprintf(stderr, "Can't open log file for appending, %s\n", logfile_date);
 376     return;
 377   }
 378 
 379   /* get time */
 380   cur_time = time(NULL);
 381   time_str = strdup(ctime(&cur_time));
 382   /* cut the '\n' at the end */
 383   time_str[strlen(time_str) - 1] = '\0';
 384 
 385   if(reading_from_mail){
 386     fprintf(log_file, ">>> time: %s MAIL ACK <<<\n\n", time_str);
 387   }else if(networkupdate){
 388     fprintf(log_file, ">>> time: %s NETWORKUPDATE ACK <<<\n\n", time_str);
 389   }else{
 390     fprintf(log_file, ">>> time: %s ACK <<<\n\n", time_str);
 391   }
 392 
 393   buf = (char *)malloc(1024);
 394   while((buf=fgets(buf, 1023, ack_file)) > 0){
 395     fprintf(log_file, "%s", buf);
 396   }
 397   free(buf);
 398 
 399   free(time_str);
 400   fclose(ack_file);
 401   fclose(log_file);
 402 
 403 }
 404 
 405 
 406 
 407 
 408 
 409 
 410 
 411 

/* [<][>][^][v][top][bottom][index][help] */