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.11 $
   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", ackfile);
 149   }
 150   
 151   if(( file_to_add = fopen(filetoadd, "r")) == NULL){
 152     fprintf(stderr, "AK_add_file_to_ack: Can't open file, %s", filetoadd);
 153   }
 154  
 155   while((buf=fgets(buf, 1023, file_to_add)) > 0){
 156     fprintf(ack_file, "%s", buf);
 157   }
 158 
 159   fclose(ack_file);
 160   fclose(file_to_add);
 161   free(buf);
 162  
 163 }
 164 
 165 
 166 
 167 
 168 /*
 169 
 170   AK_ack_file_name_generate: Generates a unique name for temporary acknowledgement
 171      files, and also creates it. 
 172 
 173       tmpdir: temporary directory (without a trailing '/')
 174       prefix: prefix for the temp file
 175       
 176       returns: the generated name. 
 177      
 178 
 179 */
 180 
 181 char * AK_ack_file_name_generate( const char * tmpdir, const char * prefix){
     /* [<][>][^][v][top][bottom][index][help] */
 182 
 183    FILE * ack_file;
 184    char * name;
 185       
 186    /* allocate space for name. 32 should be enough for PID */
 187    name = (char*)malloc(strlen(tmpdir) + strlen(prefix) + 32); 
 188    
 189    sprintf(name, "%s/%s.%i", tmpdir, prefix, getpid());
 190 
 191    /* create the file */
 192    if(( ack_file = fopen(name, "w")) == NULL){
 193      fprintf(stderr, "Can't open ack file, %s", name);
 194    }
 195 
 196    /* close it */
 197    fclose(ack_file);
 198     
 199    return name;
 200 
 201 }
 202 
 203 
 204 /* 
 205 
 206 AK_send_ack: sends the ack message contained in the temp file.
 207  
 208    
 209 */
 210 
 211 void AK_send_ack( const char * filename, const char * to_address, const char * mailercommand){
     /* [<][>][^][v][top][bottom][index][help] */
 212 
 213     char * mail_command_line = NULL;
 214     char * supress_file = NULL;
 215     FILE * ack_file, * supr_file_hdl;
 216     char buf[1025];
 217 
 218 
 219     /* first check if we the user specified some non-keyword words in
 220        the subject line (in addition to some valid keywords) 
 221        If so, we will add a warning to the ack file */
 222     if(subject_result.result == UP_SUBJ_UNRECOG){
 223       
 224       if(( ack_file = fopen(filename, "a")) == NULL){
 225         
 226         fprintf(stderr, "Can't open ack file for appending, %s", filename);
 227         
 228       }else{
 229        
 230         fprintf(ack_file, "\nWarning: unknown keywords found in subject line:\n"
 231                    "%s\n"
 232                    "Thus, all keywords in subject line were ignored.\n",
 233                     subject_result.word_list ? subject_result.word_list : "" );
 234         fclose(ack_file);
 235         
 236       }
 237       
 238     /* and now check if the user specified an invalid combination of keywords
 239        in the subject line, and if so, print an appropriate warning to ack */
 240     }else if(subject_result.result == UP_SUBJ_INVALID_COMB){
 241       
 242       if(( ack_file = fopen(filename, "a")) == NULL){
 243         
 244         fprintf(stderr, "Can't open ack file for appending, %s", filename);
 245         
 246       }else{
 247        
 248         fprintf(ack_file, "\nWarning: This combination of keywords in subject line is not allowed.\n"
 249                    "Thus, all keywords in subject line were ignored.\n");
 250         fclose(ack_file);
 251         
 252       }
 253 
 254       
 255     }
 256 
 257 
 258     /* add the ACKSIG to the ack */
 259     AK_add_to_ack(filename ,"\n%s", acksig);
 260 
 261 
 262 
 263     /* if we are not supressing acks and notifs, send the ack */
 264     if(!supress_ack_notif){
 265       if(to_address != NULL){
 266         mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(to_address) 
 267             + strlen(filename) + 128);
 268         sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
 269         system(mail_command_line);
 270       }
 271     /* if we are supressing acks and notifs, send ack to DEFMAIL  */
 272     }else{
 273       supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2); 
 274       sprintf(supress_file, "%s.supress", filename);
 275       if(( supr_file_hdl = fopen(supress_file, "w")) == NULL){
 276         fprintf(stderr, "Can't open supress ack file, %s", supress_file);
 277       }else{
 278         fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed ack mail\n\n",
 279             humailbox, defmail);
 280         if(( ack_file = fopen(filename, "r")) == NULL){
 281           fprintf(stderr, "Can't open ack file for reading, %s", filename);
 282         }else{
 283           while(fgets(buf, 1024, ack_file) != NULL){
 284             fprintf(supr_file_hdl, buf);
 285           }
 286           fclose(ack_file);
 287         }
 288       }
 289       fclose(supr_file_hdl);
 290       mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail) 
 291             + strlen(supress_file) + 128);
 292       sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
 293       system(mail_command_line);
 294       unlink(supress_file);
 295       free(supress_file);
 296     }
 297 
 298 
 299 }
 300 
 301 
 302 
 303 /*
 304 
 305   AK_print_ack: Prints out the given file (the ack file) to the standard output
 306 
 307 */
 308 void AK_print_ack( const char * filename ){
     /* [<][>][^][v][top][bottom][index][help] */
 309 
 310     FILE * ack_file;
 311     char buf[1025];
 312 
 313     if(( ack_file = fopen(filename, "r")) == NULL){
 314       fprintf(stderr, "Can't open ack file for reading, %s", filename);
 315     }else{
 316       while(fgets(buf, 1024, ack_file) != NULL){
 317         printf(buf);
 318       }
 319       fclose(ack_file);
 320     }
 321 
 322 }
 323 
 324 
 325 
 326 
 327 
 328 /*
 329 
 330   AK_delete_ack: deletes the temporary acknowledgement file.
 331 
 332 */
 333 
 334 void AK_delete_ack( const char * filename ){
     /* [<][>][^][v][top][bottom][index][help] */
 335 
 336    unlink(filename);   
 337 
 338 }
 339 
 340 /*
 341 
 342 AK_log_ack: logs the acknowledgements in the log_file.
 343 
 344 */
 345 
 346 void AK_log_ack(const char * filename, const char * logfilename){
     /* [<][>][^][v][top][bottom][index][help] */
 347 
 348   FILE * ack_file, * log_file;
 349   char * buf;
 350   time_t cur_time;
 351   char * time_str;
 352 
 353   if(( ack_file = fopen(filename, "r")) == NULL){
 354     fprintf(stderr, "Can't open ack file, %s\n", filename);
 355     return;
 356   }
 357 
 358   if(( log_file = fopen(logfilename, "a")) == NULL){
 359     fprintf(stderr, "Can't open log file, %s\n", logfilename);
 360     return;
 361   }
 362 
 363   /* get time */
 364   cur_time = time(NULL);
 365   time_str = strdup(ctime(&cur_time));
 366   /* cut the '\n' at the end */
 367   time_str[strlen(time_str) - 1] = '\0';
 368 
 369   if(reading_from_mail){
 370     fprintf(log_file, ">>> time: %s MAIL ACK <<<\n\n", time_str);
 371   }else if(networkupdate){
 372     fprintf(log_file, ">>> time: %s NETWORKUPDATE ACK <<<\n\n", time_str);
 373   }else{
 374     fprintf(log_file, ">>> time: %s ACK <<<\n\n", time_str);
 375   }
 376 
 377   buf = (char *)malloc(1024);
 378   while((buf=fgets(buf, 1023, ack_file)) > 0){
 379     fprintf(log_file, "%s", buf);
 380   }
 381   free(buf);
 382 
 383   free(time_str);
 384   fclose(ack_file);
 385   fclose(log_file);
 386 
 387 }
 388 
 389 
 390 
 391 
 392 
 393 
 394 
 395 

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