/[pkg-mixmaster]/trunk/Mix2.0/Src/send.c
ViewVC logotype

Contents of /trunk/Mix2.0/Src/send.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 200 - (show annotations) (download)
Wed Aug 28 20:06:48 2002 UTC (10 years, 8 months ago) by rabbi
File MIME type: text/plain
File size: 11813 byte(s)
Initial revision
1
2 /* $Id: send.c,v 1.1 2002/08/28 20:06:50 rabbi Exp $
3 * $Log: send.c,v $
4 * Revision 1.1 2002/08/28 20:06:50 rabbi
5 * Initial revision
6 *
7 * Revision 2.8 1998/08/21 13:26:08 um
8 * *** empty log message ***
9 *
10 * Revision 2.7 1998/05/11 19:43:16 um
11 * *** empty log message ***
12 *
13 * Revision 2.6 1998/05/10 22:16:21 um
14 * Bug fix.
15 *
16 * Revision 2.5 1998/05/07 23:59:36 um
17 * IDEXP and PACKETEXP now specify hours.
18 *
19 * Revision 2.4 1998/04/20 14:09:47 um
20 * Bug fix for trimming ID log file, by Johannes Kroeger.
21 *
22 * Revision 2.3 1998/04/13 23:22:29 um
23 * re-indented.
24 *
25 * Revision 2.2 1998/03/02 16:37:21 um
26 * fuction getline() replaces fgets() + chop().
27 *
28 *
29 * send.c 1997-12-22 um
30 * bug fix from Johannes Kroeger.
31 *
32 * send.c 1997-12-12 um
33 * return value for attempt_socket dummy corrected.
34 *
35 * send.c 1997-12-08 um
36 * bug fix by Andy Dustman.
37 *
38 * send.c 1997-11-08 um
39 * attempt_socket now exists.
40 *
41 * send.c 1997-10-10 JK
42 * parse header lines without " " after the ":" correctly.
43 *
44 * send.c 1997-09-15 um
45 * do not try to read multi-line header if the line is empty
46 * (patch from Johannes Kroeger).
47 * fix overflow bug in reading multi-line header.
48 *
49 * send.c 1997-08-30 um
50 * parse multiple-line message headers.
51 *
52 * send.c 1997-08-29 um
53 * bug fix: add mail2news gate only for "post:" destination.
54 * headers are filtered only for the final hop.
55 *
56 * send.c 1997-08-15 um
57 * re-wrote process_pool.
58 *
59 * send.c 1997-07-01 um
60 * middleman patch.
61 *
62 * send.c 1997-06-08 um
63 * use random_number to select message from pool to get even distribution
64 *
65 * send.c 1997-05-31 um
66 * exponential pool.
67 *
68 * send.c 1996-11-27 um
69 * No spaces in Newsgroups: line.
70 *
71 * modified for DOS.
72 * applied Lance's patch for "null:" um
73 *
74 * send.c 1.6 11/2/95
75 * Fixed several bugs in process_partial()
76 * Insert commas between recipients on the To line.
77 * Fixed problems from not re-initializing some variables
78 * for each mail message.
79 *
80 * send.c 1.5 9/13/95
81 * Mail2news now uses "Newsgroups:" not group.name@gateway.
82 *
83 * send.c 1.4 9/10/95
84 * "null:" sends mail to a bit bucket
85 * "post:" posts to the following newsgroup
86 *
87 * (c) Copyright 1995 by Lance Cottrell. All right reserved.
88 * The author assumes no liability for damages resulting from the
89 * use of this software, even if the damage results from defects in
90 * this software. No warranty is expressed or implied.
91 *
92 * This software is being distributed under the GNU Public Licence,
93 * see the file GNU.license for more details.
94 *
95 * - Lance Cottrell (loki@obscura.com) 4/23/95
96 *
97 */
98
99 #include "mix.h"
100 #include <stdlib.h>
101 #include <string.h>
102 #include <unistd.h>
103 #include <time.h>
104
105 #if 1
106 int
107 mix_server (int dofork)
108 {
109 return (0); /* dummy which always reports failure (true) */
110 }
111
112 int
113 attempt_socket (FILE * fp)
114 {
115 return (0); /* dummy which always reports failure (true) */
116 }
117
118 #endif
119
120 #define MAILMSG 1
121 #define POSTMSG 2
122 #define REMAILMSG 4
123
124 int
125 read_header (FILE * in, BUFFER * mess, int mm)
126 {
127 char line[8 * 1024], line2[1024], *t;
128 BUFFER *maildest, *groupdest;
129 int subject = 0, post = 0, r = 0;
130 long p;
131
132 maildest = new_buffer ();
133 groupdest = new_buffer ();
134
135 /* Read in the destination */
136 while (getline (line, sizeof (line), in) && !streq (line, "END"))
137 {
138 for (;;)
139 {
140 p = ftell (in);
141 if (getline (line2, sizeof (line2), in) &&
142 (line2[0] == ' ' || line2[0] == '\t'))
143 {
144 strncat (line, "\n", sizeof (line) - strlen (line) - 1);
145 strncat (line, line2, sizeof (line) - strlen (line) - 1);
146 }
147 else
148 break;
149 }
150 fseek (in, p, SEEK_SET);
151 if (strileft (line, "null:"))
152 return (0); /* bit bucket message */
153 else if (strileft (line, "post:"))
154 {
155 post = 1;
156 if (strlen (line) > sizeof ("post:") - 1)
157 {
158 t = line + sizeof ("post:") - 1;
159 while (*t == ' ' || *t == '\t')
160 t++;
161 add_addr (groupdest, t, &mm); /* group name */
162 }
163 }
164 else if (strlen (line) > 0)
165 add_addr (maildest, line, &mm);
166 }
167
168 /* Read in the header lines */
169 if (mm != -1)
170 while (getline (line, sizeof (line), in))
171 {
172 if (line[0] == '\0')
173 {
174 p = ftell (in);
175 if (getline (line2, sizeof (line2), in) && strleft (line2, "##"))
176 getline (line, sizeof (line), in); /* paste in more headers */
177 else
178 {
179 fseek (in, p, SEEK_SET);
180 break; /* end of header */
181 }
182 }
183 for (;;)
184 {
185 p = ftell (in);
186 if (getline (line2, sizeof (line2), in) &&
187 (line2[0] == ' ' || line2[0] == '\t'))
188 {
189 strncat (line, "\n", sizeof (line) - strlen (line) - 1);
190 strncat (line, line2, sizeof (line) - strlen (line) - 1);
191 }
192 else
193 break;
194 }
195 fseek (in, p, SEEK_SET);
196 if (strileft (line, "To:"))
197 {
198 t = line + sizeof ("To:") - 1;
199 while (*t == ' ' || *t == '\t')
200 t++;
201 add_addr (maildest, t, &mm);
202 }
203 else if (strileft (line, "Newsgroups:"))
204 {
205 /* will be posted only if "post:" is set */
206 t = line + sizeof ("Newsgroups:") - 1;
207 while (*t == ' ' || *t == '\t')
208 t++;
209 add_addr (groupdest, t, &mm);
210 }
211 else if (!header_block (line, &mm))
212 {
213 str_to_buffer (mess, line);
214 str_to_buffer (mess, "\n");
215
216 if (strileft (line, "Subject:"))
217 subject = 1;
218 }
219 }
220
221 if (groupdest->length < 1)
222 post = 0;
223 else if (post && (strlen (MAILtoNEWS) > 1))
224 add_addr (maildest, MAILtoNEWS, &mm);
225
226 if (maildest->length > 1)
227 {
228 str_to_buffer (mess, "To: ");
229 str_to_buffer (mess, maildest->message);
230 str_to_buffer (mess, "\n");
231 }
232
233 if (groupdest->length > 1)
234 {
235 str_to_buffer (mess, "Newsgroups: ");
236 str_to_buffer (mess, groupdest->message);
237 str_to_buffer (mess, "\n");
238 }
239
240 if (mm >= 2)
241 r |= REMAILMSG;
242 if (maildest->length > 1)
243 r |= MAILMSG;
244 if (post)
245 r |= POSTMSG;
246
247 free_buffer (maildest);
248 free_buffer (groupdest);
249
250 if (post && !subject)
251 str_to_buffer (mess, "Subject: none\n");
252
253 str_to_buffer (mess, "\n");
254
255 /* Read in the message body */
256 while (getline (line, sizeof (line), in))
257 {
258 str_to_buffer (mess, line);
259 str_to_buffer (mess, "\n");
260 }
261
262 return (r);
263 }
264
265 int
266 process_pool (void)
267 {
268 FILE *fptr, *in, *lockptr;
269 char **names, line[256], *tmp;
270 int pool, i, j, final, dest;
271 time_t start_time = time (NULL);
272 BUFFER *mess;
273
274 /* For the sake of ruthless efficiency, we will only build the list once. */
275 mix_lock ("mail", &lockptr);
276 i = file_list ("mail*", NULL);
277 names = malloc (i * sizeof (*names));
278 pool = file_list ("mail*", names);
279 mix_unlock ("mail", lockptr);
280 i = (i * RATE) / 100; /* exponential pool */
281 if (i < 1)
282 i = 1;
283
284 for (; pool > POOLSIZE && i > 0
285 && (POOLTIMEOUT == 0 || time (NULL) - start_time < POOLTIMEOUT); i--)
286 {
287 mix_lock ("mail", &lockptr);
288 final = 0;
289
290 j = random_number (pool); /* 0 to (pool-1) */
291 if ((in = open_mix_file (names[j], "r")) == NULL)
292 {
293 mix_unlock ("mail", lockptr);
294 return (0);
295 }
296 /* Is it a final hop? */
297 getline (line, sizeof (line), in);
298 if (streq (line, final_hop))
299 final = 1;
300 else
301 {
302 /* is it also not an intermed hop ? */
303 if (!streq (line, intermed_hop))
304 {
305 fclose (in);
306 strcpy (line, "bad-");
307 in = tempfile (line);
308 fprintf (in, "Placeholder\n");
309 fclose (in);
310 fprintf (errlog, "%s not a valid mail file!\nMoving to %s\n",
311 names[j], line);
312 if (rename (names[j], line) == -1)
313 fprintf (errlog, "Failed!\n");
314 continue; /* Try another mail file */
315 }
316 }
317
318 if (!final)
319 {
320 if (attempt_socket (in)) /* try to open a socket */
321 goto skip; /* attempt socket returns 0 if it fails */
322 }
323
324 /* Send message by mail */
325 mess = new_buffer ();
326
327 /* Read in the message header */
328 dest = read_header (in, mess, final ? MIDDLEMAN : -1);
329 if (final && MIDDLEMAN && !(dest & REMAILMSG))
330 {
331 /* message will be sent directly. filter the header properly */
332 rewind (in);
333 getline (line, sizeof (line), in);
334 clear_buffer (mess);
335 dest = read_header (in, mess, 0);
336 }
337
338 if (dest & (MAILMSG | REMAILMSG))
339 { /* There are mail addresses */
340 if ((fptr = open_sendmail (final ?
341 (dest & REMAILMSG ? 2 : -1) : -2,
342 &tmp)) == NULL)
343 goto skip;
344 if ((dest & POSTMSG) && (dest & REMAILMSG))
345 fprintf (fptr, "post:\n");
346 write_buffer (mess, fptr);
347 close_sendmail (fptr, tmp);
348 }
349 if ((dest & POSTMSG) && !(dest & REMAILMSG) && strlen (NEWS) > 1)
350 { /* Post through inews */
351 if ((fptr = open_pipe (NEWS, "w")) == NULL)
352 goto skip;
353 fromanon (fptr);
354 if (strlen (ORGANIZATION) > 0)
355 fprintf (fptr, "Organization: %s\n", ORGANIZATION);
356 write_buffer (mess, fptr);
357 close_pipe (fptr);
358 }
359 free_buffer (mess);
360
361 skip: /* Skip to here if message is for bit bucket */
362 fclose (in);
363 stats (FL_LATENCY, names[j]);
364 unlink (names[j]);
365 mix_unlock ("mail", lockptr);
366 free (names[j]);
367 if (pool > 0)
368 names[j] = names[--pool];
369 }
370 return (1);
371 }
372
373 void
374 process_latent (void)
375 {
376 int num, i;
377 unsigned long ctime, stime;
378 FILE *fptr, *out;
379 char *names[256], line[256], foo[80];
380
381 num = file_list ("latent*", names);
382 for (i = 0; i < num; i++)
383 {
384 if ((fptr = open_mix_file (names[i], "r")) != NULL)
385 {
386 getline (line, sizeof (line), fptr);
387 sscanf (line, "%s %lu", foo, &stime);
388 ctime = time (NULL);
389 if (ctime > stime)
390 {
391 /* now open up a mail file and put the body there */
392 unlink (names[i]);
393 sprintf (foo, "mail");
394 out = tempfile (foo);
395 while (getline (line, sizeof (line), fptr) != NULL)
396 fprintf (out, "%s\n", line);
397 fclose (out);
398 fclose (fptr);
399 } /* passed time */
400 } /* if could open latent */
401 } /* for */
402 }
403
404 void
405 process_partial (void)
406 {
407 int num, i;
408 unsigned char j;
409 unsigned long ctime, stime;
410 FILE *fptr, *lockptr;
411 char *names[256];
412
413 mix_lock ("pac", &lockptr);
414 num = file_list ("pac*", names);
415 for (i = 0; i < num; i++)
416 {
417 if ((fptr = open_mix_file (names[i], "r")) != NULL)
418 {
419 fread (&j, 1, 1, fptr);
420 stime = (unsigned long) j;
421 fread (&j, 1, 1, fptr);
422 stime += (unsigned long) j *256;
423 fread (&j, 1, 1, fptr);
424 stime += (unsigned long) j *256 * 256;
425 fread (&j, 1, 1, fptr);
426 stime += (unsigned long) j *256 * 256 * 256;
427
428 ctime = time (NULL);
429
430 if ((ctime - stime) > PACKETEXP * 3600)
431 { /* packet is too old */
432 fclose (fptr);
433 unlink (names[i]);
434 }
435 else
436 {
437 fclose (fptr);
438 } /* passed expiration time */
439 } /* if could open packet */
440 } /* for */
441 mix_unlock ("pac", lockptr);
442 }
443
444 int
445 packetID_housekeeping (void)
446 {
447 FILE *fptr, *lockptr;
448 char line[256], ID[50];
449 unsigned long now, then;
450 BUFFER *buff;
451
452 if (IDEXP == 0)
453 return (0);
454
455 mix_lock (IDLOG, &lockptr);
456 buff = new_buffer ();
457 now = time (NULL);
458 if ((fptr = try_open_mix_file (IDLOG, "r")) == NULL)
459 return (-1);
460
461 while (getline (line, sizeof (line), fptr) != NULL)
462 {
463 sscanf (line, "%s %lu", ID, &then);
464 if ((now - then) < IDEXP * 3600)
465 {
466 str_to_buffer (buff, line);
467 str_to_buffer (buff, "\n");
468 }
469 }
470 fclose (fptr);
471 if ((fptr = open_mix_file (IDLOG, "w")) == NULL)
472 return (-1);
473 write_buffer (buff, fptr);
474 fclose (fptr);
475 free_buffer (buff);
476 mix_unlock (IDLOG, lockptr);
477 return (0);
478 }

  ViewVC Help
Powered by ViewVC 1.1.5