comparison support/pop/mmdfII/pop/po_wtmail.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children a6481689f99c
comparison
equal deleted inserted replaced
-1:000000000000 0:bce86c4163a3
1 #ifndef POP
2 /* bb_wtmail.c - write mail to a BBoard */
3 #else POP
4 /* po_wtmail.c - write mail for a POP subscriber */
5 #endif POP
6 #ifndef lint
7 static char Id[] = "@(#)$Id$";
8 #endif
9
10
11 #include "util.h"
12 #include "mmdf.h"
13 #include "bboards.h"
14 #include "cnvtdate.h"
15 #include "ch.h"
16 #include "phs.h"
17 #include <pwd.h>
18 #include <sys/stat.h>
19
20 /* */
21
22 #ifndef RP_DOK
23 #define submitopts "vmth%s*"
24 #else RP_DOK
25 #define submitopts "vkmth%s*"
26 #endif RP_DOK
27
28 #ifndef POP
29 #define RP_NOPE RP_AOK
30
31 #define MBXMODE BBMODE
32 #else POP
33 #define RP_NOPE RP_USER
34
35 #define MBXMODE sentprotect
36
37 extern int sentprotect;
38 #endif POP
39
40
41 int err_fd = NOTOK;
42
43 int ds_address ();
44
45 extern int errno;
46
47 int bbrduid, bbrdgid;
48
49 char *chnlname,
50 chnlinfo[LINESIZE];
51 #ifndef POP
52 char bbrdaddr[LINESIZE],
53 bbrdfrom[LINESIZE],
54 bbrdheader[LINESIZE],
55 bbrdhome[LINESIZE],
56 bbrdtime[LINESIZE];
57 #endif not POP
58
59 extern char *qu_msgfile,
60 *delim1,
61 *delim2,
62 *lckdfldir,
63 *locdomain,
64 *locmachine,
65 *locname,
66 *sitesignature,
67 *supportaddr;
68
69 struct bboard *curbb;
70
71 extern LLog *logptr;
72
73 FILE *lk_fopen();
74
75 off_t lseek ();
76 char *index (), *rindex (), *sprintf ();
77 struct passwd *getpwnam ();
78
79 /* */
80
81 bb_init (chanptr)
82 Chan * chanptr;
83 {
84 int uid,
85 eid;
86 struct passwd *pw;
87
88 #ifdef DEBUG
89 ll_log (logptr, LLOGBTR, "bb_init(chanptr=%s)", chanptr -> ch_name);
90 #endif
91
92 chnlname = chanptr -> ch_name;
93 #ifndef notdef
94 sprintf (chnlinfo, submitopts, chnlname);
95 #else notdef /* the following is probably a BAD idea */
96 if (chanptr -> ch_host == NULL)
97 chnlinfo[0] = NULL; /* local delivery ONLY */
98 else
99 sprintf (chnlinfo, submitopts, chanptr -> ch_host);
100 #endif notdef
101
102 #ifndef POP
103 if ((pw = getpwnam (BBOARDS)) == NULL)
104 err_abrt (RP_BHST, "no passwd entry for '%s'", BBOARDS);
105 #else POP
106 if ((pw = getpwnam (POPUID)) == NULL)
107 err_abrt (RP_BHST, "no passwd entry for '%s'", POPUID);
108 #endif POP
109
110 bbrduid = pw -> pw_uid;
111 bbrdgid = pw -> pw_gid;
112 #ifndef POP
113 if (isstr (locmachine))
114 sprintf (bbrdfrom, "%s@%s.%s.%s", pw -> pw_name, locmachine, locname,
115 locdomain);
116 else
117 sprintf (bbrdfrom, "%s@%s.%s", pw -> pw_name, locname, locdomain);
118 #ifdef DEBUG
119 ll_log (logptr, LLOGGEN, "distributing as '%s'", bbrdfrom);
120 #endif
121 sprintf (bbrdhome, pw -> pw_dir);
122 #endif not POP
123
124 #ifndef POP
125 if (!setbbent ())
126 err_abrt (RP_BHST, "setbbent() failed");
127 #else POP
128 if (!setpwinfo (pw, POPDB, 1))
129 err_abrt (RP_BHST, "setbbinfo(%s, %s, 1) failed",
130 pw -> pw_name, POPDB);
131 #endif POP
132
133 getwho (&uid, &eid);
134 if (eid != 0)
135 err_abrt (RP_BHST, "not running as root");
136
137 return RP_OK;
138 }
139
140
141 bb_end (result)
142 short result;
143 {
144 #ifdef DEBUG
145 ll_log (logptr, LLOGBTR, "bb_end(result=0%o)", result);
146 #endif
147
148 return RP_OK;
149 }
150
151 /* */
152
153 bb_sbinit () {
154 #ifdef DEBUG
155 ll_log (logptr, LLOGBTR, "bb_sbinit()");
156 #endif
157
158 return RP_OK;
159 }
160
161
162 bb_sbend () {
163 #ifdef DEBUG
164 ll_log (logptr, LLOGBTR, "bb_sbend()");
165 #endif
166
167 return RP_OK;
168 }
169
170 /* */
171
172 bb_winit (info, sender)
173 char *info,
174 *sender;
175 {
176 #ifdef DEBUG
177 ll_log (logptr, LLOGBTR, "bb_winit(info='%s',sender='%s')",
178 info, sender);
179 #endif
180
181 return RP_OK;
182 }
183
184 /* */
185
186 bb_wtadr (host, adr)
187 char *host,
188 *adr;
189 {
190 short count,
191 result;
192 int len,
193 md,
194 offset,
195 size;
196 long start,
197 stop,
198 pos;
199 char *cp,
200 buffer[BUFSIZ];
201
202 #ifdef DEBUG
203 ll_log (logptr, LLOGBTR, "bb_wtadr(host=%s,adr=%s)", host, adr);
204 #endif
205
206 if ((cp = index (adr, '@')) != NULL)
207 *cp = NULL;
208 make_lower (adr, adr);
209 if ((curbb = getbbnam (adr)) == NULL)
210 return RP_USER;
211 #ifndef POP
212 if (isstr (locmachine))
213 sprintf (bbrdaddr, "local-%s-request@%s.%s.%s", curbb -> bb_name,
214 locmachine, locname, locdomain);
215 else
216 sprintf (bbrdaddr, "local-%s-request@%s.%s", curbb -> bb_name, locname,
217 locdomain);
218 #endif not POP
219 #ifdef DEBUG
220 ll_log (logptr, LLOGGEN, "=> BBoard %s: file='%s' info='%s'",
221 curbb -> bb_name, curbb -> bb_file, curbb -> bb_info);
222 #endif
223
224 if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
225 return RP_NOPE;
226 #ifdef DEBUG
227 ll_log (logptr, LLOGGEN, "begin local delivery...");
228 #endif
229 printx ("\r\nperforming local delivery to file %s...\n",
230 curbb -> bb_file);
231
232 qu_rtinit (0L);
233
234 if ((md = mbx_open (curbb -> bb_file, bbrduid, bbrdgid, MBXMODE)) == NOTOK)
235 return RP_FIO;
236
237 #ifndef POP
238 if (rp_isbad (result = mbx_init ())) {
239 mbx_close (curbb -> bb_file, md);
240 return result;
241 }
242 #endif not POP
243
244 pos = (long) lseek (md, (off_t)0, 1);
245 count = strlen (delim1);
246 if (write (md, delim1, count) != count) {
247 ll_log (logptr, LLOGTMP, "error writing delim1");
248 result = NOTOK;
249 goto clean_up;
250 }
251 start = (long) lseek (md, (off_t)0, 1);
252 size = 0;
253
254 #ifndef POP
255 count = strlen (bbrdheader);
256 if (write (md, bbrdheader, count) != count) {
257 ll_log (logptr, LLOGTMP, "error writing BBoard information");
258 result = NOTOK;
259 goto clean_up;
260 }
261 for (cp = bbrdheader; *cp; cp++, size++)
262 if (*cp == '\n')
263 size++;
264 #endif not POP
265
266 for (len = BUFSIZ;
267 rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
268 len = BUFSIZ) {
269 for (offset = 0;
270 (offset = strindex (delim1, buffer)) >= 0;
271 buffer[offset]++)
272 continue;
273 for (offset = 0;
274 (offset = strindex (delim2, buffer)) >= 0;
275 buffer[offset]++)
276 continue;
277 if (write (md, buffer, len) != len) {
278 ll_log (logptr, LLOGTMP, "error writing to file '%s'",
279 curbb -> bb_file);
280 result = NOTOK;
281 goto clean_up;
282 }
283 for (offset = 0, cp = buffer; offset < len; offset++, size++)
284 if (*cp++ == '\n')
285 size++;
286 }
287
288 if (result < 0)
289 ll_log (logptr, LLOGTMP, "error reading from message file '%s'",
290 qu_msgfile);
291 clean_up: ;
292
293 stop = (long) lseek (md, (off_t)0, 1);
294 count = strlen (delim2);
295 if (write (md, delim2, count) != count)
296 ll_log (logptr, LLOGTMP, "error writing delim2");
297 map_write (curbb -> bb_file, md, curbb -> bb_maxima, start, stop, pos,
298 size, 0);
299 #ifdef DEBUG
300 ll_log (logptr, LLOGGEN, "end local delivery...");
301 #endif
302
303 if (result < 0)
304 mbx_close (curbb -> bb_file, md);
305 else
306 result = mbx_close (curbb -> bb_file, md);
307
308 return (result != NOTOK ? RP_OK : RP_FIO);
309 }
310
311 /* */
312
313 bb_txtcpy () {
314 #ifndef POP
315 short result;
316
317 #ifdef DEBUG
318 ll_log (logptr, LLOGBTR, "bb_txtcpy()");
319 #endif
320
321 if (curbb -> bb_dist == NULL
322 || *curbb -> bb_dist == NULL
323 || chnlinfo[0] == NULL)
324 return RP_MOK;
325 #ifdef DEBUG
326 ll_log (logptr, LLOGGEN, "begin distribution...");
327 #endif
328 if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
329 printx ("\r\n");
330 printx("\rperforming remote distribution\n");
331
332 if (rp_isbad (result = dist_init ())
333 || rp_isbad (result = dist_adrs ())
334 || rp_isbad (result = dist_text ())
335 || rp_isbad (result = dist_end ()))
336 return dist_lose (result);
337 #ifdef DEBUG
338 ll_log (logptr, LLOGGEN, "end distribution...");
339 #endif
340
341 if (err_fd != NOTOK)
342 dist_lose (RP_MOK);
343 else
344 printx ("\rmessage distributed\n");
345 #endif not POP
346
347 return RP_MOK;
348 }
349
350 /* */
351
352 #ifndef POP
353 /* **************** (dist_) BBOARD DISTRIBUTION **************** */
354
355 dist_init () {
356 short result;
357 #ifdef RP_NS
358 int len;
359 struct rp_bufstruct reply;
360 #endif RP_NS
361
362 #ifdef DEBUG
363 ll_log (logptr, LLOGBTR, "dist_init()");
364 #endif
365
366 if (rp_isbad (result = mm_init ()))
367 return ds_log (result, LLOGFAT, "mm_init() failed [%s]",
368 rp_valstr (result));
369 if (rp_isbad (result = mm_sbinit ()))
370 return ds_log (result, LLOGFAT, "mm_sbinit() failed [%s]",
371 rp_valstr (result));
372 if (rp_isbad (result = mm_winit (chnlname, chnlinfo, bbrdaddr)))
373 return ds_log (result, LLOGFAT,
374 "mm_winit('%s','%s','%s') failed [%s]",
375 chnlname, chnlinfo, bbrdaddr, rp_valstr (result));
376 #ifdef RP_NS
377 if (rp_isbad (result = mm_rrply (&reply, &len)))
378 return ds_log (result, LLOGFAT, "problem with sender address [%s]",
379 rp_valstr (result));
380 #endif RP_NS
381
382 return result;
383 }
384
385 /* */
386
387 dist_adrs ()
388 {
389 short result;
390
391 #ifdef DEBUG
392 ll_log (logptr, LLOGBTR, "dist_adrs()");
393 #endif
394
395 if (getbbdist (curbb, ds_address))
396 return ds_log (RP_NO, LLOGTMP, "getbbdist failed: %s", getbberr ());
397
398 if (rp_isbad (result = mm_waend ()))
399 return ds_log (result, LLOGFAT, "mm_waend() failed [%s]",
400 rp_valstr (result));
401
402 return result;
403 }
404
405 /* */
406
407 ds_address (addr, host)
408 char *addr, /* local part */
409 *host; /* rest */
410 {
411 short result;
412 int len;
413 struct rp_bufstruct reply;
414
415 #ifdef DEBUG
416 ll_log (logptr, LLOGBTR, "ds_address(addr='%s',host='%s')", addr, host);
417 #endif
418
419 printx ("\rperforming distribution to %s@%s...\n", addr, host);
420 if (rp_isbad (result = mm_wadr (host, addr))) {
421 ds_log (result, LLOGFAT, "mm_wadr('%s','%s') failed [%s]",
422 host, addr, rp_valstr (result));
423 return NOTOK;
424 }
425 if (rp_isbad (result = mm_rrply (&reply, &len))) {
426 ds_log (result, LLOGFAT,
427 "mm_rrply() failed [%s] getting status of '%s@%s'",
428 rp_valstr (result), addr, host);
429 return NOTOK;
430 }
431
432 switch (rp_gval (reply.rp_val)) {
433 case RP_AOK:
434 #ifdef RP_DOK
435 case RP_DOK:
436 #endif RP_DOK
437 #ifdef DEBUG
438 ll_log (logptr, LLOGGEN, "address '%s@%s' [%s] -- %s",
439 addr, host, rp_valstr (reply.rp_val), reply.rp_line);
440 #endif
441 return OK;
442
443 case RP_NO:
444 #ifdef RP_NS
445 case RP_NS:
446 #endif RP_NS
447 case RP_USER:
448 case RP_NDEL:
449 case RP_AGN:
450 case RP_NOOP:
451 ds_log (reply.rp_val, LLOGTMP, "address '%s@%s' [%s] -- %s",
452 addr, host, rp_valstr (reply.rp_val), reply.rp_line);
453 return OK; /* fail-soft */
454
455 default:
456 ds_log (reply.rp_val, LLOGFAT, "unexpected reply [%s] -- %s",
457 rp_valstr (reply.rp_val), reply.rp_line);
458 return NOTOK;
459 }
460 }
461
462 /* */
463
464 dist_text ()
465 {
466 short result;
467 int len;
468 char buffer[BUFSIZ];
469
470 #ifdef DEBUG
471 ll_log (logptr, LLOGBTR, "dist_text()");
472 #endif
473
474 qu_rtinit (0L);
475 for (len = BUFSIZ;
476 rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
477 len = BUFSIZ)
478 if (rp_isbad (result = mm_wtxt (buffer, len)))
479 return ds_log (result, LLOGFAT, "mm_wtxt() failed [%s]",
480 rp_valstr (result));
481
482 if (result < 0)
483 return ds_log (RP_FIO, LLOGTMP,
484 "error reading from message file '%s'", qu_msgfile);
485
486 if (rp_isbad (result = mm_wtend ()))
487 return ds_log (result, LLOGFAT, "mm_wtend() failed [%s]",
488 rp_valstr (result));
489
490 return result;
491 }
492
493 /* */
494
495 dist_end ()
496 {
497 short result;
498 int len;
499 struct rp_bufstruct reply;
500
501 #ifdef DEBUG
502 ll_log (logptr, LLOGBTR, "dist_end()");
503 #endif
504
505 if (rp_isbad (result = mm_rrply (&reply, &len)))
506 return ds_log (result, LLOGFAT,
507 "mm_rrply() failed [%s] getting final status",
508 rp_valstr (result));
509
510 switch (rp_gval (reply.rp_val)) {
511 case RP_OK:
512 case RP_MOK:
513 #ifdef DEBUG
514 ll_log (logptr, LLOGGEN, "message [%s] -- %s",
515 rp_valstr (reply.rp_val), reply.rp_line);
516 #endif
517 mm_sbend ();
518 mm_end (OK);
519 return result;
520
521 case RP_NO:
522 case RP_NDEL:
523 case RP_AGN:
524 case RP_NOOP:
525 return ds_log (RP_NO, LLOGTMP, "not delivered [%s] -- %s",
526 rp_valstr (reply.rp_val), reply.rp_line);
527
528 default:
529 return ds_log (RP_RPLY, LLOGFAT,
530 "unexpected final reply [%s] -- %s",
531 rp_valstr (reply.rp_val), reply.rp_line);
532 }
533 }
534
535 /* */
536
537 dist_lose (result)
538 short result;
539 {
540 int i;
541 char *cp,
542 intro[BUFSIZ],
543 buffer[BUFSIZ];
544
545 #ifdef DEBUG
546 ll_log (logptr, LLOGBTR, "dist_lose(result=0%o)", result);
547 #endif DEBUG
548
549 mm_end (NOTOK);
550
551 printx ("\rerrors during distribution: ");
552 if (domsg)
553 (void) fflush (stdout);
554 (void) sprintf (intro, "bboards%d distribution for %s failed [%s]\n",
555 getpid (), curbb -> bb_name, rp_valstr (result));
556 if (loseaux (bbrdaddr, bbrdfrom, intro) != OK
557 && loseaux (bbrdfrom, (char *) 0, intro) != OK) {
558 printx ("unable to post advisory.\n");
559 ll_log (logptr, LLOGFAT, "unable to post failure notice");
560 if (err_fd != NOTOK) {
561 (void) lseek (err_fd, (off_t)0, 0);
562 if ((i = read (err_fd, buffer, sizeof buffer)) > 0) {
563 buffer[i] = NULL;
564 if (cp = index (buffer, '\n'))
565 *cp = NULL;
566 ll_log (logptr, LLOGFAT, "info: %s", buffer);
567 }
568 }
569 if (loseaux (supportaddr, (char *) 0, intro) != NOTOK)
570 ll_log (logptr, LLOGFAT, "unable to advise %s of failure!",
571 supportaddr);
572 }
573 else
574 printx ("advisory posted.\n");
575 if (domsg)
576 (void) fflush (stdout);
577
578 if (err_fd != NOTOK) {
579 close (err_fd);
580 err_fd = NOTOK;
581 }
582 return RP_MOK;
583 }
584
585 /* */
586
587 int loseaux (to, cc, intro)
588 char *to,
589 *cc,
590 *intro;
591 {
592 int i;
593 char buffer[BUFSIZ];
594
595 if (ml_init (NO, NO, sitesignature, "Re-distribution Failure") != OK
596 || ml_adr (to) != OK)
597 return NOTOK;
598 if (cc && (ml_cc () != OK || ml_adr (cc) != OK))
599 return NOTOK;
600 if (ml_aend () != OK || ml_tinit () != OK)
601 return NOTOK;
602
603 ml_txt (intro);
604 if (err_fd != NOTOK) {
605 lseek (err_fd, (off_t)0, 0);
606 while ((i = read (err_fd, buffer, sizeof buffer)) > 0) {
607 buffer[i] = NULL;
608 ml_txt (buffer);
609 }
610 }
611 encap ();
612
613 return ml_end (OK);
614 }
615
616 /* */
617
618 /* very similar to sbr/cpydgst.c */
619
620 #define S1 0
621 #define S2 1
622
623 #define output(c) if (bp >= dp) {flush (); *bp++ = c;} else *bp++ = c
624 #define flush() if (bp - outbuf) \
625 *bp = NULL, ml_txt (outbuf), bp = outbuf
626
627 static encap () {
628 register int state;
629 short result;
630 int len,
631 init;
632 register char *cp,
633 *ep;
634 char buffer[BUFSIZ];
635 register char *bp,
636 *dp;
637 char outbuf[BUFSIZ];
638
639 qu_rtinit (0L);
640
641 dp = (bp = outbuf) + sizeof outbuf;
642 init = 0;
643 for (state = S1, len = BUFSIZ;
644 rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
645 len = BUFSIZ)
646 for (ep = (cp = buffer) + len; cp < ep; cp++) {
647 if (*cp == NULL)
648 continue;
649 switch (state) {
650 case S1:
651 if (*cp == '-') {
652 if (init == 0) {
653 ml_txt ("\n------- Forwarded Message\n\n");
654 init++;
655 }
656 output ('-');
657 output (' ');
658 }
659 state = S2; /* fall */
660
661 case S2:
662 if (init == 0) {
663 ml_txt ("\n------- Forwarded Message\n\n");
664 init++;
665 }
666 output (*cp);
667 if (*cp == '\n')
668 state = S1;
669 break;
670 }
671 }
672
673 flush ();
674
675 if (result < 0) {
676 ll_log (logptr, LLOGTMP, "error reading message when noting failure");
677 if (init)
678 ml_txt ("\n------- End of Forwarded Message\n\n");
679 ml_txt ("[ error reading message ]\n");
680 }
681 else
682 if (init)
683 ml_txt ("\n------- End of Forwarded Message\n\n");
684 else {
685 ll_log (logptr, LLOGTMP, "message empty when noting failure");
686 ml_txt ("[ message empty ]\n");
687 }
688 }
689
690 /* */
691
692 /* VARARGS3 */
693
694 ds_log (result, level, fmt, a, b, c, d, e)
695 short result;
696 int level;
697 char *fmt,
698 *a,
699 *b,
700 *c,
701 *d,
702 *e;
703 {
704 int i;
705 char buffer[BUFSIZ],
706 tmpfil[BUFSIZ];
707
708 ll_log (logptr, level, fmt, a, b, c, d, e);
709
710 sprintf (buffer, fmt, a, b, c, d, e);
711 strcat (buffer, "\n");
712
713 printx ("\rerror: %s", buffer);
714
715 if (err_fd == NOTOK) {
716 unlink (mktemp (strcpy (tmpfil, "/tmp/bboardsXXXXXX")));
717 if ((err_fd = creat (tmpfil, 0600)) == NOTOK)
718 return result;
719 close (err_fd);
720 if ((err_fd = open (tmpfil, 2)) == NOTOK)
721 return result;
722 unlink (tmpfil);
723 lseek (err_fd, (off_t)0, 0);
724 }
725 i = strlen (buffer);
726 write (err_fd, buffer, i);
727
728 return result;
729 }
730 #endif not POP
731
732 /* */
733
734 /* mbx_ local mailbox routines */
735
736 #ifndef POP
737 mbx_init () {
738 int fd,
739 clear;
740 char name[BUFSIZ];
741 FILE * fp;
742
743 if ((fd = mbx_Xopen (curbb -> bb_info, bbrduid, bbrdgid, MBXMODE, &clear))
744 == NOTOK) {
745 if (errno == ETXTBSY) {
746 printx ("\runable to lock %s\n", curbb -> bb_info);
747 ll_err (logptr, LLOGTMP, "unable to lock %s",
748 curbb -> bb_info);
749 return RP_LOCK;
750 }
751 printx ("\runable to open '%s'", curbb -> bb_info);
752 ll_log (logptr, LLOGTMP, "unable to open '%s'", curbb -> bb_info);
753 return RP_FOPN;
754 }
755 if ((fp = fdopen (fd, "w")) == (FILE *) NULL) {
756 printx ("\runable to fdopen '%s'", curbb -> bb_info);
757 ll_err (logptr, LLOGTMP, "unable to fdopen '%s'", curbb -> bb_info);
758 mbx_close (curbb -> bb_info, fd);
759 return RP_LIO;
760 }
761
762 strcpy (name, curbb -> bb_name);
763 if ((curbb = getbbnam (name)) == (struct bboard *) NULL) {
764 printx ("\runable to get information on BBoard %s\n", name);
765 ll_err (logptr, LLOGFAT, "unable to get info on %s", name);
766 lkfclose (fp, curbb -> bb_info);
767 return RP_LIO;
768 }
769 sprintf (bbrdheader, "BBoard-ID: %d\nBB-Posted: %s\n",
770 ++curbb -> bb_maxima, cnvtdate (TIMREG, bbrdtime));
771 fprintf (fp, "%d\n%s\n", curbb -> bb_maxima, bbrdtime);
772
773 lkfclose (fp, curbb -> bb_info);
774
775 return RP_OK;
776 }
777 #endif not POP