Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / support / bboards / mmdfI / bboards / RCS / bb_wtmail.c,v
1 head    1.3;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.3
9 date    93.08.25.17.43.26;      author jromine; state Exp;
10 branches;
11 next    1.2;
12
13 1.2
14 date    93.08.25.17.22.00;      author jromine; state Exp;
15 branches;
16 next    1.1;
17
18 1.1
19 date    93.08.25.17.21.49;      author jromine; state Exp;
20 branches;
21 next    ;
22
23
24 desc
25 @@
26
27
28 1.3
29 log
30 @add id
31 @
32 text
33 @/* bb_wtmail.c - write mail to a BBoard */
34 #ifndef lint
35 static char Id[] = "@@(#)$Id:$";
36 #endif
37
38 #include "util.h"
39 #include "mmdf.h"
40 #include "ch.h"
41 #include "bboards.h"
42 #include "tws.h"
43 #include <pwd.h>
44 #include <sys/stat.h>
45
46 /* \f */
47
48 int     err_fd = NOTOK;
49
50 int     dist_address ();
51
52 extern int  errno;
53
54 int     bbrduid, bbrdgid;
55
56 char   *channelname,
57         channelinfo[LINESIZE],
58         bbrdaddr[LINESIZE],
59         bbrdfrom[LINESIZE],
60         bbrdheader[LINESIZE],
61         bbrdhome[LINESIZE],
62         bbrdtime[LINESIZE];
63
64 extern char *qu_msgfile,
65             delim1[],
66             delim2[],
67             locname[],
68             sitesignature[];
69
70 struct bboard  *curbb;
71
72 extern struct ll_struct *logptr;
73
74
75 off_t    lseek ();
76 char   *index (), *rindex (), *sprintf ();
77 struct passwd  *getpwnam ();
78
79 /* \f */
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_spec);
90 #endif
91
92     channelname = chanptr -> ch_spec;
93 #ifndef notdef
94     sprintf (channelinfo, "vmth%s*", channelname);
95 #else   notdef                  /* the following is probably a BAD idea */
96     if (chanptr -> ch_host == NULL)
97         channelinfo[0] = NULL;  /* local delivery ONLY */
98     else
99         sprintf (channelinfo, "vmth%s*", chanptr -> ch_host);
100 #endif  notdef
101
102     if ((pw = getpwnam (BBOARDS)) == NULL)
103         err_abrt (RP_BHST, "no passwd entry for '%s'", BBOARDS);
104     bbrduid = pw -> pw_uid;
105     bbrdgid = pw -> pw_gid;
106     sprintf (bbrdfrom, "%s@@%s", pw -> pw_name, locname);
107 #ifdef DEBUG
108     ll_log (logptr, LLOGGEN, "distributing as '%s'", bbrdfrom);
109 #endif
110     sprintf (bbrdhome, pw -> pw_dir);
111
112     if (!setbbent ())
113         err_abrt (RP_BHST, "setbbent() failed");
114
115     getwho (&uid, &eid);
116     if (eid != 0)
117         err_abrt (RP_BHST, "not running as root");
118
119     return RP_OK;
120 }
121
122
123 bb_end (result)
124 short   result;
125 {
126 #ifdef DEBUG
127     ll_log (logptr, LLOGBTR, "bb_end(result=0%o)", result);
128 #endif
129
130     return RP_OK;
131 }
132
133 /* \f */
134
135 bb_sbinit () {
136 #ifdef DEBUG
137     ll_log (logptr, LLOGBTR, "bb_sbinit()");
138 #endif
139
140     return RP_OK;
141 }
142
143
144 bb_sbend () {
145 #ifdef DEBUG
146     ll_log (logptr, LLOGBTR, "bb_sbend()");
147 #endif
148
149     return RP_OK;
150 }
151
152 /* \f */
153
154 bb_winit (info, sender)
155 char   *info,
156        *sender;
157 {
158 #ifdef DEBUG
159     ll_log (logptr, LLOGBTR, "bb_winit(info='%s',sender='%s')",
160             info, sender);
161 #endif
162
163     return RP_OK;
164 }
165
166 /* \f */
167
168 bb_wtadr (host, adr)
169 char   *host,
170        *adr;
171 {
172     short   count,
173             result;
174     int     i,
175             md,
176             offset,
177             qd,
178             size;
179     long    start,
180             stop,
181             pos;
182     char   *cp,
183             buffer[BUFSIZ];
184
185 #ifdef DEBUG
186     ll_log (logptr, LLOGBTR, "bb_wtadr(host=%s,adr=%s)", host, adr);
187 #endif
188
189     make_lower (adr, adr);
190     if ((curbb = getbbnam (adr)) == NULL)
191         return RP_USER;
192     sprintf (bbrdaddr, "local-%s-request@@%s", curbb -> bb_name, locname);
193 #ifdef DEBUG
194     ll_log (logptr, LLOGGEN, "=> BBoard %s: file='%s' info='%s addr='%s'",
195             curbb -> bb_name, curbb -> bb_file, curbb -> bb_info, bbrdaddr);
196 #endif
197
198     if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
199         return RP_AOK;
200 #ifdef DEBUG
201     ll_log (logptr, LLOGGEN, "begin local delivery...");
202 #endif
203     printx ("\r\nperforming local delivery to file %s...\n",
204             curbb -> bb_file);
205
206     qu_rtinit (0L);
207     if ((qd = dup (qu_fileno ())) == NOTOK) {
208         ll_log (logptr, LLOGFAT, "unable to dup qu_fileno()");
209         return RP_LIO;
210     }
211
212     if ((md = mbx_open (curbb -> bb_file, bbrduid, bbrdgid, BBMODE)) == NOTOK) {
213         close (qd);
214         return RP_FOPEN;
215     }
216
217     if (rp_isbad (result = mbx_init ())) {
218         close (qd);
219         mbx_close (curbb -> bb_file, md);
220         return result;
221     }
222
223     pos = (long) lseek (md, (off_t)0, 1);
224     count = strlen (delim1);
225     if (write (md, delim1, count) != count) {
226         ll_log (logptr, LLOGTMP, "error writing delim1");
227         i = NOTOK;
228         goto clean_up;
229     }
230     start = (long) lseek (md, (off_t)0, 1);
231     size = 0;
232
233     count = strlen (bbrdheader);
234     if (write (md, bbrdheader, count) != count) {
235         ll_log (logptr, LLOGTMP, "error writing BBoard information");
236         i = NOTOK;
237         goto clean_up;
238     }
239     for (cp = bbrhdheader; *cp; cp++, size++)
240         if (*cp == '\n')
241             size++;
242
243 /* \f */
244
245     while ((i = read (qd, buffer, sizeof buffer)) > 0) {
246         for (offset = 0;
247                 (offset = strindex (delim1, buffer)) >= 0;
248                 buffer[offset]++)
249             continue;
250         for (offset = 0;
251                 (offset = strindex (delim2, buffer)) >= 0;
252                 buffer[offset]++)
253             continue;
254         if (write (md, buffer, i) != i) {
255             ll_log (logptr, LLOGTMP, "error writing to file '%s'",
256                     curbb -> bb_file);
257             i = NOTOK;
258             goto clean_up;
259         }
260         for (offset = 0, cp = buffer; offset < i; offset++, size++)
261             if (*cp++ == '\n')
262                 size++;
263     }
264
265     if (i < 0)
266         ll_log (logptr, LLOGTMP, "error reading from message file '%s'",
267                 qu_msgfile);
268 clean_up: ;
269     close (qd);
270
271     stop = (long) lseek (md, (off_t)0, 1);
272     count = strlen (delim2);
273     if (write (md, delim2, count) != count)
274         ll_log (logptr, LLOGTMP, "error writing delim2");
275     map_write (curbb -> bb_file, md, curbb -> bb_maxima, start, stop, pos,
276         size, 0);
277
278 #ifdef DEBUG
279     ll_log (logptr, LLOGGEN, "end local delivery...");
280 #endif
281
282     result = mbx_close (curbb -> bb_file, md);
283     return (i < 0 ? RP_FIO : result);
284 }
285
286 /* \f */
287
288 bb_txtcpy () {
289     short   result;
290
291 #ifdef  DEBUG
292     ll_log (logptr, LLOGBTR, "bb_txtcpy()");
293 #endif
294
295     if (curbb -> bb_dist == NULL
296             || *curbb -> bb_dist == NULL
297             || channelinfo[0] == NULL)
298         return RP_MOK;
299 #ifdef DEBUG
300     ll_log (logptr, LLOGGEN, "begin distribution...");
301 #endif
302     if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
303         printx ("\r\n");
304     printx("\rperforming remote distribution\n");
305
306     if (rp_isbad (result = dist_init ())
307             || rp_isbad (result = dist_adrs ())
308             || rp_isbad (result = dist_text ())
309             || rp_isbad (result = dist_end ()))
310         return dist_lose (result);
311
312 #ifdef DEBUG
313     ll_log (logptr, LLOGGEN, "end distribution...");
314 #endif
315     if (err_fd != NOTOK)
316         dist_lose (RP_MOK);
317     else
318         printx ("\rmessage distributed\n");
319
320     return RP_MOK;
321 }
322
323 /* \f */
324
325 /* dist_    BBoard distribution routines */
326
327 dist_init () {
328     short   result;
329
330 #ifdef DEBUG
331     ll_log (logptr, LLOGBTR, "dist_init()");
332 #endif
333
334     if (rp_isbad (result = mm_init ()))
335         return dist_log (result, LLOGFAT, "mm_init() failed [%s]",
336                 rp_valstr (result));
337     if (rp_isbad (result = mm_sbinit ()))
338         return dist_log (result, LLOGFAT, "mm_sbinit() failed [%s]",
339                 rp_valstr (result));
340     if (rp_isbad (result = mm_winit (chnlname, chnlinfo, bbrdaddr)))
341         return dist_log (result, LLOGFAT,
342                 "mm_winit('%s','%s','%s') failed [%s]",
343                 chnlname, chnlinfo, bbrdaddr, rp_valstr (result));
344
345     return result;
346 }
347
348 /* \f */
349
350 dist_adrs () {
351     short   result;
352
353 #ifdef DEBUG
354     ll_log (logptr, LLOGBTR, "dist_adrs()");
355 #endif
356
357     if (getbbdist (curbb, dist_address))
358         return dist_log (RP_NO, LLOGTMP, "getbbdist failed: %s", getbberr ());
359
360     if (rp_isbad (result = mm_waend ()))
361         return dist_log (result, LLOGFAT, "mm_waend() failed [%s]",
362                 rp_valstr (result));
363
364     return result;
365 }
366
367 /* \f */
368
369 dist_address (addr, host)
370 char *addr,
371      *host;
372 {
373     short   result,
374             len;
375     struct rp_bufstruct reply;
376
377 #ifdef DEBUG
378     ll_log (logptr, LLOGBTR, "dist_address(addr='%s',host='%s')", addr, host);
379 #endif
380
381     printx ("\rperforming distribution to %s@@%s...\n", addr, host);
382     if (rp_isbad (result = mm_wadr (host, addr))) {
383         dist_log (result, LLOGFAT, "mm_wadr('%s','%s') failed [%s]",
384                 host, addr, rp_valstr (result));
385         return NOTOK;
386     }
387     if (rp_isbad (result = mm_rrply (&reply, &len))) {
388         dist_log (result, LLOGFAT,
389                 "mm_rrply() failed [%s] getting status of '%s@@%s'",
390                 rp_valstr (result), addr, host);
391         return NOTOK;
392     }
393
394     switch (rp_gval (reply.rp_val)) {
395         case RP_AOK:
396 #ifdef DEBUG
397             ll_log (logptr, LLOGGEN, "address '%s@@%s' [%s] -- %s",
398                     addr, host, rp_valstr (reply.rp_val), reply.rp_line);
399 #endif
400             return OK;
401
402         case RP_NO:
403         case RP_USER:
404         case RP_NDEL:
405         case RP_AGN:
406         case RP_NOOP:
407             dist_log (reply.rp_val, LLOGTMP, "address '%s@@%s' [%s] -- %s",
408                     addr, host, rp_valstr (reply.rp_val), reply.rp_line);
409             return OK;          /* fail-soft */
410
411         default:
412             dist_log (reply.rp_val, LLOGFAT, "unexpected reply [%s] -- %s",
413                     rp_valstr (reply.rp_val), reply.rp_line);
414             return NOTOK;
415     }
416 }
417
418 /* \f */
419
420 dist_text () {
421     short   result;
422     int     i,
423             qd;
424     char    buffer[BUFSIZ];
425
426 #ifdef DEBUG
427     ll_log (logptr, LLOGBTR, "dist_text()");
428 #endif
429
430     qu_rtinit (0L);
431     if ((qd = dup (qu_fileno ())) == NOTOK)
432         return dist_log (RP_LIO, LLOGFAT, "unable to dup qu_fileno()");
433
434     while ((i = read (qd, buffer, sizeof buffer)) > 0)
435         if (rp_isbad (result = mm_wtxt (buffer, i)))
436             return dist_log (result, LLOGFAT, "mm_wtxt() failed [%s]",
437                     rp_valstr (result));
438
439     close (qd);
440     if (i < 0)
441         return dist_log (RP_FIO, LLOGTMP,
442                 "error reading from message file '%s'", qu_msgfile);
443
444     if (rp_isbad (result = mm_wtend ()))
445         return dist_log (result, LLOGFAT, "mm_wtend() failed [%s]",
446                 rp_valstr (result));
447
448     return result;
449 }
450
451 /* \f */
452
453 dist_end () {
454     short   result,
455             len;
456     struct rp_bufstruct reply;
457
458 #ifdef DEBUG
459     ll_log (logptr, LLOGBTR, "dist_end()");
460 #endif
461
462     if (rp_isbad (result = mm_rrply (&reply, &len)))
463         return dist_log (result, LLOGFAT,
464                 "mm_rrply() failed [%s] getting final status",
465                 rp_valstr (result));
466
467     switch (rp_gval (reply.rp_val)) {
468         case RP_OK:
469         case RP_MOK:
470 #ifdef DEBUG
471             ll_log (logptr, LLOGGEN, "message [%s] -- %s",
472                     rp_valstr (reply.rp_val), reply.rp_line);
473 #endif
474             mm_sbend ();
475             mm_end (OK);
476             return result;
477
478         case RP_NO:
479         case RP_NDEL:
480         case RP_AGN:
481         case RP_NOOP:
482             return dist_log (RP_NO, LLOGTMP, "not delivered [%s] -- %s",
483                     rp_valstr (reply.rp_val), reply.rp_line);
484
485         default:
486             return dist_log (RP_RPLY, LLOGFAT,
487                     "unexpected final reply [%s] -- %s",
488                     rp_valstr (reply.rp_val), reply.rp_line);
489     }
490 }
491
492 /* \f */
493
494 dist_lose (result)
495 short   result;
496 {
497     int     qd;
498     char    buffer[BUFSIZ];
499     FILE * qp;
500
501 #ifdef  DEBUG
502     ll_log (logptr, LLOGBTR, "dist_lose(result=0%o)", result);
503 #endif  DEBUG
504     mm_end (NOTOK);
505
506     printx ("\rerrors during distribution: ");
507     if (domsg)
508         fflush (stdout);
509     sprintf (buffer, "ch_bboards(%d) distribution for %s failed [%s]\n",
510             getpid (), curbb -> bb_name, rp_valstr (result));
511     if (ml_init (NO, NO, sitesignature, "Re-distribution Failure") != OK
512             || ml_adr (bbrdaddr) != OK
513             || ml_cc () != OK
514             || ml_adr (bbrdfrom) != OK
515             || ml_aend () != OK
516             || ml_tinit () != OK)
517         goto ml_err;
518     ml_txt (buffer);
519
520     if (err_fd != NOTOK) {
521         lseek (err_fd, (off_t)0, 0);
522         if ((qp = fdopen (err_fd, "r")) == NULL) {
523             ml_txt ("unable to fdopen() for diagnostic copy\n");
524             close (err_fd);
525         }
526         else {
527             ml_file (qp);
528             fclose (qp);
529         }
530         err_fd = NOTOK;
531     }
532
533     qu_rtinit (0L);
534     if ((qd = dup (qu_fileno ())) == NOTOK)
535         ml_txt ("unable to dup qu_fileno() for message copy\n");
536     else
537         if ((qp = fdopen (qd, "r")) == NULL) {
538             ml_txt ("unable to fdopen() for message copy\n");
539             close (qd);
540         }
541         else {
542             ml_txt ("\n  --Message Follows--\n");
543             ml_file (qp);
544             fclose (qp);
545         }
546
547     if (ml_end (OK) != OK) {
548         char   *cp;
549
550 ml_err: ;
551         if (cp = index (buffer, '\n'))
552             *cp = NULL;
553         printx ("unable to post advisory.\n");
554         ll_log (logptr, LLOGFAT, "unable to post failure notice");
555         ll_log (logptr, LLOGFAT, "info: %s", buffer);
556     }
557     else
558         printx ("advisory posted.\n");
559     if (domsg)
560         fflush (stdout);
561
562     return RP_MOK;
563 }
564
565 /* \f */
566
567 /* VARARGS3 */
568
569 dist_log (result, level, fmt, a, b, c, d, e)
570 short   result;
571 int     level;
572 char   *fmt,
573        *a,
574        *b,
575        *c,
576        *d,
577        *e;
578 {
579     int     i;
580     char    buffer[BUFSIZ],
581             tmpfil[BUFSIZ];
582
583     ll_log (logptr, level, fmt, a, b, c, d, e);
584
585     sprintf (buffer, fmt, a, b, c, d, e);
586     strcat (buffer, "\n");
587
588     printx ("\rerror: %s", buffer);
589
590     if (err_fd == NOTOK) {
591         unlink (mktemp (strcpy (tmpfil, "/tmp/bboardsXXXXXX")));
592         if ((err_fd = creat (tmpfil, 0600)) == NOTOK)
593             return result;
594         close (err_fd);
595         if ((err_fd = open (tmpfil, 2)) == NOTOK)
596             return result;
597         unlink (tmpfil);
598         lseek (err_fd, (off_t)0, 0);
599     }
600     i = strlen (buffer);
601     write (err_fd, buffer, i);
602
603     return result;
604 }
605
606 /* \f */
607
608 /* mbx_     local mailbox routines */
609
610 mbx_init () {
611     int     fd,
612             clear;
613     char    name[BUFSIZ];
614     FILE  *fp;
615
616 #ifdef DEBUG
617     ll_log (logptr, LLOGBTR, "mbx_init()");
618 #endif
619
620     if ((fd = mbx_Xopen (curbb -> bb_info, bbrduid, bbrdgid, BBMODE, &clear))
621             == NOTOK) {
622         if (errno == ETXTBSY) {
623             printx ("\runable to lock %s\n", curbb -> bb_info);
624             ll_err (logptr, LLOGTMP, "unable to lock %s",
625                     curbb -> bb_info);
626             return RP_LOCK;
627         }
628         printx ("\runable to open '%s'", curbb -> bb_info);
629         ll_log (logptr, LLOGTMP, "unable to open '%s'", curbb -> bb_info);
630         return RP_FOPN;
631     }
632     if ((fp = fdopen (fd, "w")) == (FILE *) NULL) {
633         printx ("\runable to fdopen '%s'", curbb -> bb_info);
634         ll_err (logptr, LLOGTMP, "unable to fdopen '%s'", curbb -> bb_info);
635         mbx_close (curbb -> bb_info, fd);
636         return RP_LIO;
637     }
638
639     strcpy (name, curbb -> bb_name);
640     if ((curbb = getbbnam (name)) == NULL) {
641         printx ("\runable to get information on BBoard %s\n", name);
642         ll_err (logptr, LLOGFAT, "unable to get info on %s", name);
643         lkfclose (fp, curbb -> bb_info);
644         return RP_LIO;
645     }
646
647     strcpy (bbrdtime, dtimenow ());
648     sprintf (bbrdheader, "BBoard-ID: %d\nBB-Posted: %s\n",
649             ++curbb -> bb_maxima, bbrdtime);
650
651     fprintf (fp, "%d\n%s\n", curbb -> bb_maxima, bbrdtime);
652     lkfclose (fp, curbb -> bb_info);
653
654     return RP_OK;
655 }
656 @
657
658
659 1.2
660 log
661 @off_t fixes for BSD44
662 @
663 text
664 @d2 3
665 @
666
667
668 1.1
669 log
670 @Initial revision
671 @
672 text
673 @d40 1
674 a40 1
675 long    lseek ();
676 d188 1
677 a188 1
678     pos = lseek (md, 0L, 1);
679 d195 1
680 a195 1
681     start = lseek (md, 0L, 1);
682 d236 1
683 a236 1
684     stop = lseek (md, 0L, 1);
685 d486 1
686 a486 1
687         lseek (err_fd, 0L, 0);
688 d563 1
689 a563 1
690         lseek (err_fd, 0L, 0);
691 @