modules/ak/ack.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- AK_add_to_ack
- AK_add_to_ack_string
- AK_add_file_to_ack
- AK_ack_file_name_generate
- AK_send_ack
- AK_print_ack
- AK_delete_ack
- 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