]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/support/pop/RCS/popser.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / support / pop / RCS / popser.c,v
1 head 1.34;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.34
9 date 95.12.07.18.54.35; author jromine; state Exp;
10 branches;
11 next 1.33;
12
13 1.33
14 date 94.04.21.18.26.16; author jromine; state Exp;
15 branches;
16 next 1.32;
17
18 1.32
19 date 94.04.21.18.20.15; author jromine; state Exp;
20 branches;
21 next 1.31;
22
23 1.31
24 date 93.08.25.17.23.14; author jromine; state Exp;
25 branches;
26 next 1.30;
27
28 1.30
29 date 92.12.16.22.31.20; author jromine; state Exp;
30 branches;
31 next 1.29;
32
33 1.29
34 date 92.12.15.00.20.22; author jromine; state Exp;
35 branches;
36 next 1.28;
37
38 1.28
39 date 92.12.14.17.49.09; author jromine; state Exp;
40 branches;
41 next 1.27;
42
43 1.27
44 date 92.10.28.18.42.42; author jromine; state Exp;
45 branches;
46 next 1.26;
47
48 1.26
49 date 92.10.26.16.45.35; author jromine; state Exp;
50 branches;
51 next 1.25;
52
53 1.25
54 date 92.10.20.22.47.28; author jromine; state Exp;
55 branches;
56 next 1.24;
57
58 1.24
59 date 92.05.19.20.59.21; author jromine; state Exp;
60 branches;
61 next 1.23;
62
63 1.23
64 date 92.02.11.17.40.59; author jromine; state Exp;
65 branches;
66 next 1.22;
67
68 1.22
69 date 92.02.10.22.35.58; author jromine; state Exp;
70 branches;
71 next 1.21;
72
73 1.21
74 date 92.02.04.21.59.41; author jromine; state Exp;
75 branches;
76 next 1.20;
77
78 1.20
79 date 92.02.04.21.44.56; author jromine; state Exp;
80 branches;
81 next 1.19;
82
83 1.19
84 date 92.02.04.21.39.42; author jromine; state Exp;
85 branches;
86 next 1.18;
87
88 1.18
89 date 92.02.03.17.52.59; author jromine; state Exp;
90 branches;
91 next 1.17;
92
93 1.17
94 date 92.01.31.22.06.03; author jromine; state Exp;
95 branches;
96 next 1.16;
97
98 1.16
99 date 90.11.16.14.56.38; author mh; state Exp;
100 branches;
101 next 1.15;
102
103 1.15
104 date 90.11.16.14.38.00; author mh; state Exp;
105 branches;
106 next 1.14;
107
108 1.14
109 date 90.11.05.16.04.57; author mh; state Exp;
110 branches;
111 next 1.13;
112
113 1.13
114 date 90.04.09.09.45.18; author sources; state Exp;
115 branches;
116 next 1.12;
117
118 1.12
119 date 90.04.05.16.07.32; author sources; state Exp;
120 branches;
121 next 1.11;
122
123 1.11
124 date 90.04.05.16.07.03; author sources; state Exp;
125 branches;
126 next 1.10;
127
128 1.10
129 date 90.04.05.15.34.40; author sources; state Exp;
130 branches;
131 next 1.9;
132
133 1.9
134 date 90.04.05.14.54.01; author sources; state Exp;
135 branches;
136 next 1.8;
137
138 1.8
139 date 90.03.20.11.15.44; author sources; state Exp;
140 branches;
141 next 1.7;
142
143 1.7
144 date 90.02.23.14.49.38; author sources; state Exp;
145 branches;
146 next 1.6;
147
148 1.6
149 date 90.02.06.13.13.55; author sources; state Exp;
150 branches;
151 next 1.5;
152
153 1.5
154 date 90.02.05.15.04.53; author sources; state Exp;
155 branches;
156 next 1.4;
157
158 1.4
159 date 90.02.05.14.16.51; author sources; state Exp;
160 branches;
161 next 1.3;
162
163 1.3
164 date 90.02.05.14.08.18; author sources; state Exp;
165 branches;
166 next 1.2;
167
168 1.2
169 date 90.02.05.13.58.53; author sources; state Exp;
170 branches;
171 next 1.1;
172
173 1.1
174 date 90.02.05.13.58.34; author sources; state Exp;
175 branches;
176 next ;
177
178
179 desc
180 @@
181
182
183 1.34
184 log
185 @include prototype for truncate() - 64biyt
186 @
187 text
188 @/* popser.c - the POP service */
189 #ifndef lint
190 static char ident[]="@@(#)$Id: popser.c,v 1.33 1994/04/21 18:26:16 jromine Exp jromine $";
191 #endif
192
193 #include "../h/mh.h"
194 #include "../h/dropsbr.h"
195 #ifdef MPOP
196 #ifdef BPOP
197 #include "../h/formatsbr.h"
198 #include "../h/scansbr.h"
199 #endif
200 #endif /* MPOP */
201 #include "../zotnet/bboards.h"
202 #include <stdio.h>
203 #include "../zotnet/mts.h"
204 #include <ctype.h>
205 #include <errno.h>
206 #include <pwd.h>
207 #include <signal.h>
208 #include "syslog.h"
209 #include <sys/types.h>
210 #include <sys/stat.h>
211 #ifdef UNISTD
212 #include <unistd.h>
213 #endif
214 #ifdef KPOP
215 #include <krb.h>
216 #endif /* KPOP */
217 #ifdef SYS5
218 #include <fcntl.h>
219 #endif /* SYS5 */
220 #ifdef SHADOW
221 #include <shadow.h>
222 #endif /* SHADOW */
223
224
225 #define TRUE 1
226 #define FALSE 0
227
228 #define NVEC 5
229
230 #ifndef POPSERVICE
231 #define POPSERVICE "pop"
232 #endif
233
234 /* \f */
235
236 extern int errno;
237
238 extern int debug;
239 extern char myhost[];
240 extern char *myname;
241
242 #ifndef POP2
243 static enum state {
244 auth1, auth2, trans, update, halt, error
245 } mystate;
246 #else
247 static enum state {
248 auth1, auth2, trans, mbox, item, ack, update, halt, error
249 } mystate;
250 #endif
251
252
253 static int user (), pass ();
254 #ifdef BPOP
255 static isguest(), getbbmax();
256 #ifndef MPOP
257 static int xtnd1(), xtnd2();
258 #else
259 static int xtnd1(), xtnd2(), xtnd3 ();
260 #endif /* MPOP */
261 #endif /* BPOP */
262 #ifdef RPOP
263 static int rpop ();
264 #endif /* RPOP */
265 #ifdef APOP
266 static int apop ();
267 #endif
268 static int status (), list (), retrieve (), delete (), reset ();
269 static int top (), last ();
270 #ifdef BPOP
271 static int xtnd ();
272 #endif /* BPOP */
273 static int quit ();
274 #ifdef POP2
275 static int helo (), rdp2 (), acks (), ack2 (), fold (), nack ();
276 #endif /* POP2 */
277
278 static struct vector {
279 char *v_cmd;
280 int v_min, v_max;
281 int (*v_vec) ();
282 enum state v_valid;
283 enum state v_win, v_lose;
284 } vectors[] = {
285 "user", 1, 1, user, auth1, auth2, auth1,
286 "pass", 1, 1, pass, auth2, trans, auth1,
287 #ifdef RPOP
288 "rpop", 1, 1, rpop, auth2, trans, auth1,
289 #endif /* RPOP */
290 #ifdef APOP
291 "apop", 2, 2, apop, auth1, trans, auth1,
292 #endif
293 "quit", 0, 0, NULL, auth1, halt, halt,
294 "quit", 0, 0, NULL, auth2, halt, halt,
295
296 "stat", 0, 0, status, trans, trans, trans,
297 "list", 0, 1, list, trans, trans, trans,
298 "retr", 1, 1, retrieve, trans, trans, trans,
299 "dele", 1, 1, delete, trans, trans, trans,
300 "noop", 0, 0, NULL, trans, trans, trans,
301 "rset", 0, 0, reset, trans, trans, trans,
302
303 "top", 2, 2, top, trans, trans, trans,
304 "last", 0, 0, last, trans, trans, trans,
305 #ifdef BPOP
306 #ifndef MPOP
307 "xtnd", 1, 2, xtnd, trans, trans, trans,
308 #else
309 "xtnd", 1, 3, xtnd, trans, trans, trans,
310 #endif /* MPOP */
311 #endif /* BPOP */
312 "quit", 0, 0, quit, trans, halt, halt,
313
314 #ifdef POP2
315 "helo", 2, 2, helo, auth1, mbox, auth1,
316
317 "fold", 1, 1, fold, mbox, mbox, mbox,
318 "quit", 0, 0, quit, mbox, halt, halt,
319 "read", 0, 1, rdp2, mbox, item, error,
320
321 "fold", 1, 1, fold, item, mbox, mbox,
322 "read", 0, 1, rdp2, item, item, error,
323 "quit", 0, 0, quit, item, halt, halt,
324 "retr", 0, 0, retrieve, item, ack, error,
325
326 "acks", 0, 0, ack2, ack, item, error,
327 "ackd", 0, 0, ack2, ack, item, error,
328 "nack", 0, 0, rdp2, ack, item, error,
329 "quit", 0, 0, NULL, ack, halt, halt,
330
331 #endif /* POP2 */
332 NULL
333 };
334
335 static struct vector *getvector ();
336
337 /* \f */
338
339 #ifdef POP2
340 static int pop2 = NOTOK; /* current pop2 msg, or NOTOK if pop3 */
341 #endif /* POP2 */
342 #ifdef DPOP
343 static int pop_uid;
344 static int pop_gid;
345 #endif /* DPOP */
346
347 static int rproto;
348 static char *hostname;
349 static char server[BUFSIZ];
350 static char timestamp[BUFSIZ];
351
352 static char username[BUFSIZ];
353
354 static char maildrop[BUFSIZ];
355 static int mode;
356 static time_t mtime;
357 static FILE *dp;
358
359 static long lastseen;
360 static int rmsgs;
361
362 #ifdef BPOP
363 static int xtnded;
364
365 static int guest_uid;
366 static int guest_gid;
367
368 static struct bboard *BBhead = NULL;
369 static struct bboard *BBtail = NULL;
370
371 static long BBtime = 0L;
372
373 static struct bboard *getbbaux ();
374 #endif /* BPOP */
375
376
377 struct Msg { /* Msgs[0] contains info for entire maildrop */
378 struct drop m_drop;
379 #define m_id m_drop.d_id
380 #define m_size m_drop.d_size
381 #define m_last m_drop.d_start /* Msgs[i = 0] */
382 #define m_start m_drop.d_start /* Msgs[i > 0] */
383 #define m_stop m_drop.d_stop
384
385 unsigned m_flags;
386 #define MNULL 0x00
387 #define MDELE 0x01
388 #define MREAD 0x02
389 };
390
391 static int nMsgs = 0;
392 static struct Msg *Msgs = NULL;
393
394 static int nmsgs;
395 static int dmsgs;
396 #ifdef MPOP
397 #ifdef BPOP
398 static int _sc_width = 0;
399 static char *nfs = NULL;
400 #endif
401 #endif /* MPOP */
402
403
404 #define TRM "."
405 #define TRMLEN (sizeof TRM - 1)
406 #define IAC 255
407
408 static TYPESIG pipeser ();
409
410 FILE *input;
411 FILE *output;
412
413 #ifndef __STDC__
414 #ifdef SYS5
415 struct passwd *getpwnam();
416 #endif
417 #endif
418
419 void padvise (), padios ();
420 char *crypt ();
421
422 #ifdef POPUUMBOX
423 #define MBX_READ pmbx_read
424 static int pmbx_read ();
425 static char *p_copy(), *p_copyin(), *p_nextword();
426 static p_cmatch(), p_isdate(), p_ishead(), p_parse(), any();
427 #else
428 #define MBX_READ mbx_read
429 #endif
430 extern int mbx_read ();
431
432 static int setup(), setupaux(), read_map(), read_file(), pmbx_size();
433 static int quitaux(), quitfile(), respond(), getline();
434 static m_gMsgs(), multiline(), multiend(), putline();
435 /* \f */
436
437 popinit () {
438 #ifdef BPOP
439 padvise (NULLCP, LOG_INFO, "initialize list of BBoards");
440
441 BBhead = BBtail = NULL;
442 while (getbbaux (NULLCP))
443 continue;
444 #endif /* BPOP */
445 }
446
447 popassert () {
448 #ifdef BPOP
449 register char **p;
450 register struct bboard *bb,
451 *bp;
452
453 if (BBtime == getbbtime ())
454 return;
455
456 padvise (NULLCP, LOG_INFO, "list of BBoards has changed");
457
458 for (bb = BBhead; bb; bb = bp) {
459 bp = bb -> bb_next;
460
461 if (bb -> bb_name)
462 free (bb -> bb_name);
463 if (bb -> bb_file)
464 free (bb -> bb_file);
465 if (bb -> bb_archive)
466 free (bb -> bb_archive);
467 if (bb -> bb_info)
468 free (bb -> bb_info);
469 if (bb -> bb_map)
470 free (bb -> bb_map);
471 if (bb -> bb_passwd)
472 free (bb -> bb_passwd);
473 if (bb -> bb_date)
474 free (bb -> bb_date);
475 if (bb -> bb_addr)
476 free (bb -> bb_addr);
477 if (bb -> bb_request)
478 free (bb -> bb_request);
479 if (bb -> bb_relay)
480 free (bb -> bb_relay);
481
482 for (p = bb -> bb_aka; *p; p++)
483 free (*p);
484 free ((char *) bb -> bb_aka);
485
486 for (p = bb -> bb_leader; *p; p++)
487 free (*p);
488 free ((char *) bb -> bb_leader);
489
490 for (p = bb -> bb_dist; *p; p++)
491 free (*p);
492 free ((char *) bb -> bb_dist);
493
494 free ((char *) bb);
495 }
496
497 BBhead = BBtail = NULL;
498 while (getbbaux (NULLCP))
499 continue;
500 #endif /* BPOP */
501 }
502
503 /* \f */
504
505 #ifdef KPOP
506 static char *kusername;
507
508 kpop (in, out, principal, rhost, auth)
509 int in,
510 out;
511 char *principal, *rhost;
512 int auth;
513 #else /* KPOP */
514 pop (in, out, priv, rhost)
515 int in,
516 out,
517 priv;
518 char *rhost;
519 #endif /* KPOP */
520 {
521 char buffer[BUFSIZ],
522 *vec[NVEC + 1];
523 #if defined (DPOP) || defined (BPOP)
524 register struct passwd *pw;
525 #endif /* defined (DPOP) || defined (BPOP) */
526 register struct vector *v;
527
528 m_foil (NULLCP);
529 mts_init (myname);
530
531 hostname = rhost;
532 #ifdef KPOP
533 rproto = 1;
534 (void) sprintf (server, "%s KPOP server", myhost);
535 #else
536 rproto = priv;
537 (void) sprintf (server, "%s server", priv ? "RPOP" : "POP");
538 #endif /* KPOP */
539
540 if ((input = fdopen (in, "r")) == NULL
541 || (output = fdopen (out, "w")) == NULL) {/* you lose big */
542 (void) respond (NOTOK, "%s loses on initialization", server);
543 return;
544 }
545 (void) signal (SIGPIPE, pipeser);
546 #ifdef KPOP
547 if (principal == NULLCP) {
548 char buf[512];
549 strcpy(buf, "Authentication failed: ");
550 strcat(buf, krb_err_txt[auth]);
551 (void) respond (NOTOK, buf);
552 return;
553 }
554 kusername = principal;
555 #endif /* KPOP */
556
557 #ifdef DPOP
558 if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1)) {
559 (void) respond (NOTOK, "%s loses on DB initialization -- %s",
560 server, pw ? getbberr () : "POP user-id unknown");
561 return;
562 }
563 pop_uid = pw -> pw_uid;
564 pop_gid = pw -> pw_gid;
565 #endif /* DPOP */
566 #ifdef BPOP
567 if ((pw = getpwnam (popbbuser)) && pw -> pw_uid) {
568 guest_uid = pw -> pw_uid;
569 guest_gid = pw -> pw_gid;
570 }
571 else
572 guest_uid = guest_gid = 0;
573 #endif /* BPOP */
574
575 {
576 long clock;
577
578 (void) time (&clock);
579 (void) sprintf (timestamp, "<%d.%ld@@%s>", getpid (), clock, myhost);
580 }
581 (void) respond (OK, "%s ready %s", server, timestamp);
582
583 for (mystate = auth1; mystate != halt && mystate != error;)
584 switch (getline (buffer, sizeof buffer, input)) {
585 case OK:
586 if ((v = getvector (buffer, vec)) == NULL)
587 continue;
588 mystate = (v -> v_vec ? (v -> v_vec) (vec)
589 : respond (OK, NULLCP)) == OK
590 ? v -> v_win
591 : v -> v_lose;
592 break;
593
594 case NOTOK:
595 case DONE:
596 mystate = error;
597 (void) respond (NOTOK, "%s signing off", server);
598 break;
599 }
600 }
601
602 /* \f */
603 #ifdef POP2
604 static int helo (vec) /* sort of "user" and "pass" */
605 register char **vec;
606 {
607 pop2 = 0; /* now we're talkin' pop2! */
608 make_lower (username, vec[1]); /* helo user pass */
609 return pass (++vec); /* user pass */
610 }
611 #endif
612
613 static int user (vec)
614 register char **vec;
615 {
616 make_lower (username, vec[1]);
617 #ifdef KPOP
618 if (!strcmp(username, kusername))
619 return respond (OK, "Kerberos authentication succeeded. Send username as password (%s)", username);
620 else {
621 respond (NOTOK, "Wrong username supplied (%s vs. %s)",
622 kusername, username);
623 return (NOTOK);
624 }
625 #else
626 return respond (OK, "password required for %s", username);
627 #endif
628 }
629
630 /* \f */
631
632 static int pass (vec)
633 register char **vec;
634 {
635 int guest = 0;
636 #ifndef DPOP
637 register struct passwd *pw;
638 #ifdef SHADOW
639 register struct spwd *shpw;
640 #endif /* SHADOW */
641 #else /* DPOP */
642 register struct bboard *pw;
643 #endif /* DPOP */
644
645 #ifdef KPOP
646 #ifndef DPOP
647 if ((pw = getpwnam (username)) != NULL)
648 return setup(pw, FALSE);
649 else
650 return respond (NOTOK, "no local password entry");
651 #else
652 {
653 static struct bboard entry;
654 static char entry_file[BUFSIZ] = "/usr/spool/pop";
655
656 pw = &entry;
657 pw->bb_name = username;
658 strcat(entry_file, username);
659 pw->bb_file = entry_file;
660 return setup(pw, FALSE);
661 }
662 #endif
663 #else /* KPOP */
664
665 #ifndef DPOP
666 #ifdef BPOP
667 if (isguest ()) {
668 #ifdef TRUSTED
669 static passwd gw;
670
671 gw.pw_name = popbbuser;
672 gw.pw_uid = guest_uid;
673 pw = &gw;
674 #endif /* TRUSTED */
675 guest = 1;
676 goto anonymous;
677 }
678 #endif /* BPOP */
679 if ((pw = getpwnam (username)) == NULL
680 #ifndef SHADOW
681 || *pw -> pw_passwd == NULL
682 || strcmp (crypt (vec[1], pw -> pw_passwd), pw -> pw_passwd)) {
683 #else /* SHADOW */
684 || (shpw = getspnam (username)) == NULL
685 || *shpw -> sp_pwdp == NULL
686 || strcmp (crypt (vec[1], shpw -> sp_pwdp), shpw -> sp_pwdp)) {
687 #endif /* SHADOW */
688 #ifdef TRUSTED
689 trusted (0, hostname, NULLCP, 0, pw ? pw -> pw_name : username,
690 pw && pw -> pw_uid == 0, POPSERVICE, "tcp", NULL);
691 #endif /* TRUSTED */
692 return respond (NOTOK, "login incorrect");
693 }
694 #else /* DPOP */
695 #ifdef BPOP
696 if (isguest ()) {
697 static struct bboard gw;
698
699 gw.bb_name = popbbuser;
700 pw = &gw;
701 guest = 1;
702 goto anonymous;
703 }
704 #endif /* BPOP */
705 if (((pw = getbbnam (username)) == NULL
706 && (pw = getbbaka (username)) == NULL)
707 || *pw -> bb_passwd == NULL
708 || strcmp (crypt (vec[1], pw -> bb_passwd), pw -> bb_passwd)) {
709 #ifdef TRUSTED
710 trusted (0, hostname, NULLCP, 0, pw ? pw -> bb_name : username,
711 0, POPSERVICE, "tcp", NULL);
712 #endif /* TRUSTED */
713 return respond (NOTOK, "login incorrect");
714 }
715 #endif /* DPOP */
716
717 #ifdef BPOP
718 anonymous: ;
719 #endif /* BPOP */
720 #ifdef TRUSTED
721 if (trusted (1, hostname, NULLCP, 0, myhost,
722 #ifndef DPOP
723 pw -> pw_name, pw -> pw_uid == 0,
724 #else /* DPOP */
725 pw -> bb_name, 0,
726 #endif /* DPOP */
727 POPSERVICE, "tcp", NULL)
728 == 0)
729 return respond (NOTOK, "permission denied");
730 #endif /* TRUSTED */
731 return setup (pw, guest);
732 #endif /* KPOP */
733 }
734
735 /* \f */
736
737 #ifdef BPOP
738 static isguest () {
739 int i;
740 register char *cp;
741 char buffer[BUFSIZ];
742 register FILE *fp;
743
744 if (strcmp (username, popbbuser) || !guest_uid)
745 return FALSE;
746 if (popbblist == NULL || (fp = fopen (popbblist, "r")) == NULL)
747 return TRUE;
748
749 i = FALSE;
750 if (hostname)
751 while (fgets (buffer, sizeof buffer, fp)) {
752 if (cp = index (buffer, '\n'))
753 *cp = NULL;
754 if (strcmp (buffer, hostname) == 0) {
755 i = TRUE;
756 break;
757 }
758 }
759
760 (void) fclose (fp);
761
762 return i;
763 }
764 #endif /* BPOP */
765
766 /* \f */
767
768 #ifdef RPOP
769 static int rpop (vec)
770 register char **vec;
771 {
772 #ifndef DPOP
773 register struct passwd *pw;
774 #else /* DPOP */
775 register int hostok = 0;
776 register char *bp,
777 *cp;
778 char buffer[BUFSIZ];
779 register struct bboard *pw;
780 #endif /* DPOP */
781
782 #ifndef DPOP
783 if (!rproto || (pw = getpwnam (username)) == NULL) {
784 #ifdef TRUSTED
785 trusted (0, hostname, vec[1], 0, username, 0, "rpop", "tcp",
786 NULL);
787 #endif /* TRUSTED */
788 return respond (NOTOK, "login incorrect");
789 }
790 if (chdir (pw -> pw_dir) == NOTOK && chdir ("/") == NOTOK)
791 return respond (NOTOK, "no remote directory");
792 if (ruserok (hostname, pw -> pw_uid == 0, vec[1], username) == NOTOK) {
793 #ifdef TRUSTED
794 trusted (0, hostname, vec[1], 0, pw -> pw_name,
795 pw -> pw_uid == 0, "rpop", "tcp", NULL);
796 #endif /* TRUSTED */
797 return respond (NOTOK, "permission denied");
798 }
799 #else /* DPOP */
800 if (!rproto
801 || ((pw = getbbnam (username)) == NULL
802 && (pw = getbbaka (username)) == NULL)) {
803 #ifdef TRUSTED
804 trusted (0, hostname, vec[1], 0, username, 0, "rpop", "tcp",
805 NULL);
806 #endif /* TRUSTED */
807 return respond (NOTOK, "login incorrect");
808 }
809 /*
810 * hacked by Dave Cohrs Tue Feb 4 14:12:15 CST 1986
811 * to allow the hostname to be a list: user@@host1,user@@host2
812 * NOTE: the separator must be a comma -- no spaces are allowed
813 */
814 (void) sprintf (buffer, "%s@@%s", vec[1], hostname);
815 for (bp = pw -> bb_addr; bp; bp = cp) {
816 if ((cp = index (bp, ',')))
817 *cp = 0;
818 hostok = uleq (bp, buffer);
819 if (cp)
820 *cp++ = ',';
821 if (hostok)
822 break;
823 }
824 if (!hostok) {
825 #ifdef TRUSTED
826 trusted (0, hostname, vec[1], 0, pw -> bb_name, 0, "rpop",
827 "tcp", NULL);
828 #endif /* TRUSTED */
829 return respond (NOTOK, "permission denied");
830 }
831 #endif /* DPOP */
832
833 #ifdef TRUSTED
834 if (trusted (1, hostname, vec[1], 0, username,
835 #ifndef DPOP
836 pw -> pw_uid == 0,
837 #else /* DPOP */
838 0,
839 #endif /* DPOP */
840 "rpop", "tcp", NULL)
841 == 0)
842 return respond (NOTOK, "permission denied");
843 #endif /* TRUSTED */
844 return setup (pw, FALSE);
845 }
846 #endif /* RPOP */
847
848 /* \f */
849
850 #ifdef APOP
851 #include "popauth.h"
852 #include "../../uip/md5.c"
853 #include <ndbm.h>
854 #include <sys/file.h>
855 #ifdef SYS5
856 #include <fcntl.h>
857 #endif
858
859
860 static int apop (vec)
861 register char **vec;
862 {
863 register char *cp;
864 char buffer[BUFSIZ];
865 register unsigned char *dp;
866 unsigned char *ep,
867 digest[16];
868 #ifndef DPOP
869 register struct passwd *pw;
870 #else
871 register struct bboard *pw;
872 #endif
873 struct stat st;
874 datum key,
875 value;
876 DBM *db;
877 MD5_CTX mdContext;
878 struct authinfo auth;
879
880 (void) strcpy (username, vec[1]);
881
882 #ifndef DPOP
883 if ((pw = getpwnam (username)) == NULL
884 || *pw -> pw_passwd == NULL) {
885 return respond (NOTOK, "user invalid");
886 }
887 #else
888 if (((pw = getbbnam (username)) == NULL
889 && (pw = getbbaka (username)) == NULL)
890 || *pw -> bb_passwd == NULL) {
891 return respond (NOTOK, "subscriber invalid");
892 }
893 #endif
894
895 if ((db = dbm_open (APOP, O_RDONLY, 0)) == NULL)
896 return respond (NOTOK, "POP authorization DB not available (%d)",
897 errno);
898 if (fstat (dbm_pagfno (db), &st) != NOTOK
899 && (st.st_mode & 0777) != 0600) {
900 dbm_close (db);
901 return respond (NOTOK, "POP authorization DB has wrong mode (0%o)",
902 st.st_mode & 0777);
903 }
904 if (flock (dbm_pagfno (db), LOCK_SH) == NOTOK) {
905 dbm_close (db);
906 return respond (NOTOK, "unable to lock POP authorization DB (%d)",
907 errno);
908 }
909 key.dsize = strlen (key.dptr = vec[1]) + 1;
910 value = dbm_fetch (db, key);
911 if (value.dptr == NULL) {
912 dbm_close (db);
913 return respond (NOTOK, "not authorized");
914 }
915 bcopy (value.dptr, (char *) &auth, sizeof auth);
916 (void) sprintf (cp = buffer, "%s%*.*s", timestamp, auth.auth_secretlen,
917 auth.auth_secretlen, auth.auth_secret);
918
919 dbm_close (db);
920
921 MD5Init (&mdContext);
922 MD5Update (&mdContext, (unsigned char *) buffer,
923 (unsigned int) (strlen (timestamp) + auth.auth_secretlen));
924 MD5Final (digest, &mdContext);
925
926 cp = buffer;
927 for (ep = (dp = digest) + sizeof digest / sizeof digest[0];
928 dp < ep;
929 cp += 2)
930 (void) sprintf (cp, "%02x", *dp++ & 0xff);
931 *cp = NULL;
932
933 if (strcmp (vec[2], buffer))
934 return respond (NOTOK, "authentication failure");
935
936 return setup (pw, 0);
937 }
938 #endif
939
940 /* \f */
941
942 static int setup (pw, guest)
943 #ifndef DPOP
944 register struct passwd *pw;
945 #else /* DPOP */
946 register struct bboard *pw;
947 #endif /* DPOP */
948 int guest;
949 {
950 #ifdef BPOP
951 if (guest) {
952 (void) setgid (guest_gid);
953 #ifndef SYS5
954 (void) initgroups (popbbuser, guest_gid);
955 #endif /* SYS5 */
956 (void) setuid (guest_uid);
957 }
958 else {
959 #endif /* BPOP */
960 #ifndef DPOP
961 (void) setgid (pw -> pw_gid);
962 #ifndef SYS5
963 (void) initgroups (pw -> pw_name, pw -> pw_gid);
964 #endif /* SYS5 */
965 (void) setuid (pw -> pw_uid);
966 #else /* DPOP */
967 (void) setgid (pop_gid);
968 #ifndef SYS5
969 (void) initgroups (POPUID, pop_gid);
970 #endif /* SYS5 */
971 (void) setuid (pop_uid);
972 #endif /* DPOP */
973 #ifdef BPOP
974 }
975 #endif /* BPOP */
976
977 #ifndef DPOP
978 (void) sprintf (maildrop, "%s/%s",
979 mmdfldir && *mmdfldir ? mmdfldir : pw -> pw_dir,
980 mmdflfil && *mmdflfil ? mmdflfil : pw -> pw_name);
981 #else /* DPOP */
982 (void) strcpy (maildrop, pw -> bb_file);
983 #endif /* DPOP */
984
985 if (setupaux (guest) == NOTOK)
986 return NOTOK;
987
988 #ifdef POP2
989 if (pop2 != NOTOK) { /* in response to pop2 "helo" */
990 pop2 = nmsgs > 0 ? 1 : 0;
991 return respond ('#', "%d message%s (%d octets)",
992 nmsgs, nmsgs != 1 ? "s" : "", Msgs[0].m_size);
993 }
994 else
995 #endif /* POP2 */
996 return respond (OK,
997 nmsgs ? "maildrop has %d message%s (%d octets)" : "maildrop empty",
998 nmsgs, nmsgs != 1 ? "s" : "", Msgs[0].m_size);
999 }
1000
1001 /* \f */
1002
1003 static int setupaux (readonly)
1004 int readonly;
1005 {
1006 register int i,
1007 msgp;
1008 struct stat st;
1009
1010 #ifdef BPOP
1011 xtnded = 0;
1012 #endif /* BPOP */
1013 if ((dp = readonly ? fopen (maildrop, "r") : lkfopen (maildrop, "r"))
1014 == NULL)
1015 switch (errno) {
1016 case ENOENT:
1017 m_gMsgs (msgp = 0);
1018 goto no_mail;
1019
1020 default:
1021 nmsgs = dmsgs = 0;
1022 return respond (NOTOK, "unable to %s maildrop: \"%s\"",
1023 readonly ? "read" : "lock", maildrop);
1024 }
1025
1026 if (fstat (fileno (dp), &st) != NOTOK) {
1027 mode = (int) (st.st_mode & 0777), mtime = st.st_mtime;
1028 msgp = read_map (maildrop, (long) st.st_size);
1029 }
1030 else {
1031 mode = 0600, mtime = 0;
1032 msgp = 0;
1033 }
1034
1035 if ((msgp = read_file (msgp ? Msgs[msgp].m_stop : 0L, msgp + 1)) < 1)
1036 m_gMsgs (0);
1037
1038 no_mail: ;
1039 lastseen = Msgs[0].m_last;
1040 if(debug)padvise(NULLCP,LOG_DEBUG,"XXX: lastseen=%d",lastseen);
1041 dmsgs = rmsgs = 0;
1042 nmsgs = msgp;
1043
1044 Msgs[0].m_flags = readonly ? MREAD : MNULL;
1045 Msgs[0].m_size = 0;
1046 for (i = 1; i <= nmsgs; i++) {
1047 if (Msgs[i].m_size == 0)
1048 Msgs[i].m_size = pmbx_size (i);
1049 Msgs[0].m_size += Msgs[i].m_size;
1050 Msgs[i].m_flags = MNULL;
1051 }
1052
1053 return OK;
1054 }
1055
1056 /* \f */
1057
1058 static int read_map (file, pos)
1059 char *file;
1060 long pos;
1061 {
1062 register int i,
1063 msgp;
1064 register struct drop *pp,
1065 *mp;
1066 struct drop *rp;
1067
1068 if (debug)
1069 padvise (NULLCP, LOG_DEBUG, "read_map (%s, %ld)", file, pos);
1070
1071 if ((i = map_read (file, pos, &rp, debug)) == 0)
1072 return 0;
1073
1074 m_gMsgs (i);
1075
1076 Msgs[0].m_last = rp -> d_start;
1077
1078 msgp = 1;
1079 for (pp = rp + 1; i-- > 0; msgp++, pp++) {
1080 mp = &Msgs[msgp].m_drop;
1081 mp -> d_id = pp -> d_id;
1082 mp -> d_size = pp -> d_size;
1083 mp -> d_start = pp -> d_start;
1084 mp -> d_stop = pp -> d_stop;
1085 }
1086 free ((char *) rp);
1087
1088 if (Msgs[0].m_last > msgp) {
1089 if (debug)
1090 padvise (NULLCP, LOG_DEBUG, "lastseen adjusted from %d to %d",
1091 Msgs[0].m_last, msgp);
1092 Msgs[0].m_last = msgp;
1093 }
1094
1095 return (msgp - 1);
1096 }
1097
1098 /* \f */
1099
1100 static int read_file (pos, msgp)
1101 register long pos;
1102 register int msgp;
1103 {
1104 register int i;
1105 register struct drop *pp,
1106 *mp;
1107 struct drop *rp;
1108
1109 if (debug)
1110 padvise (NULLCP, LOG_DEBUG, "read_file (%ld, %d)",
1111 pos, msgp);
1112
1113 if ((i = MBX_READ (dp, pos, &rp, debug)) <= 0)
1114 return (msgp - 1);
1115
1116 m_gMsgs ((msgp - 1) + i);
1117
1118 for (pp = rp; i-- > 0; msgp++, pp++) {
1119 mp = &Msgs[msgp].m_drop;
1120 mp -> d_id = 0;
1121 mp -> d_size = pp -> d_size;
1122 mp -> d_start = pp -> d_start;
1123 mp -> d_stop = pp -> d_stop;
1124 }
1125 free ((char *) rp);
1126
1127 return (msgp - 1);
1128 }
1129
1130 /* \f */
1131
1132 static m_gMsgs (n)
1133 int n;
1134 {
1135 if (debug)
1136 padvise (NULLCP, LOG_DEBUG, "m_gMsgs (%d) 0x%x %d",
1137 n, Msgs, nMsgs);
1138
1139 if (Msgs == NULL) {
1140 nMsgs = n + MAXFOLDER / 2;
1141 Msgs = (struct Msg *) calloc ((unsigned) (nMsgs + 2), sizeof *Msgs);
1142 if (Msgs == NULL)
1143 padios (NULLCP, "unable to allocate Msgs structure");
1144 return;
1145 }
1146
1147 if (nMsgs >= n)
1148 return;
1149
1150 nMsgs = n + MAXFOLDER / 2;
1151 Msgs = (struct Msg *) realloc ((char *) Msgs,
1152 (unsigned) (nMsgs + 2) * sizeof *Msgs);
1153 if (Msgs == NULL)
1154 padios (NULLCP, "unable to reallocate Msgs structure");
1155 }
1156
1157 /* \f */
1158
1159 static int pmbx_size (m)
1160 register int m;
1161 {
1162 register int i;
1163 register long pos;
1164
1165 (void) fseek (dp, Msgs[m].m_start, 0);
1166 for (i = 0, pos = Msgs[m].m_stop - Msgs[m].m_start; pos > 0; i++, pos--)
1167 if (fgetc (dp) == '\n')
1168 i++;
1169
1170 return i;
1171 }
1172
1173 /* \f */
1174
1175 /* ARGSUSED */
1176
1177 static int status (vec)
1178 char **vec;
1179 {
1180 return respond (OK, "%d %d", nmsgs - dmsgs, Msgs[0].m_size);
1181 }
1182
1183
1184 #ifdef POP2
1185 static int rdp2 (vec) /* always returns OK */
1186 char **vec;
1187 {
1188 if (vec[1]) {
1189 if ((pop2 = atoi (vec[1])) <= 0)
1190 pop2 = 0;
1191 }
1192 else if (pop2 == 0)
1193 return NOTOK; /* close 'em down */
1194
1195 if (pop2 <= 0 || pop2 > nmsgs) {
1196 pop2 = 0;
1197 return respond ('=', "0 no message");
1198 }
1199 if (Msgs[pop2].m_flags & MDELE) {
1200 pop2 = 0;
1201 return respond ('=', "0 message %d is deleted", pop2);
1202 }
1203
1204 return respond ('=', "%d (message %d)", Msgs[pop2].m_size, pop2);
1205 }
1206
1207 static int ack2 (vec)
1208 char **vec;
1209 {
1210 if (strcmp (vec[0], "ackd") == 0) {
1211 Msgs[pop2].m_flags |= MDELE; /* ignored later if MREAD */
1212 Msgs[0].m_size -= Msgs[pop2].m_size;
1213 dmsgs++;
1214 }
1215
1216 if (pop2) { /* a current msg */
1217 rmsgs++; /* mark this one as read */
1218 if (++pop2 > nmsgs)
1219 pop2 = -1; /* let rdp2 reset */
1220 else if (Msgs[pop2].m_flags & MDELE)
1221 pop2 = -1; /* let rdp2 reset */
1222 if (pop2 > Msgs[0].m_last)
1223 Msgs[0].m_last = pop2;
1224 }
1225 return rdp2 (vec); /* vec = { "acks", 0 } */
1226 }
1227
1228 static int fold (vec)
1229 register char **vec;
1230 {
1231 pop2 = 0;
1232
1233 #ifdef notdef
1234
1235 /* This might work, or it might be a huge security hole. For my purpose,
1236 * it doesn't need to work, so I'm not going to make sure it's OK.
1237 * 16Nov90/JLR
1238 */
1239
1240 if (quitaux (NULLVP) == NOTOK)
1241 return respond ('#', "0 unable to close folder");
1242
1243 (void) sprintf (maildrop, vec[1]);
1244 if (setupaux (access (maildrop, 2) ? 1 : 0) == NOTOK)
1245 return respond ('#', "0 unable to read %s", maildrop);
1246
1247 pop2 = nmsgs > 0 ? 1 : 0;
1248 return respond ('#', "%d message%s in %s (%d octets)",
1249 nmsgs, nmsgs != 1 ? "s" : "", maildrop, Msgs[0].m_size);
1250
1251 #endif
1252
1253 respond ('#', "0 unable to change folders");
1254 return NOTOK;
1255 }
1256 #endif /* POP2 */
1257
1258 static int list (vec)
1259 register char **vec;
1260 {
1261 register int i;
1262
1263 if (vec[1]) {
1264 if ((i = atoi (vec[1])) <= 0 || i > nmsgs)
1265 return respond (NOTOK, "no such message: \"%s\"", vec[1]);
1266 if (Msgs[i].m_flags & MDELE)
1267 return respond (NOTOK, "message %d is deleted", i);
1268
1269 #ifndef BPOP
1270 return respond (OK, "%d %d", i, Msgs[i].m_size);
1271 #else /* BPOP */
1272 #ifdef MPOP
1273 if (nfs && !xtnded) {
1274 char *cp;
1275
1276 (void) fseek (dp, Msgs[i].m_start, 0);
1277
1278 switch (scan (dp, i, 0, nfs, 0, 0, 0,
1279 0, NULLCP, (long) Msgs[i].m_size, 0)) {
1280 case SCNMSG:
1281 case SCNENC:
1282 case SCNERR:
1283 if (cp = index (scanl, '\n'))
1284 *cp = NULL;
1285 return respond (OK, "%d %d #%s",
1286 i, Msgs[i].m_size, scanl);
1287
1288 case SCNEOF:
1289 return respond (OK, "%d %d #%*d empty",
1290 i, Msgs[i].m_size, DMAXFOLDER, i);
1291
1292 default:
1293 break;
1294 }
1295 }
1296 #endif /* MPOP */
1297 return respond (OK, xtnded ? "%d %d %d" : "%d %d",
1298 i, Msgs[i].m_size, Msgs[i].m_id);
1299 #endif /* BPOP */
1300 }
1301
1302 (void) respond (OK, "%d message%s (%d octets)",
1303 nmsgs - dmsgs, nmsgs - dmsgs != 1 ? "s" : "",
1304 Msgs[0].m_size);
1305 for (i = 1; i <= nmsgs; i++)
1306 if (!(Msgs[i].m_flags & MDELE)) {
1307 #ifndef BPOP
1308 multiline ("%d %d", i, Msgs[i].m_size);
1309 #else /* BPOP */
1310 #ifdef MPOP
1311 if (nfs && !xtnded) {
1312 char *cp;
1313
1314 (void) fseek (dp, Msgs[i].m_start, 0);
1315
1316 switch (scan (dp, i, 0, nfs, 0, 0, 0,
1317 0, NULLCP, (long) Msgs[i].m_size, 0)) {
1318 case SCNMSG:
1319 case SCNENC:
1320 case SCNERR:
1321 if (cp = index (scanl, '\n'))
1322 *cp = NULL;
1323 multiline ("%d %d #%s",
1324 i, Msgs[i].m_size, scanl);
1325 continue;
1326
1327 case SCNEOF:
1328 multiline ("%d %d #%*d empty",
1329 i, Msgs[i].m_size, DMAXFOLDER, i);
1330 continue;
1331
1332 default:
1333 break;
1334 }
1335 }
1336 #endif /* MPOP */
1337 multiline (xtnded ? "%d %d %d" : "%d %d",
1338 i, Msgs[i].m_size, Msgs[i].m_id);
1339 #endif /* BPOP */
1340 }
1341 multiend ();
1342
1343 return OK;
1344 }
1345
1346 /* \f */
1347
1348 static int retrieve (vec)
1349 register char **vec;
1350 {
1351 register int i;
1352 register long pos;
1353 register char *cp;
1354 char buffer[BUFSIZ];
1355
1356 #ifdef POP2
1357 if (pop2 == 0)
1358 return NOTOK;
1359 else if (pop2 == NOTOK) {
1360 #endif
1361 if ((i = atoi (vec[1])) <= 0 || i > nmsgs)
1362 return respond (NOTOK, "no such message: \"%s\"", vec[1]);
1363 if (Msgs[i].m_flags & MDELE)
1364 return respond (NOTOK, "message %d is deleted", i);
1365
1366 (void) respond (OK, "%d octets", Msgs[i].m_size);
1367 #ifdef POP2
1368 }
1369 else /* if called by pop2, vec = { "retr", 0 } */
1370 i = pop2;
1371 #endif
1372
1373 for ((void) fseek (dp, pos = Msgs[i].m_start, 0);
1374 fgets (buffer, sizeof buffer, dp) != NULL && pos < Msgs[i].m_stop;
1375 pos += (long) (cp - buffer + 1)) {
1376 if (*(cp = buffer + strlen (buffer) - 1) == '\n')
1377 *cp = 0;
1378 multiline ("%s", buffer);
1379 }
1380 #ifdef POP2
1381 if (pop2 == NOTOK) { /* then multiend */
1382 #endif
1383 multiend ();
1384
1385 if (i > Msgs[0].m_last) {
1386 Msgs[0].m_last = i;
1387 rmsgs++;
1388 }
1389 #ifdef POP2
1390 }
1391 #endif
1392
1393 return OK;
1394 }
1395
1396 /* \f */
1397
1398 static int delete (vec)
1399 register char **vec;
1400 {
1401 register int i;
1402
1403 if (Msgs[0].m_flags & MREAD)
1404 return respond (NOTOK, "maildrop is read-only");
1405
1406 if ((i = atoi (vec[1])) <= 0 || i > nmsgs)
1407 return respond (NOTOK, "no such message: \"%s\"", vec[1]);
1408 if (Msgs[i].m_flags & MDELE)
1409 return respond (NOTOK, "message %d is deleted", i);
1410
1411 Msgs[i].m_flags |= MDELE;
1412 Msgs[0].m_size -= Msgs[i].m_size;
1413 dmsgs++;
1414
1415 if (i > Msgs[0].m_last)
1416 Msgs[0].m_last = i;
1417
1418 return respond (OK, "message %d deleted (%d octets)", i, Msgs[i].m_size);
1419 }
1420
1421
1422 static int reset (vec)
1423 char **vec;
1424 {
1425 register int i;
1426
1427 for (i = 1; i <= nmsgs; i++)
1428 if (Msgs[i].m_flags & MDELE) {
1429 Msgs[i].m_flags &= ~MDELE;
1430 Msgs[0].m_size += Msgs[i].m_size;
1431 dmsgs--;
1432 }
1433
1434 Msgs[0].m_last = lastseen;
1435
1436 #ifdef MPOP
1437 #ifdef BPOP
1438 if (nfs) {
1439 if (scanl)
1440 free (scanl), scanl = NULL;
1441 free (nfs), nfs = NULL;
1442 }
1443 #endif
1444 #endif /* MPOP */
1445
1446 return status (vec);
1447 }
1448
1449 /* \f */
1450
1451 static int top (vec)
1452 register char **vec;
1453 {
1454 register int i,
1455 j,
1456 body,
1457 lines;
1458 register long pos;
1459 register char *cp;
1460 char buffer[BUFSIZ];
1461
1462 if ((i = atoi (vec[1])) <= 0 || i > nmsgs)
1463 return respond (NOTOK, "no such message: \"%s\"", vec[1]);
1464 if (Msgs[i].m_flags & MDELE)
1465 return respond (NOTOK, "message %d is deleted", i);
1466 if ((j = atoi (vec[2])) < 0)
1467 return respond (NOTOK, "bad number: \"%s\"", vec[2]);
1468
1469 (void) respond (OK, vec[0]);
1470
1471 body = lines = 0;
1472 for ((void) fseek (dp, pos = Msgs[i].m_start, 0);
1473 fgets (buffer, sizeof buffer, dp) != NULL && pos < Msgs[i].m_stop;
1474 pos += (long) (cp - buffer + 1)) {
1475 if (*(cp = buffer + strlen (buffer) - 1) == '\n')
1476 *cp = 0;
1477 if (body) {
1478 if (lines++ >= j)
1479 break;
1480 }
1481 else
1482 if (*buffer == 0)
1483 body++;
1484 multiline ("%s", buffer);
1485 }
1486 multiend ();
1487
1488 return OK;
1489 }
1490
1491 /* \f */
1492
1493 /* ARGSUSED */
1494
1495 static int last (vec)
1496 char **vec;
1497 {
1498 return respond (OK, "%d is the last msg seen", Msgs[0].m_last);
1499 }
1500
1501 /* \f */
1502
1503 #ifdef BPOP
1504 static int xtnd (vec)
1505 register char **vec;
1506 {
1507 make_lower (vec[1], vec[1]);
1508
1509 if (strcmp (vec[1], "bboards") == 0 || strcmp (vec[1], "archive") == 0)
1510 return xtnd1 (vec);
1511 if (strcmp (vec[1], "x-bboards") == 0)
1512 return xtnd2 (vec);
1513 #ifdef MPOP
1514 if (strcmp (vec[1], "scan") == 0)
1515 return xtnd3 (vec);
1516 #endif /* MPOP */
1517
1518 return respond (NOTOK, "unknown XTND command: \"%s\"", vec[1]);
1519 }
1520
1521
1522 static int xtnd1 (vec)
1523 register char **vec;
1524 {
1525 register struct bboard *bb;
1526
1527 if (vec[2]) {
1528 make_lower (vec[2], vec[2]);
1529 if ((bb = getbbaux (vec[2])) == NULL)
1530 return respond (NOTOK, "unknown BBoard: \"%s\"", vec[2]);
1531
1532 if (quitaux (NULLVP) == NOTOK)
1533 return NOTOK;
1534 (void) strcpy (maildrop,
1535 strcmp (vec[1], "bboards") ? bb -> bb_archive : bb -> bb_file);
1536 if (setupaux (TRUE) == NOTOK)
1537 return NOTOK;
1538 xtnded++;
1539 (void) respond (OK, "%s", vec[1]);
1540 multiline ("%s %d", bb -> bb_name, bb -> bb_maxima);
1541 }
1542 else {
1543 if (strcmp (vec[1], "bboards"))
1544 return respond (NOTOK, "too few arguments to XTND \"%s\"", vec[1]);
1545
1546 (void) respond (OK, "%s", vec[1]);
1547 for (bb = BBhead; bb; bb = bb -> bb_next) {
1548 getbbmax (bb);
1549 if (!(bb -> bb_flags & BB_INVIS))
1550 multiline ("%s %d", bb -> bb_name, bb -> bb_maxima);
1551 }
1552 while (bb = getbbaux (NULLCP))
1553 if (!(bb -> bb_flags & BB_INVIS))
1554 multiline ("%s %d", bb -> bb_name, bb -> bb_maxima);
1555 }
1556 multiend ();
1557
1558 return OK;
1559 }
1560
1561 /* \f */
1562
1563 static int xtnd2 (vec)
1564 register char **vec;
1565 {
1566 register char *cp,
1567 **ap;
1568 char buffer[BUFSIZ];
1569 register struct bboard *bb;
1570
1571 if (vec[2] == NULL)
1572 return respond (NOTOK, "too few arguments to XTND \"%s\"", vec[1]);
1573
1574 make_lower (vec[2], vec[2]);
1575 if ((bb = getbbaux (vec[2])) == NULL)
1576 return respond (NOTOK, "unknown BBoard: \"%s\"", vec[2]);
1577
1578 (void) respond (OK, "%s", vec[1]);
1579 multiline ("%s", bb -> bb_name);
1580
1581 cp = buffer;
1582 for (ap = bb -> bb_aka; *ap; ap++) {
1583 (void) sprintf (cp, cp != buffer ? " %s" : "%s", *ap);
1584 cp += strlen (cp);
1585 }
1586 multiline ("%s", buffer);
1587
1588 multiline ("%s", bb -> bb_file);
1589 multiline ("%s", bb -> bb_archive);
1590 multiline ("%s", bb -> bb_info);
1591 multiline ("%s", bb -> bb_map);
1592 multiline ("%s", bb -> bb_passwd);
1593
1594 cp = buffer;
1595 for (ap = bb -> bb_leader; *ap; ap++) {
1596 (void) sprintf (cp, cp != buffer ? " %s" : "%s", *ap);
1597 cp += strlen (cp);
1598 }
1599 multiline ("%s", buffer);
1600
1601 multiline ("%s", bb -> bb_addr);
1602 multiline ("%s", bb -> bb_request);
1603 multiline ("%s", bb -> bb_relay);
1604
1605 cp = buffer;
1606 for (ap = bb -> bb_dist; *ap; ap++) {
1607 (void) sprintf (cp, cp != buffer ? " %s" : "%s", *ap);
1608 cp += strlen (cp);
1609 }
1610 multiline ("%s", buffer);
1611
1612 getbbmax (bb);
1613 multiline ("0%o %d", bb -> bb_flags, bb -> bb_maxima);
1614 multiline ("%s", bb -> bb_date);
1615
1616 multiend ();
1617
1618 return OK;
1619 }
1620
1621 /* \f */
1622
1623 static struct bboard *getbbaux (s)
1624 register char *s;
1625 {
1626 register struct bboard *bb;
1627 struct stat st;
1628
1629 if (BBhead == NULL)
1630 if (setbbinfo (BBOARDS, BBDB, 1))
1631 BBtime = getbbtime ();
1632 else
1633 return NULL;
1634
1635 if (s != NULLCP)
1636 for (bb = BBhead; bb; bb = bb -> bb_next)
1637 if (strcmp (bb -> bb_name, s) == 0) {
1638 if (debug)
1639 padvise (NULLCP, LOG_DEBUG, "getbbaux: \"%s\" from cache",
1640 bb -> bb_name);
1641 getbbmax (bb);
1642 return bb;
1643 }
1644
1645 while (bb = getbbent ()) {
1646 if ((bb = getbbcpy (bb)) == NULL)
1647 return NULL;
1648
1649 if (access (bb -> bb_file, 04) == NOTOK && errno == EACCES)
1650 bb -> bb_flags |= BB_INVIS;
1651 bb -> bb_mtime = stat (bb -> bb_info, &st) != NOTOK ? st.st_mtime : 0L;
1652
1653 if (BBtail != NULL)
1654 BBtail -> bb_next = bb;
1655 if (BBhead == NULL)
1656 BBhead = bb;
1657 BBtail = bb;
1658
1659 if (s == NULL || strcmp (bb -> bb_name, s) == 0) {
1660 if (s && debug)
1661 padvise (NULLCP, LOG_DEBUG, "getbbaux: \"%s\" from scratch",
1662 bb -> bb_name);
1663 return bb;
1664 }
1665 }
1666
1667 return NULL;
1668 }
1669
1670 /* \f */
1671
1672 static getbbmax (bb)
1673 register struct bboard *bb;
1674 {
1675 int i;
1676 register char *cp;
1677 char buffer[BUFSIZ];
1678 struct stat st;
1679 register FILE * fp;
1680
1681 if (debug)
1682 padvise (NULLCP, LOG_DEBUG, "getbbmax: \"%s\", 0%o, %d, %s",
1683 bb -> bb_name, bb -> bb_flags, bb -> bb_maxima, bb -> bb_date);
1684
1685 if (!(bb -> bb_flags & BB_INVIS)
1686 && access (bb -> bb_file, 04) == NOTOK && errno == EACCES)
1687 bb -> bb_flags |= BB_INVIS;
1688
1689 if (stat (bb -> bb_info, &st) == NOTOK
1690 || bb -> bb_mtime == st.st_mtime
1691 || (fp = fopen (bb -> bb_info, "r")) == NULL)
1692 return;
1693 bb -> bb_mtime = st.st_mtime;
1694
1695 if (fgets (buffer, sizeof buffer, fp) && (i = atoi (buffer)) > 0)
1696 bb -> bb_maxima = i;
1697 if (!feof (fp) && fgets (buffer, sizeof buffer, fp)) {
1698 if (bb -> bb_date)
1699 free (bb -> bb_date);
1700 if (cp = index (buffer, '\n'))
1701 *cp = NULL;
1702 bb -> bb_date = getcpy (buffer);
1703 }
1704
1705 (void) fclose (fp);
1706
1707 if (debug)
1708 padvise (NULLCP, LOG_DEBUG, "updated: \"%s\", 0%o, %d, %s",
1709 bb -> bb_name, bb -> bb_flags, bb -> bb_maxima, bb -> bb_date);
1710 }
1711
1712 /* \f */
1713
1714 #ifdef MPOP
1715 static int xtnd3 (vec)
1716 register char **vec;
1717 {
1718 if (vec[2] == NULL)
1719 return respond (NOTOK, "too few arguments to XTND \"%s\"", vec[1]);
1720 if ((_sc_width = atoi (vec[2])) < WIDTH / 2)
1721 _sc_width = WIDTH / 2;
1722 nfs = new_fs (NULLCP, vec[3], FORMAT);
1723 if (scanl)
1724 (void) free (scanl), scanl = NULL;
1725
1726 return respond (OK, vec[1]);
1727 }
1728
1729 int sc_width () { return _sc_width; }
1730 #endif /* MPOP */
1731 #endif /* BPOP */
1732
1733 /* \f */
1734
1735 static int quit (vec)
1736 char **vec;
1737 {
1738 int d,
1739 n;
1740
1741 d = dmsgs, n = nmsgs;
1742
1743 if (quitaux (vec) == NOTOK)
1744 return NOTOK;
1745
1746 #ifdef BPOP
1747 if (xtnded)
1748 return respond (OK, "%s signing off", server);
1749 #endif /* BPOP */
1750
1751 if (n == d)
1752 return respond (OK, "%s signing off (maildrop empty)", server);
1753
1754 return respond (OK,
1755 n ? "%s signing off (%d message%s, %d octets left)"
1756 : "%s signing off (maildrop empty)",
1757 server, n - d, n - d != 1 ? "s" : "", Msgs[0].m_size);
1758 }
1759
1760
1761 static int quitaux (vec)
1762 char **vec;
1763 {
1764 int i;
1765
1766 if (dp == NULL)
1767 return OK;
1768
1769 i = quitfile (vec);
1770
1771 nmsgs = dmsgs = rmsgs = 0;
1772 (void) lkfclose (dp, maildrop);
1773 dp = NULL;
1774
1775 return i;
1776 }
1777
1778 /* \f */
1779
1780 /* ARGSUSED */
1781
1782 static int quitfile (vec)
1783 char **vec;
1784 {
1785 register int i,
1786 j,
1787 tmpDR,
1788 md;
1789 char tmpfil[BUFSIZ],
1790 map1[BUFSIZ],
1791 map2[BUFSIZ];
1792 struct stat st;
1793
1794 if(debug)padvise(NULLCP,LOG_DEBUG,"XXX: dmsgs=%d rmsgs=%d readonly=%d",
1795 dmsgs, rmsgs, Msgs[0].m_flags & MREAD);
1796
1797 if (dmsgs == 0 || (Msgs[0].m_flags & MREAD))
1798 return OK;
1799
1800 if (fstat (fileno (dp), &st) == NOTOK)
1801 return respond (NOTOK, "unable to stat file");
1802 if (mtime != st.st_mtime)
1803 return respond (NOTOK, "new messages have arrived, no update");
1804 mode = (int) (st.st_mode & 0777);
1805
1806 if (nmsgs == dmsgs) {
1807 #ifndef SYS5
1808 i = truncate (maildrop, 0);
1809 #else /* SYS5 */
1810 i = open (maildrop, O_WRONLY | O_TRUNC);
1811 if (i != NOTOK) (void) close (i);
1812 #endif /* SYS5 */
1813 (void) unlink (map_name (maildrop));/* XXX */
1814 if (i == NOTOK)
1815 return respond (NOTOK, "unable to zero %s", maildrop);
1816 return OK;
1817 }
1818
1819 (void) strcpy (tmpfil, m_backup (maildrop));
1820 if ((md = mbx_open (tmpfil, st.st_uid, st.st_gid, mode)) == NOTOK)
1821 { char msgbuf0[256];
1822 sprintf(msgbuf0,"unable to create temporary file (%s)",tmpfil);
1823 return respond (NOTOK, msgbuf0);
1824 }
1825
1826 j = 0, tmpDR = Msgs[0].m_last;
1827 if(debug)padvise(NULLCP,LOG_DEBUG,"XXX: last=%d",Msgs[0].m_last);
1828 for (i = 1; i <= nmsgs; i++) {
1829 if (!(Msgs[i].m_flags & MDELE))
1830 j++;
1831 if (i == tmpDR)
1832 Msgs[0].m_last = j;
1833 }
1834 if(debug)padvise(NULLCP,LOG_DEBUG,"XXX: last=%d",Msgs[0].m_last);
1835
1836 for (i = 1; i <= nmsgs; i++)
1837 if (!(Msgs[i].m_flags & MDELE)
1838 && mbx_write (tmpfil, md, dp, Msgs[i].m_id, Msgs[0].m_last,
1839 Msgs[i].m_start, Msgs[i].m_stop, TRUE, debug)
1840 == NOTOK) {
1841 (void) mbx_close (tmpfil, md);
1842 (void) unlink (tmpfil);
1843 return respond (NOTOK, "error writing temporary file");
1844 }
1845 (void) mbx_close (tmpfil, md);
1846
1847 if ((i = rename (tmpfil, maildrop)) == OK) {
1848 (void) strcpy (map1, map_name (tmpfil));
1849 (void) strcpy (map2, map_name (maildrop));
1850 if (rename (map1, map2) == NOTOK) {
1851 (void) unlink (map1);
1852 (void) unlink (map2);
1853 }
1854 }
1855
1856 if (i == NOTOK)
1857 return respond (NOTOK, "unable to rename maildrop");
1858
1859 return OK;
1860 }
1861
1862 /* \f */
1863
1864 static struct vector *getvector (bp, vec)
1865 register char *bp,
1866 **vec;
1867 {
1868 register int i;
1869 register struct vector *v;
1870
1871 for (i = 0; i < NVEC; i++) {
1872 while (isspace (*bp))
1873 *bp++ = 0;
1874 if (*bp == 0) {
1875 vec[i] = NULL;
1876 break;
1877 }
1878
1879 if (*bp == '"') {
1880 for (vec[i] = ++bp; *bp != '\0' && *bp != '"'; bp++)
1881 if (*bp == '\\') {
1882 switch (*++bp) {
1883 case 'n':
1884 (void) strcpy (bp, bp + 1);
1885 *--bp = '\n';
1886 break;
1887
1888 case '\\':
1889 case '"':
1890 (void) strcpy (bp - 1, bp);
1891 /* and fall... */
1892 default:
1893 bp--;
1894 break;
1895 }
1896 }
1897 if (*bp == '"')
1898 *bp++ = '\0';
1899 continue;
1900 }
1901
1902 vec[i] = bp;
1903 while (!isspace (*bp))
1904 bp++;
1905 }
1906 i--;
1907 vec[NVEC] = NULL;
1908
1909 if (*bp != 0) {
1910 (void) respond (NOTOK, "too many arguments");
1911 return NULL;
1912 }
1913 if (*vec[0] == 0) {
1914 (void) respond (NOTOK, "null command");
1915 return NULL;
1916 }
1917 make_lower (vec[0], vec[0]);
1918
1919 for (v = vectors; v -> v_cmd; v++)
1920 if (strcmp (v -> v_cmd, vec[0]) == 0 && v -> v_valid == mystate) {
1921 if (i < v -> v_min || v -> v_max < i) {
1922 (void) respond (NOTOK, "too %s arguments to \"%s\"",
1923 i < v -> v_min ? "few" : "many", vec[0]);
1924 return NULL;
1925 }
1926 else
1927 return v;
1928 }
1929
1930 (void) respond (NOTOK, "unknown command: \"%s\"", vec[0]);
1931 return NULL;
1932 }
1933
1934 /* \f */
1935
1936 /* VARARGS2 */
1937
1938 static int respond (code, fmt, a, b, c, d)
1939 char *fmt,
1940 *a,
1941 *b,
1942 *c,
1943 *d;
1944 int code;
1945 {
1946 register char *bp;
1947 char buffer[BUFSIZ];
1948
1949 bp = buffer;
1950 #ifndef POP2
1951 (void) sprintf (bp, "%s%s", code == OK ? "+OK" : "-ERR", fmt ? " " : "");
1952 bp += strlen (bp);
1953 #else
1954 switch (code) {
1955 case OK:
1956 case NOTOK:
1957 (void) sprintf (bp, "%s%s", code == OK ? "+OK" : "-ERR",
1958 fmt ? " " : "");
1959 bp += strlen (bp);
1960 break;
1961
1962 default: /* only happens in pop2 */
1963 *bp++ = code;
1964 code = OK;
1965 }
1966 #endif
1967 if (fmt) {
1968 (void) sprintf (bp, fmt, a, b, c, d);
1969 bp += strlen (bp);
1970 }
1971 putline (buffer, output);
1972
1973 return code;
1974 }
1975
1976
1977 /* VARARGS1 */
1978
1979 static multiline (fmt, a, b, c, d)
1980 char *fmt,
1981 *a,
1982 *b,
1983 *c,
1984 *d;
1985 {
1986 register char *cp;
1987 char buffer[BUFSIZ + TRMLEN];
1988
1989 (void) strcpy (buffer, TRM);
1990 (void) sprintf (cp = (buffer + TRMLEN), fmt, a, b, c, d);
1991 if (strncmp (cp, TRM, TRMLEN) == 0)
1992 cp = buffer;
1993
1994 putline (cp, output);
1995 }
1996
1997
1998 static multiend () {
1999 putline (TRM, output);
2000 }
2001
2002 /* \f */
2003
2004 static int getline (s, n, iop)
2005 register char *s;
2006 register int n;
2007 register FILE *iop;
2008 {
2009 register int c;
2010 register char *p;
2011
2012 p = s;
2013 while (--n > 0 && (c = fgetc (iop)) != EOF) {
2014 while (c == IAC) {
2015 (void) fgetc (iop);
2016 c = fgetc (iop);
2017 }
2018 if ((*p++ = c) == '\n')
2019 break;
2020 }
2021 if (ferror (iop))
2022 return NOTOK;
2023 if (c == EOF && p == s)
2024 return DONE;
2025 if (debug) {
2026 if (*--p == '\n')
2027 *p = 0;
2028 padvise (NULLCP, LOG_DEBUG, "<--- %s", s);
2029 if (*p == 0)
2030 *p = '\n';
2031 p++;
2032 }
2033 *p++ = 0;
2034
2035 return OK;
2036 }
2037
2038
2039 static putline (s, iop)
2040 register char *s;
2041 register FILE *iop;
2042 {
2043 (void) fprintf (iop, "%s\r\n", s);
2044 if (debug)
2045 padvise (NULLCP, LOG_DEBUG, "---> %s", s);
2046
2047 (void) fflush (iop);
2048 }
2049
2050
2051 /* ARGSUSED */
2052
2053 static TYPESIG pipeser (sig, code, sc)
2054 int sig;
2055 long code;
2056 struct sigcontext *sc;
2057 {
2058 padvise (NULLCP, LOG_WARNING, "lost connection");
2059
2060 _exit (NOTOK);
2061 }
2062
2063 /* \f */
2064
2065 /* Some people don't want to use the POP delivery agent with Sendmail
2066 * if they're going to run POP. Sendmail writes maildrops in the old
2067 * UUCP format, and popd doesn't know how to read them. These people
2068 * really should do what the MH manual says -- run the pop delivery
2069 * agent and be done with it. Some things never die.
2070 *
2071 * A real fix would be to make uip/dropsbr.c should use the same methods
2072 * as sbr/m_getfld.c to determine the format of maildrops and read &
2073 * write them. Unfortunately, it'll take a lot of work to bring it into
2074 * the fold. 20Mar90/JLR
2075 *
2076 * I really really hate to add this, but this lets stuff popd read
2077 * UUCP style maildrops as well as MMDF (ctrl/A) style maildrops. It was
2078 * contributed by Steve Dempsey <steved@@longs.LANCE.ColoState.Edu>.
2079 *
2080 * Here's what he says:
2081 *
2082 * Ideally, one should be able to do it with the mmdelim strings, but
2083 * the MH parser is not intelligent enough to do this. You have at
2084 * least a couple of choices:
2085 *
2086 * - use aliases to deliver mail to POP users (user: user@@pop) and
2087 * install the POP delivery agent - should work well with sendmail.
2088 * - fix the POP server!
2089 *
2090 * We have all mail sent to one machine and users are given two options:
2091 *
2092 * - MH on any machine.
2093 * - any user agent on the postoffice machine.
2094 *
2095 * Most of our workstations run xmh and users find that to be sufficient.
2096 * New users are only taught to use MH, and a very few old timers stay
2097 * with BSD mail. In any case, several agents are available at the cost
2098 * of a telnet/rlogin if a user does not like MH.
2099 *
2100 * I have made the changes to the POP server (MH-6.6/support/pop/popser.c)
2101 * to look for the `\n\nFrom ' delimiter instead of the ^A's, using some
2102 * code from the BSD agent. Context diff is included below. When this
2103 * is installed, you just go back to the normal localmail and get rid of
2104 * slocal completely.
2105 *
2106 * I have not tried this modification with anything but the MH client,
2107 * but it should work. Nothing in the POP protocol changes; the server
2108 * just has different criteria for delimiting messages in the mailbox.
2109 * If you decide to use this, I'd like to know what happens.
2110 *
2111 * Steve Dempsey, Center for Computer Assisted Engineering
2112 * Colorado State University, Fort Collins, CO 80523 +1 303 491 0630
2113 * INET: steved@@longs.LANCE.ColoState.Edu, dempsey@@handel.CS.ColoState.Edu
2114 * boulder!ccncsu!longs.LANCE.ColoState.Edu!steved, ...!ncar!handel!dempsey
2115 */
2116 /* From: Jim Reid <jim@@computer-science.strathclyde.ac.UK>
2117 *
2118 * MH-6.7 does not support MMDF-style mailboxes with POP as claimed. It
2119 * appears that when code was added to popser.c to support UNIX-style
2120 * mailboxes, the old behaviour was lost. i.e. The new popd worked with
2121 * UNIX-style mailboxes, but not MMDF ones. Users would get "format error"
2122 * error messages if they tried to inc a remote MMDF-style mailbox because
2123 * the pop daemon didn't want to know or like the MMDF message delimiters.
2124 */
2125
2126 /* So... Now there's an incredible hack in mhconfig.c to define POPUUMBOX
2127 * in support/pop/Makefile if we're using Sendmail. This causes this
2128 * UUCP-mbox reading code to be used here. Ugh. 05Nov90/JLR
2129 */
2130
2131 /* \f */
2132 #ifdef POPUUMBOX
2133 /* from dropsbr.c - read from a mailbox - pop server version */
2134
2135 /* ALMOST IDENTICAL to mbx_read */
2136
2137 static int pmbx_read (fp, pos, drops, noisy)
2138 register FILE *fp;
2139 register long pos;
2140 struct drop **drops;
2141 int noisy;
2142 {
2143 register int len,
2144 size;
2145 register char *bp;
2146 char buffer[BUFSIZ];
2147 register struct drop *cp,
2148 *dp,
2149 *ep,
2150 *pp;
2151
2152 /* MTR: tsk, tsk, tsk... */
2153 (void) fseek (fp, pos, 0);
2154 if (fgets (buffer, sizeof buffer, fp)
2155 && strcmp (buffer, mmdlm1) == 0)
2156 return mbx_read (fp, pos, drops, noisy);
2157
2158 /* get drop storage */
2159 pp = (struct drop *) calloc ((unsigned) (len = MAXFOLDER), sizeof *dp);
2160
2161 if (debug)
2162 padvise (NULLCP, LOG_DEBUG, "pmbx_read (%d, %ld, %d, %d)",
2163 fp, pos,drops,noisy);
2164
2165 if (pp == NULL) {
2166 if (noisy)
2167 admonish (NULLCP, "unable to allocate drop storage");
2168 return NOTOK;
2169 }
2170
2171 /* rewind drop file */
2172 (void) fseek (fp, pos, 0);
2173
2174 if (debug)
2175 padvise (NULLCP, LOG_DEBUG, "rewind maildrop");
2176
2177 /* read a buffer */
2178 for (ep = (dp = pp) + len - 1; fgets (buffer, sizeof buffer, fp);) {
2179 size = 0;
2180
2181 /* if beginning of msg then mark it */
2182
2183 if (p_ishead(buffer)) /*(strcmp (buffer, mmdlm1) == 0)*/ {
2184 /* (don't) inc pos to msg start, mark it */
2185 /*pos += ld1;*/
2186 dp -> d_start = pos;
2187 pos += strlen(buffer); /* inc pos after marking head */
2188 }
2189 else {
2190 /* didn't find it; mark it anyway */
2191 dp -> d_start = pos, pos += (long) strlen (buffer);
2192
2193 /* count newlines and inc size if any found */
2194 for (bp = buffer; *bp; bp++, size++)
2195 if (*bp == '\n')
2196 size++;
2197 }
2198
2199 /* read more lines... */
2200 while (fgets (buffer, sizeof buffer, fp) != NULL)
2201
2202 /* found end? */
2203 if (p_ishead(buffer)) /*(strcmp (buffer, mmdlm2) == 0)*/ {
2204
2205 /* out of loop */
2206 (void) fseek (fp, pos, 0);
2207 break;
2208
2209 }
2210 else {
2211 /* add buffer size to pos */
2212 pos += (long) strlen (buffer);
2213
2214 /* count newlines.... */
2215 for (bp = buffer; *bp; bp++, size++)
2216 if (*bp == '\n')
2217 size++;
2218 }
2219
2220 if (dp -> d_start != pos) {
2221 /* do this if pos was actually incremented; got some text */
2222 dp -> d_id = 0;
2223 dp -> d_size = size; /* save the stuff we got */
2224 dp -> d_stop = pos;
2225 dp++;
2226 }
2227
2228 /* (don't) advance pos */
2229 /* pos += ld2; */
2230
2231 /* need more storage.... */
2232 if (dp >= ep) {
2233 register int curlen = dp - pp;
2234
2235 cp = (struct drop *) realloc ((char *) pp,
2236 (unsigned) (len += MAXFOLDER) * sizeof *pp);
2237 if (cp == NULL) {
2238 if (noisy)
2239 admonish (NULLCP, "unable to allocate drop storage");
2240 free ((char *) pp);
2241 return 0;
2242 }
2243 dp = cp + curlen, ep = (pp = cp) + len - 1;
2244 }
2245 }
2246
2247 /* return unused stuff */
2248 if (dp == pp)
2249 free ((char *) pp);
2250 else
2251 *drops = pp;
2252 return (dp - pp);
2253 }
2254
2255 /*
2256 * The remainder of this file adapted from:
2257 *
2258 * head.c 5.2 (Berkeley) 6/21/85
2259 */
2260
2261 struct p_hdline {
2262 char *l_from; /* The name of the sender */
2263 char *l_tty; /* His tty string (if any) */
2264 char *l_date; /* The entire date string */
2265 };
2266
2267 /*
2268 *
2269 * See if position in a file is a mail header.
2270 * Return true if yes. Note the extreme pains to
2271 * accomodate all funny formats.
2272 */
2273
2274 #define NOSTR ((char *) 0) /* Null string pointer */
2275 static char *p_copyin();
2276 static char *p_copy();
2277
2278
2279 static p_ishead(buffer)
2280 char buffer[];
2281 {
2282 register char *cp;
2283 struct p_hdline hl;
2284 char linebuf[BUFSIZ];
2285 char parbuf[BUFSIZ];
2286
2287 strcpy(linebuf,buffer);
2288 cp = linebuf;
2289
2290 if (linebuf[0]=='F')
2291 padvise (NULLCP, LOG_DEBUG, "ishead: '%s'",linebuf);
2292
2293 if (strncmp("From ", cp, 5) != 0)
2294 return(0);
2295
2296 padvise (NULLCP, LOG_DEBUG, "Fromline...");
2297
2298 /* get full header */
2299 p_parse(cp, &hl, parbuf);
2300
2301 if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
2302 padvise (NULLCP, LOG_DEBUG, "Fromline...NODATE");
2303 return(0);
2304 }
2305
2306 if (!p_isdate(hl.l_date)) {
2307 padvise (NULLCP, LOG_DEBUG, "Fromline...BADDATE %s",
2308 hl.l_date);
2309 return(0);
2310 }
2311
2312 /* I guess we got it! */
2313 padvise (NULLCP, LOG_DEBUG, "got a head.. ");
2314
2315 return(1);
2316 }
2317
2318 /*
2319 * Split a headline into its useful components.
2320 * Copy the line into dynamic string space, then set
2321 * pointers into the copied line in the passed headline
2322 * structure. Actually, it scans.
2323 */
2324
2325 static p_parse(line, hl, pbuf)
2326 char line[], pbuf[];
2327 struct p_hdline *hl;
2328 {
2329 register char *cp, *dp;
2330 char *sp;
2331 char word[BUFSIZ];
2332 char * p_nextword();
2333
2334 hl->l_from = NOSTR;
2335 hl->l_tty = NOSTR;
2336 hl->l_date = NOSTR;
2337 cp = line;
2338 sp = pbuf;
2339
2340 /*
2341 * Skip the first "word" of the line, which should be "From"
2342 * anyway.
2343 */
2344 cp = p_nextword(cp, word);
2345 dp = p_nextword(cp, word);
2346 if (!(strcmp(word, "")==0))
2347 hl->l_from = p_copyin(word, &sp);
2348
2349 /* UNLIKELY */
2350 if (strncmp(dp, "tty", 3) == 0) {
2351 cp = p_nextword(dp, word);
2352 hl->l_tty = p_copyin(word, &sp);
2353 if (cp != NOSTR)
2354 hl->l_date = p_copyin(cp, &sp);
2355 }
2356
2357 /* USUAL */
2358 else
2359 if (dp != NOSTR)
2360 hl->l_date = p_copyin(dp, &sp);
2361 }
2362
2363 /*
2364 * Copy the string on the left into the string on the right
2365 * and bump the right (reference) string pointer by the length.
2366 * Thus, dynamically allocate space in the right string, copying
2367 * the left string into it.
2368 */
2369
2370 static char *
2371 p_copyin(src, space)
2372 char src[];
2373 char **space;
2374 {
2375 register char *cp, *top;
2376 register int s;
2377
2378 s = strlen(src);
2379 cp = *space;
2380 top = cp;
2381 strcpy(cp, src);
2382 cp += s + 1;
2383 *space = cp;
2384 return(top);
2385 }
2386
2387 /*
2388 * Collect a liberal (space, tab delimited) word into the word buffer
2389 * passed. Also, return a pointer to the next word following that,
2390 * or (empty) if none follow.
2391 */
2392
2393 static char *
2394 p_nextword(wp, wbuf)
2395 char wp[], wbuf[];
2396 {
2397 register char *cp, *cp2;
2398
2399 if ((cp = wp) == NOSTR) {
2400 p_copy("", wbuf);
2401 return(NOSTR);
2402 }
2403 cp2 = wbuf;
2404 while (!any(*cp, " \t") && *cp != '\0')
2405 if (*cp == '"') {
2406 *cp2++ = *cp++;
2407 while (*cp != '\0' && *cp != '"')
2408 *cp2++ = *cp++;
2409 if (*cp == '"')
2410 *cp2++ = *cp++;
2411 } else
2412 *cp2++ = *cp++;
2413 *cp2 = '\0';
2414 while (any(*cp, " \t"))
2415 cp++;
2416 if (*cp == '\0')
2417 return(NOSTR);
2418 return(cp);
2419 }
2420
2421 /*
2422 * Copy str1 to str2, return pointer to null in str2.
2423 */
2424
2425 static char *
2426 p_copy(str1, str2)
2427 char *str1, *str2;
2428 {
2429 register char *s1, *s2;
2430
2431 s1 = str1;
2432 s2 = str2;
2433 while (*s1)
2434 *s2++ = *s1++;
2435 *s2 = 0;
2436 return(s2);
2437 }
2438
2439 #define L 1 /* A lower case char */
2440 #define S 2 /* A space */
2441 #define D 3 /* A digit */
2442 #define O 4 /* An optional digit or space */
2443 #define C 5 /* A colon */
2444 #define N 6 /* A new line */
2445 #define U 7 /* An upper case char */
2446
2447 static char p_ctypes[] =
2448 {U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0};
2449 /* T h u S e p 2 9 1 5 : 2 0 : 1 9 1 9 8 8 */
2450
2451 static char p_tmztyp[] =
2452 {U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,U,U,U,S,D,D,D,D,0};
2453 /* T h u S e p 2 9 1 5 : 2 0 : 1 9 M S T 1 9 8 8 */
2454
2455 static p_isdate(date)
2456 char date[];
2457 {
2458 register char *cp;
2459
2460 cp = date;
2461 if (p_cmatch(cp, p_ctypes))
2462 return(1);
2463
2464 return(p_cmatch(cp, p_tmztyp));
2465 }
2466
2467 /*
2468 * Match the given string against the given template.
2469 * Return 1 if they match, 0 if they don't
2470 */
2471
2472 static p_cmatch(str, temp)
2473 char str[], temp[];
2474 {
2475 register char *cp, *tp;
2476 register int c;
2477
2478 cp = str;
2479 tp = temp;
2480 while (*cp != '\0' && *tp != 0) {
2481 c = *cp++;
2482 switch (*tp++) {
2483 case L:
2484 if (c < 'a' || c > 'z')
2485 return(0);
2486 break;
2487
2488 case U:
2489 if (c < 'A' || c > 'Z')
2490 return(0);
2491 break;
2492
2493 case S:
2494 if (c != ' ')
2495 return(0);
2496 break;
2497
2498 case D:
2499 if (!isdigit(c))
2500 return(0);
2501 break;
2502
2503 case O:
2504 if (c != ' ' && !isdigit(c))
2505 return(0);
2506 break;
2507
2508 case C:
2509 if (c != ':')
2510 return(0);
2511 break;
2512
2513 case N:
2514 if (c != '\n')
2515 return(0);
2516 break;
2517 }
2518 }
2519 if ((*cp != '\0' && *cp != '\n') || *tp != 0)
2520 return(0);
2521 return(1);
2522 }
2523
2524 static any(ch, str)
2525 char *str;
2526 {
2527 register char *f;
2528 register c;
2529
2530 f = str;
2531 c = ch;
2532 while (*f)
2533 if (c == *f++)
2534 return(1);
2535 return(0);
2536 }
2537 #endif
2538 @
2539
2540
2541 1.33
2542 log
2543 @typo
2544 @
2545 text
2546 @d3 1
2547 a3 1
2548 static char ident[]="@@(#)$Id: popser.c,v 1.32 1994/04/21 18:20:15 jromine Exp jromine $";
2549 d24 3
2550 @
2551
2552
2553 1.32
2554 log
2555 @update for scansbr.c
2556 @
2557 text
2558 @d3 1
2559 a3 1
2560 static char ident[]="@@(#)$Id: popser.c,v 1.31 1993/08/25 17:23:14 jromine Exp jromine $";
2561 d1126 2
2562 a1127 2
2563 switch (scan (dp, i, 0, nfs, 0, 0, NULLCP,
2564 (long) Msgs[i].m_size, 0)) {
2565 @
2566
2567
2568 1.31
2569 log
2570 @off_t fixes for BSD44
2571 @
2572 text
2573 @d3 1
2574 a3 1
2575 static char ident[]="@@(#)$Id: popser.c,v 1.30 1992/12/16 22:31:20 jromine Exp jromine $";
2576 d1088 2
2577 a1089 2
2578 switch (scan (dp, i, 0, nfs, 0, 0, NULLCP,
2579 (long) Msgs[i].m_size, 0)) {
2580 @
2581
2582
2583 1.30
2584 log
2585 @TYPESIG fixups
2586 @
2587 text
2588 @d3 1
2589 a3 1
2590 static char ident[]="@@(#)$Id: popser.c,v 1.29 1992/12/15 00:20:22 jromine Exp jromine $";
2591 a229 1
2592 long lseek ();
2593 @
2594
2595
2596 1.29
2597 log
2598 @endif sugar
2599 @
2600 text
2601 @d3 1
2602 a3 1
2603 static char ident[]="@@(#)$Id: popser.c,v 1.28 1992/12/14 17:49:09 jromine Exp jromine $";
2604 d218 1
2605 a218 1
2606 static int pipeser ();
2607 d1864 1
2608 a1864 1
2609 static int pipeser (sig, code, sc)
2610 @
2611
2612
2613 1.28
2614 log
2615 @fix decls
2616 @
2617 text
2618 @d3 1
2619 a3 1
2620 static char ident[]="@@(#)$Id: popser.c,v 1.27 1992/10/28 18:42:42 jromine Exp jromine $";
2621 d29 1
2622 a29 1
2623 #endif SYS5
2624 d32 1
2625 a32 1
2626 #endif SHADOW
2627 d71 1
2628 a71 1
2629 #endif BPOP
2630 d74 1
2631 a74 1
2632 #endif RPOP
2633 d82 1
2634 a82 1
2635 #endif BPOP
2636 d86 1
2637 a86 1
2638 #endif POP2
2639 d99 1
2640 a99 1
2641 #endif RPOP
2642 d121 1
2643 a121 1
2644 #endif BPOP
2645 d141 1
2646 a141 1
2647 #endif POP2
2648 d151 1
2649 a151 1
2650 #endif POP2
2651 d155 1
2652 a155 1
2653 #endif DPOP
2654 d184 1
2655 a184 1
2656 #endif BPOP
2657 d255 1
2658 a255 1
2659 #endif BPOP
2660 d311 1
2661 a311 1
2662 #endif BPOP
2663 d336 1
2664 a336 1
2665 #endif defined (DPOP) || defined (BPOP)
2666 d376 1
2667 a376 1
2668 #endif DPOP
2669 d384 1
2670 a384 1
2671 #endif BPOP
2672 d451 2
2673 a452 2
2674 #endif SHADOW
2675 #else DPOP
2676 d454 1
2677 a454 1
2678 #endif DPOP
2679 d485 1
2680 a485 1
2681 #endif TRUSTED
2682 d489 1
2683 a489 1
2684 #endif BPOP
2685 d494 1
2686 a494 1
2687 #else SHADOW
2688 d498 1
2689 a498 1
2690 #endif SHADOW
2691 d502 1
2692 a502 1
2693 #endif TRUSTED
2694 d505 1
2695 a505 1
2696 #else DPOP
2697 d515 1
2698 a515 1
2699 #endif BPOP
2700 d523 1
2701 a523 1
2702 #endif TRUSTED
2703 d526 1
2704 a526 1
2705 #endif DPOP
2706 d530 1
2707 a530 1
2708 #endif BPOP
2709 d535 1
2710 a535 1
2711 #else DPOP
2712 d537 1
2713 a537 1
2714 #endif DPOP
2715 d541 1
2716 a541 1
2717 #endif TRUSTED
2718 d575 1
2719 a575 1
2720 #endif BPOP
2721 d585 1
2722 a585 1
2723 #else DPOP
2724 d591 1
2725 a591 1
2726 #endif DPOP
2727 d598 1
2728 a598 1
2729 #endif TRUSTED
2730 d607 1
2731 a607 1
2732 #endif TRUSTED
2733 d610 1
2734 a610 1
2735 #else DPOP
2736 d617 1
2737 a617 1
2738 #endif TRUSTED
2739 d639 1
2740 a639 1
2741 #endif TRUSTED
2742 d642 1
2743 a642 1
2744 #endif DPOP
2745 d648 1
2746 a648 1
2747 #else DPOP
2748 d650 1
2749 a650 1
2750 #endif DPOP
2751 d654 1
2752 a654 1
2753 #endif TRUSTED
2754 d657 1
2755 a657 1
2756 #endif RPOP
2757 d756 1
2758 a756 1
2759 #else DPOP
2760 d758 1
2761 a758 1
2762 #endif DPOP
2763 d766 1
2764 a766 1
2765 #endif SYS5
2766 d770 1
2767 a770 1
2768 #endif BPOP
2769 d775 1
2770 a775 1
2771 #endif SYS5
2772 d777 1
2773 a777 1
2774 #else DPOP
2775 d781 1
2776 a781 1
2777 #endif SYS5
2778 d783 1
2779 a783 1
2780 #endif DPOP
2781 d786 1
2782 a786 1
2783 #endif BPOP
2784 d792 1
2785 a792 1
2786 #else DPOP
2787 d794 1
2788 a794 1
2789 #endif DPOP
2790 d806 1
2791 a806 1
2792 #endif POP2
2793 d823 1
2794 a823 1
2795 #endif BPOP
2796 d1067 1
2797 a1067 1
2798 #endif POP2
2799 d1082 1
2800 a1082 1
2801 #else BPOP
2802 d1110 1
2803 a1110 1
2804 #endif BPOP
2805 d1120 1
2806 a1120 1
2807 #else BPOP
2808 d1150 1
2809 a1150 1
2810 #endif BPOP
2811 d1542 1
2812 a1542 1
2813 #endif BPOP
2814 d1560 1
2815 a1560 1
2816 #endif BPOP
2817 d1620 1
2818 a1620 1
2819 #else SYS5
2820 d1623 1
2821 a1623 1
2822 #endif SYS5
2823 @
2824
2825
2826 1.27
2827 log
2828 @add some MPOP #ifdefs
2829 @
2830 text
2831 @d3 1
2832 a3 1
2833 static char ident[]="@@(#)$Id: popser.c,v 1.16 1990/11/16 14:56:38 mh Exp jromine $";
2834 d81 1
2835 a81 1
2836 int xtnd ();
2837 d183 1
2838 a183 1
2839 struct bboard *getbbaux ();
2840 @
2841
2842
2843 1.26
2844 log
2845 @APOP changes from MTR
2846 @
2847 text
2848 @d3 1
2849 a3 1
2850 static char ident[]="@@(#)$Id: popser.c,v 1.25 1992/10/20 22:47:28 jromine Exp jromine $";
2851 d8 1
2852 d13 1
2853 d66 3
2854 d70 1
2855 d116 3
2856 d120 1
2857 d206 1
2858 d211 1
2859 d1083 1
2860 d1107 1
2861 d1121 1
2862 d1147 1
2863 d1247 1
2864 d1255 1
2865 d1324 1
2866 d1327 1
2867 d1525 1
2868 d1541 1
2869 @
2870
2871
2872 1.25
2873 log
2874 @change location of md5.c
2875 @
2876 text
2877 @d3 1
2878 a3 1
2879 static char ident[]="@@(#)$Id: popser.c,v 1.24 1992/05/19 20:59:21 jromine Exp jromine $";
2880 d665 2
2881 a666 1
2882 unsigned char *ep;
2883 d723 1
2884 a723 1
2885 MD5Final (&mdContext);
2886 d726 1
2887 a726 2
2888 for (ep = (dp = mdContext.digest)
2889 + sizeof mdContext.digest / sizeof mdContext.digest[0];
2890 @
2891
2892
2893 1.24
2894 log
2895 @NULL->0
2896 @
2897 text
2898 @d3 1
2899 a3 1
2900 static char ident[]="@@(#)$Id: popser.c,v 1.23 1992/02/11 17:40:59 jromine Exp jromine $";
2901 d651 1
2902 a651 1
2903 #include "md5.c"
2904 @
2905
2906
2907 1.23
2908 log
2909 @cleanup KPOP ifdefs
2910 @
2911 text
2912 @d3 1
2913 a3 1
2914 static char ident[]="@@(#)$Id: popser.c,v 1.22 1992/02/10 22:35:58 jromine Exp jromine $";
2915 d1669 1
2916 a1669 1
2917 for (vec[i] = ++bp; *bp != NULL && *bp != '"'; bp++)
2918 d1687 1
2919 a1687 1
2920 *bp++ = NULL;
2921 @
2922
2923
2924 1.22
2925 log
2926 @allow "top msg 0"
2927 @
2928 text
2929 @d3 1
2930 a3 1
2931 static char ident[]="@@(#)$Id: popser.c,v 1.21 1992/02/04 21:59:41 jromine Exp jromine $";
2932 d24 1
2933 a24 1
2934 #endif
2935 d312 1
2936 a312 1
2937 #else
2938 d318 1
2939 a318 1
2940 #endif
2941 d337 1
2942 a337 1
2943 #endif
2944 d354 1
2945 a354 1
2946 #endif
2947 a418 4
2948 #else
2949 return respond (OK, "password required for %s", username);
2950 #endif
2951 #ifdef KPOP
2952 d424 2
2953 d462 1
2954 a462 1
2955 #else
2956 @
2957
2958
2959 1.21
2960 log
2961 @contributed patch
2962 @
2963 text
2964 @d3 1
2965 a3 1
2966 static char ident[]="@@(#)$Id: popser.c,v 1.20 1992/02/04 21:44:56 jromine Exp jromine $";
2967 d1261 1
2968 a1261 1
2969 if ((j = atoi (vec[2])) <= 0)
2970 @
2971
2972
2973 1.20
2974 log
2975 @contributed patch
2976 @
2977 text
2978 @d3 1
2979 a3 1
2980 static char ident[]="@@(#)$Id: popser.c,v 1.19 1992/02/04 21:39:42 jromine Exp jromine $";
2981 d719 2
2982 d734 1
2983 a734 2
2984 if (strcmp (vec[2], buffer)) {
2985 dbm_close (db);
2986 a735 1
2987 }
2988 @
2989
2990
2991 1.19
2992 log
2993 @contributed patch
2994 @
2995 text
2996 @d3 1
2997 a3 1
2998 static char ident[]="@@(#)$Id: popser.c,v 1.18 1992/02/03 17:52:59 jromine Exp jromine $";
2999 d95 1
3000 a95 1
3001 "apop", 3, 3, apop, auth1, trans, auth1,
3002 d150 1
3003 d336 1
3004 a336 1
3005 (void) sprintf (server, "%s %s server", myhost, priv ? "RPOP" : "POP");
3006 d374 2
3007 a375 2
3008 (void) respond (OK, "%s ready (Comments to: PostMaster@@%s)",
3009 server, myhost);
3010 d377 5
3011 d652 1
3012 a660 7
3013 struct authinfo {
3014 long auth_clock;
3015 char auth_secret[16];
3016 int auth_secretlen;
3017 };
3018
3019
3020 a663 1
3021 long clock;
3022 d665 1
3023 a665 2
3024 char *ap,
3025 buffer[BUFSIZ];
3026 d695 1
3027 a695 1
3028 if ((db = dbm_open (APOP, O_RDWR, 0)) == NULL)
3029 d704 1
3030 a704 1
3031 if (flock (dbm_pagfno (db), LOCK_EX) == NOTOK) {
3032 d716 2
3033 a718 14
3034 if (sscanf (vec[2], "%ld", &clock) != 1) {
3035 dbm_close (db);
3036 return respond (NOTOK, "invalid timestamp");
3037 }
3038 if (clock < auth.auth_clock) {
3039 dbm_close (db);
3040 return respond (NOTOK, "timestamp smaller than %ld",
3041 auth.auth_clock);
3042 }
3043
3044 (void) sprintf (cp = buffer, "%s %s ", vec[1], vec[2]);
3045 cp += strlen (cp);
3046 (void) bcopy (auth.auth_secret, ap = cp, auth.auth_secretlen);
3047
3048 d721 1
3049 a721 1
3050 (unsigned int) ((cp - buffer) + auth.auth_secretlen));
3051 d724 1
3052 d732 1
3053 a732 1
3054 if (strcmp (vec[3], ap)) {
3055 a735 5
3056 auth.auth_clock = clock;
3057 value.dptr = (char *) &auth, value.dsize = sizeof auth;
3058 if (dbm_store (db, key, value, DBM_REPLACE))
3059 padvise (NULLCP, LOG_INFO, "POP authorization DB may be corrupt?!?");
3060 dbm_close (db);
3061 @
3062
3063
3064 1.18
3065 log
3066 @getpw
3067 STDC
3068 SYS5
3069 @
3070 text
3071 @d3 1
3072 a3 1
3073 static char ident[]="@@(#)$Id: popser.c,v 1.17 1992/01/31 22:06:03 jromine Exp jromine $";
3074 d8 4
3075 d36 1
3076 a36 1
3077 #define NVEC 4
3078 d64 1
3079 a64 1
3080 static int xtnd1(), xtnd2();
3081 d69 3
3082 d94 3
3083 d110 1
3084 a110 1
3085 "xtnd", 1, 2, xtnd, trans, trans, trans,
3086 d195 4
3087 d227 1
3088 a228 1
3089 #endif
3090 d645 116
3091 d1091 23
3092 d1115 1
3093 a1115 1
3094 i, Msgs[i].m_size, Msgs[i].m_id);
3095 d1123 1
3096 a1123 1
3097 if (!(Msgs[i].m_flags & MDELE))
3098 d1127 25
3099 d1153 1
3100 a1153 1
3101 i, Msgs[i].m_size, Msgs[i].m_id);
3102 d1155 1
3103 d1251 8
3104 d1306 2
3105 d1326 2
3106 d1522 18
3107 d1603 4
3108 a1606 1
3109 if ((dmsgs == 0 && rmsgs == 0) || (Msgs[0].m_flags & MREAD))
3110 a1608 1
3111 if(debug)padvise(NULLCP,LOG_DEBUG,"XXX: rmsgs=%d",rmsgs);
3112 d1687 24
3113 d1834 8
3114 a1842 2
3115 if (debug)
3116 padvise (NULLCP, LOG_DEBUG, "<--- %s", s);
3117 a1953 2
3118 long ld1,
3119 ld2;
3120 d1961 6
3121 a1978 4
3122
3123 /* get sizes of msg delimiters */
3124 ld1 = (long) strlen (mmdlm1);
3125 ld2 = (long) strlen (mmdlm2);
3126 @
3127
3128
3129 1.17
3130 log
3131 @kerberos
3132 @
3133 text
3134 @d3 1
3135 a3 1
3136 static char ident[]="@@(#)$Id: popser.c,v 1.16 1990/11/16 14:56:38 mh Exp jromine $";
3137 d196 5
3138 @
3139
3140
3141 1.16
3142 log
3143 @jlr
3144 @
3145 text
3146 @d3 1
3147 a3 1
3148 static char ident[]="@@(#)$Id: popser.c,v 1.15 90/11/16 14:38:00 mh Exp Locker: mh $";
3149 d18 3
3150 d284 9
3151 d298 1
3152 d310 5
3153 a315 1
3154 hostname = rhost;
3155 d317 1
3156 d325 10
3157 d391 4
3158 a394 1
3159
3160 d396 8
3161 d421 20
3162 d508 1
3163 d593 1
3164 a593 1
3165 *cp = NULL;
3166 d1008 1
3167 a1008 1
3168 *cp = NULL;
3169 d1097 1
3170 a1097 1
3171 *cp = NULL;
3172 d1103 1
3173 a1103 1
3174 if (*buffer == NULL)
3175 d1466 2
3176 a1467 2
3177 *bp++ = NULL;
3178 if (*bp == NULL) {
3179 d1478 1
3180 a1478 1
3181 if (*bp != NULL) {
3182 d1482 1
3183 a1482 1
3184 if (*vec[0] == NULL) {
3185 d1594 1
3186 a1594 1
3187 *p++ = NULL;
3188 @
3189
3190
3191 1.15
3192 log
3193 @make popser speak POP2 as well as POP3 -- a major win!
3194
3195 jlr
3196 @
3197 text
3198 @d3 1
3199 a3 1
3200 static char ident[]="@@(#)$Id: popser.c,v 1.14 90/11/05 16:04:57 mh Exp Locker: mh $";
3201 a4 2
3202
3203 #define POP2
3204 @
3205
3206
3207 1.14
3208 log
3209 @see comments in code
3210 @
3211 text
3212 @d3 1
3213 a3 1
3214 static char ident[]="@@(#)$Id: popser.c,v 1.13 90/04/09 09:45:18 sources Exp Locker: mh $";
3215 d6 2
3216 d45 1
3217 d49 5
3218 d70 3
3219 a100 1
3220
3221 d103 18
3222 d128 3
3223 d351 9
3224 d614 8
3225 d624 1
3226 a624 1
3227 nmsgs, nmsgs != 1 ? "s" : NULL, Msgs[0].m_size);
3228 d810 74
3229 d904 1
3230 a904 1
3231 nmsgs - dmsgs, nmsgs - dmsgs != 1 ? "s" : NULL,
3232 d929 5
3233 d940 5
3234 d953 3
3235 d962 3
3236 d1294 1
3237 a1294 1
3238 server, n - d, n - d != 1 ? "s" : NULL, Msgs[0].m_size);
3239 d1461 21
3240 a1481 4
3241 bp += strlen (sprintf (bp, "%s%s", code == OK ? "+OK" : "-ERR",
3242 fmt ? " " : NULL));
3243 if (fmt)
3244 bp += strlen (sprintf (bp, fmt, a, b, c, d));
3245 @
3246
3247
3248 1.13
3249 log
3250 @POPSERVICE define
3251 @
3252 text
3253 @d3 1
3254 a3 1
3255 static char ident[]="@@(#)$Id: popser.c,v 1.12 90/04/05 16:07:32 sources Exp Locker: sources $";
3256 d169 2
3257 d174 4
3258 d691 1
3259 a691 1
3260 if ((i = pmbx_read (dp, pos, &rp, debug)) <= 0)
3261 d1466 9
3262 d1476 5
3263 d1482 1
3264 d1887 1
3265 @
3266
3267
3268 1.12
3269 log
3270 @Id
3271 @
3272 text
3273 @d3 1
3274 a3 1
3275 static char ident[]="@@(#)$Id:$";
3276 d31 4
3277 d363 1
3278 a363 1
3279 pw && pw -> pw_uid == 0, "pop", "tcp", NULL);
3280 d384 1
3281 a384 1
3282 0, "pop", "tcp", NULL);
3283 d400 1
3284 a400 1
3285 "pop", "tcp", NULL)
3286 @
3287
3288
3289 1.11
3290 log
3291 @*** empty log message ***
3292 @
3293 text
3294 @d2 3
3295 @
3296
3297
3298 1.10
3299 log
3300 @add ID
3301 @
3302 text
3303 @a1 3
3304 #ifndef lint
3305 static char ident[] = "@@(#)$Id:$";
3306 #endif lint
3307 d42 4
3308 d162 4
3309 d1459 1
3310 a1459 1
3311 int pmbx_read (fp, pos, drops, noisy)
3312 d1597 2
3313 d1600 2
3314 a1601 1
3315 p_ishead(buffer)
3316 a1608 3
3317 char * p_copyin();
3318 char * p_copy();
3319
3320 d1647 1
3321 a1647 1
3322 p_parse(line, hl, pbuf)
3323 d1692 1
3324 a1692 1
3325 char *
3326 d1715 1
3327 a1715 1
3328 char *
3329 d1747 1
3330 a1747 1
3331 char *
3332 d1769 3
3333 a1771 2
3334 /*example T h u S e p 2 9 1 5 : 2 0 : 1 9 1 9 8 8 */
3335 char p_ctypes[] = {U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0};
3336 d1773 3
3337 a1775 2
3338 /* example T h u S e p 2 9 1 5 : 2 0 : 1 9 M S T 1 9 8 8 */
3339 char p_tmztyp[] = {U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,U,U,U,S,D,D,D,D,0};
3340 d1777 1
3341 a1777 1
3342 p_isdate(date)
3343 d1794 1
3344 a1794 1
3345 p_cmatch(str, temp)
3346 d1846 1
3347 a1846 1
3348 any(ch, str)
3349 a1858 1
3350
3351 @
3352
3353
3354 1.9
3355 log
3356 @add ID
3357 @
3358 text
3359 @d3 1
3360 a3 1
3361 static char ident[] = "@@(#)$Id:";
3362 @
3363
3364
3365 1.8
3366 log
3367 @contrib'd fixes to make popd read UUCP as well as MMDF maildrops.
3368 @
3369 text
3370 @d2 3
3371 @
3372
3373
3374 1.7
3375 log
3376 @make mbx_size be pmbx_size for ANSI C
3377 @
3378 text
3379 @d670 1
3380 a670 1
3381 if ((i = mbx_read (dp, pos, &rp, debug)) <= 0)
3382 d1197 4
3383 a1200 1
3384 return respond (NOTOK, "unable to create temporary file");
3385 d1391 459
3386 @
3387
3388
3389 1.6
3390 log
3391 @ANSI Compilance
3392 @
3393 text
3394 @d158 1
3395 a158 1
3396 static int setup(), setupaux(), read_map(), read_file(), mbx_size();
3397 d605 1
3398 a605 1
3399 Msgs[i].m_size = mbx_size (i);
3400 d716 1
3401 a716 1
3402 static int mbx_size (m)
3403 @
3404
3405
3406 1.5
3407 log
3408 @SHADOW
3409 @
3410 text
3411 @d41 1
3412 a41 1
3413 int user (), pass ();
3414 d43 1
3415 a43 1
3416 int rpop ();
3417 d45 2
3418 a46 2
3419 int status (), list (), retrieve (), delete (), reset ();
3420 int top (), last ();
3421 d50 1
3422 a50 1
3423 int quit ();
3424 d85 1
3425 a85 1
3426 struct vector *getvector ();
3427 d148 1
3428 a148 1
3429 int pipeser ();
3430 d158 3
3431 @
3432
3433
3434 1.4
3435 log
3436 @*** empty log message ***
3437 @
3438 text
3439 @d18 3
3440 d313 3
3441 d335 1
3442 d338 5
3443 @
3444
3445
3446 1.3
3447 log
3448 @*** empty log message ***
3449 @
3450 text
3451 @d1307 1
3452 a1307 1
3453 cp = sprintf (buffer + TRMLEN, fmt, a, b, c, d);
3454 @
3455
3456
3457 1.2
3458 log
3459 @SYS5 fix
3460 @
3461 text
3462 @d12 1
3463 a12 1
3464 #include <syslog.h>
3465 @
3466
3467
3468 1.1
3469 log
3470 @Initial revision
3471 @
3472 text
3473 @d15 3
3474 d503 1
3475 d505 1
3476 d512 1
3477 d514 1
3478 d518 1
3479 d520 1
3480 d1168 1
3481 d1170 4
3482 @