Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / support / pop / mmdfII / pop / po_wtmail.c
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: po_wtmail.c,v 1.3 1993/08/25 17:43:26 jromine Exp $";
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 /* \f */
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 /* \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_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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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 /* \f */
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