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