## 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] */