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.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