Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / slocal.c,v
1 head    1.25;
2 access;
3 symbols;
4 locks
5         shettich:1.25; strict;
6 comment @ * @;
7
8
9 1.25
10 date    95.12.07.00.01.25;      author jromine; state Exp;
11 branches;
12 next    1.24;
13
14 1.24
15 date    93.08.25.17.28.16;      author jromine; state Exp;
16 branches;
17 next    1.23;
18
19 1.23
20 date    92.12.15.00.20.22;      author jromine; state Exp;
21 branches;
22 next    1.22;
23
24 1.22
25 date    92.12.11.19.00.32;      author jromine; state Exp;
26 branches;
27 next    1.21;
28
29 1.21
30 date    92.12.11.18.26.10;      author jromine; state Exp;
31 branches;
32 next    1.20;
33
34 1.20
35 date    92.11.25.04.20.30;      author jromine; state Exp;
36 branches;
37 next    1.19;
38
39 1.19
40 date    92.11.11.23.10.37;      author jromine; state Exp;
41 branches;
42 next    1.18;
43
44 1.18
45 date    92.11.04.01.03.18;      author jromine; state Exp;
46 branches;
47 next    1.17;
48
49 1.17
50 date    92.10.27.16.43.48;      author jromine; state Exp;
51 branches;
52 next    1.16;
53
54 1.16
55 date    92.10.26.16.47.04;      author jromine; state Exp;
56 branches;
57 next    1.15;
58
59 1.15
60 date    92.02.15.00.53.47;      author jromine; state Exp;
61 branches;
62 next    1.14;
63
64 1.14
65 date    92.02.12.17.18.19;      author jromine; state Exp;
66 branches;
67 next    1.13;
68
69 1.13
70 date    92.02.03.18.12.31;      author jromine; state Exp;
71 branches;
72 next    1.12;
73
74 1.12
75 date    92.02.03.17.57.22;      author jromine; state Exp;
76 branches;
77 next    1.11;
78
79 1.11
80 date    92.01.31.22.27.43;      author jromine; state Exp;
81 branches;
82 next    1.10;
83
84 1.10
85 date    92.01.30.00.06.00;      author jromine; state Exp;
86 branches;
87 next    1.9;
88
89 1.9
90 date    91.01.10.14.39.00;      author mh;      state Exp;
91 branches;
92 next    1.8;
93
94 1.8
95 date    90.04.05.14.58.46;      author sources; state Exp;
96 branches;
97 next    1.7;
98
99 1.7
100 date    90.03.21.16.22.43;      author sources; state Exp;
101 branches;
102 next    1.6;
103
104 1.6
105 date    90.03.19.15.41.29;      author sources; state Exp;
106 branches;
107 next    1.5;
108
109 1.5
110 date    90.03.19.15.37.13;      author sources; state Exp;
111 branches;
112 next    1.4;
113
114 1.4
115 date    90.02.06.13.31.25;      author sources; state Exp;
116 branches;
117 next    1.3;
118
119 1.3
120 date    90.02.05.15.02.49;      author sources; state Exp;
121 branches;
122 next    1.2;
123
124 1.2
125 date    89.11.17.16.13.22;      author sources; state Exp;
126 branches;
127 next    1.1;
128
129 1.1
130 date    89.11.17.16.10.30;      author sources; state Exp;
131 branches;
132 next    ;
133
134
135 desc
136 @@
137
138
139 1.25
140 log
141 @null ptr fix
142 @
143 text
144 @/* slocal.c - MH style mailer to write to a local user's mailbox */
145 #ifndef lint
146 static char ident[] = "@@(#)$Id: slocal.c,v 1.24 1993/08/25 17:28:16 jromine Exp jromine $";
147 #endif  /* lint */
148
149 /* This program implements mail delivery in the MH/MMDF style.
150
151    Under SendMail, users should add the line
152
153         "| /usr/local/lib/mh/slocal"
154
155    to their $HOME/.forward file.
156
157    Under MMDF-I, users should (symbolically) link /usr/local/lib/mh/slocal
158    to $HOME/bin/rcvmail.
159
160    Under stand-alone MH, post will automatically run this during local
161    delivery.
162
163    This program should be used ONLY if you have "mts sendmail" or "mts mh"
164    or "mts mmdf1" set in your MH configuration.
165  */
166
167 /* \f */
168
169 #include "../h/mh.h"
170 #include "../h/dropsbr.h"
171 #include "../h/rcvmail.h"
172 #include "../zotnet/tws.h"
173 #include "../zotnet/mts.h"
174 #include <pwd.h>
175 #include <signal.h>
176 #ifndef V7
177 #ifndef NOIOCTLH
178 #include <sys/ioctl.h>
179 #endif  /* NOIOCTLH */
180 #endif  /* not V7 */
181 #include <sys/stat.h>
182 #include <utmp.h>
183 #ifdef LOCALE
184 #include        <locale.h>
185 #endif
186
187
188 #ifdef  MSGID
189
190 #undef  DBM             /* used by ndbm.h */
191 #include <ndbm.h>
192 #include <stdio.h>
193 #include <sys/types.h>
194 #include <sys/file.h>
195 #ifdef  SYS5
196 #include <fcntl.h>
197 #endif
198 #ifdef UNISTD
199 #include <unistd.h>
200 #endif
201 #if defined(LOCKF) && !defined(F_ULOCK)
202 #include <sys/fcntl.h>
203 #endif  /* LOCKF */
204
205 #endif
206
207
208 #define NVEC    100
209
210 /* \f */
211
212 static struct swit switches[] = {
213 #define ADDRSW  0
214     "addr address", 0,
215 #define USERSW  1
216     "user name", 0,
217 #define FILESW  2
218     "file file", 0,
219 #define SENDSW  3
220     "sender address", 0,
221 #define MBOXSW  4
222     "mailbox file", 0,
223 #define HOMESW  5
224     "home directory", -4,
225 #define INFOSW  6
226     "info data", 0,
227
228 #define MAILSW  7
229     "maildelivery file", 0,
230
231 #define VERBSW  8
232     "verbose", 0,
233 #define NVERBSW 9
234     "noverbose", 0,
235
236 #define DEBUGSW 10
237     "debug", 0,
238
239 #define HELPSW  11
240     "help", 4,
241
242     NULL, 0
243 };
244
245 /* \f */
246
247 static int  debug = 0;
248 static int  globbed = 0;
249 static int  parsed = 0;
250 static int  utmped = 0;
251 static int  verbose = 0;
252
253 static char *addr = NULLCP;
254 static char *user = NULLCP;
255 static char *info = NULLCP;
256 static char *file = NULLCP;
257 static char *sender = NULLCP;
258 static char *unixfrom = NULLCP;
259 static char *mbox = NULLCP;
260 static char *home = NULLCP;
261
262
263 static struct passwd *pw;
264
265
266 static char ddate[BUFSIZ];
267
268 struct tws *now;
269
270
271 static jmp_buf myctx;
272
273 /* \f */
274
275 struct pair {
276     char   *p_name;
277     char   *p_value;
278
279     char    p_flags;
280 #define P_NIL   0x00
281 #define P_ADR   0x01
282 #define P_HID   0x02
283 #define P_CHK   0x04
284 };
285
286 static struct pair *lookup ();
287
288
289 static struct pair  hdrs[NVEC + 1] = {
290     "source", NULL, P_HID,
291     "addr", NULL, P_HID,
292
293     "Return-Path", NULL, P_ADR,
294     "Reply-To", NULL, P_ADR,
295     "From", NULL, P_ADR,
296     "Sender", NULL, P_ADR,
297     "To", NULL, P_ADR,
298     "cc", NULL, P_ADR,
299     "Resent-Reply-To", NULL, P_ADR,
300     "Resent-From", NULL, P_ADR,
301     "Resent-Sender", NULL, P_ADR,
302     "Resent-To", NULL, P_ADR,
303     "Resent-cc", NULL, P_ADR,
304
305     NULL
306 };
307
308
309 static struct pair  vars[] = {
310     "sender", NULL, P_NIL,
311     "address", NULL, P_NIL,
312     "size", NULL, P_NIL,
313     "reply-to", NULL, P_CHK,
314     "info", NULL, P_NIL,
315
316     NULL
317 };
318
319 /* \f */
320
321 extern char **environ;
322
323 static void     adorn ();
324 static TYPESIG  alrmser ();
325
326
327 off_t    lseek ();
328 #ifndef __STDC__
329 #ifdef  SYS5
330 struct passwd *getpwnam ();
331 #endif  /* SYS5 */
332 #endif
333 static int      localmail(), usr_delivery(), split(), parse(), logged_in();
334 static int      timely(), usr_file(), usr_pipe(), copyfile();
335 static expand(), glob(), copyinfo();
336
337 /* \f */
338
339 /* ARGSUSED */
340
341 main (argc, argv, envp)
342 int     argc;
343 char  **argv,
344       **envp;
345 {
346     int     fd;
347     FILE   *fp    = stdin;
348     char   *cp,
349            *mdlvr = NULL,
350             buf[100],
351             from[BUFSIZ],
352             mailbox[BUFSIZ],
353             tmpfil[BUFSIZ],
354           **argp = argv + 1;
355
356 #ifdef LOCALE
357         setlocale(LC_ALL, "");
358 #endif
359     invo_name = r1bindex (*argv, '/');
360     m_foil (NULLCP);
361     mts_init (invo_name);
362
363 /* \f */
364
365     while (cp = *argp++) {
366         if (*cp == '-')
367             switch (smatch (++cp, switches)) {
368                 case AMBIGSW: 
369                     ambigsw (cp, switches);
370                     done (1);
371                 case UNKWNSW: 
372                     adios (NULLCP, "-%s unknown", cp);
373                 case HELPSW: 
374                     (void) sprintf (buf, "%s [switches] [address info sender]",
375                             invo_name);
376                     help (buf, switches);
377                     done (1);
378
379                 case ADDRSW: 
380                     if (!(addr = *argp++))/* allow -xyz arguments */
381                         adios (NULLCP, "missing argument to %s", argp[-2]);
382                     continue;
383                 case INFOSW: 
384                     if (!(info = *argp++))/* allow -xyz arguments */
385                         adios (NULLCP, "missing argument to %s", argp[-2]);
386                     continue;
387                 case USERSW: 
388                     if (!(user = *argp++))/* allow -xyz arguments */
389                         adios (NULLCP, "missing argument to %s", argp[-2]);
390                     continue;
391                 case FILESW: 
392                     if (!(file = *argp++) || *file == '-')
393                         adios (NULLCP, "missing argument to %s", argp[-2]);
394                     continue;
395                 case SENDSW: 
396                     if (!(sender = *argp++))/* allow -xyz arguments */
397                         adios (NULLCP, "missing argument to %s", argp[-2]);
398                     continue;
399                 case MBOXSW: 
400                     if (!(mbox = *argp++) || *mbox == '-')
401                         adios (NULLCP, "missing argument to %s", argp[-2]);
402                     continue;
403                 case HOMESW: 
404                     if (!(home = *argp++) || *home == '-')
405                         adios (NULLCP, "missing argument to %s", argp[-2]);
406                     continue;
407
408                 case MAILSW: 
409                     if (!(cp = *argp++) || *cp == '-')
410                         adios (NULLCP, "missing argument to %s", argp[-2]);
411                     if (mdlvr)
412                         adios (NULLCP, "only one maildelivery file at a time!");
413                     mdlvr = cp;
414                     continue;
415
416                 case VERBSW: 
417                     verbose++;
418                     continue;
419                 case NVERBSW: 
420                     verbose = 0;
421                     continue;
422
423                 case DEBUGSW: 
424                     debug++;
425                     continue;
426             }
427
428         switch (argp - (argv + 1)) {
429             case 1: 
430                 addr = cp;
431                 break;
432
433             case 2: 
434                 info = cp;
435                 break;
436
437             case 3: 
438                 sender = cp;
439                 break;
440         }
441     }
442
443 /* \f */
444
445     if (addr == NULL)
446         addr = getusr ();
447     if (user == NULL)
448         user = (cp = index (addr, '.')) ? ++cp : addr;
449     if ((pw = getpwnam (user)) == NULL)
450         adios (NULLCP, "no such local user as %s", user);
451
452     if (chdir (pw -> pw_dir) == NOTOK)
453         (void) chdir ("/");
454     (void) umask (0077);
455
456     if (geteuid () == 0) {
457 #ifdef  BSD41A
458         (void) inigrp (pw -> pw_name, pw -> pw_gid);
459 #endif  /* BSD41A */
460         (void) setgid (pw -> pw_gid);
461 #ifdef  BSD42
462         (void) initgroups (pw -> pw_name, pw -> pw_gid);
463 #endif  /* BSD42 */
464         (void) setuid (pw -> pw_uid);
465     }
466     
467     if (info == NULL)
468         info = "";
469
470     setbuf (stdin, NULLCP);
471
472     if (file == NULL) {
473         if ((fd = copyfile (fileno (stdin), file = tmpfil, 1)) == NOTOK)
474             adios (NULLCP, "unable to create temporary file");
475         if (debug)
476             fprintf (stderr, "temporary file \"%s\" selected\n", tmpfil);
477         else
478             (void) unlink (tmpfil);
479         if ((fp = fdopen (fd, "r+")) == NULL)
480             adios (NULLCP, "unable to access temporary file");
481     }
482     else
483         fd = fileno (stdin);
484
485     from[0] = 0;
486     if (sender == NULL)
487         copyinfo (fp, from);
488
489
490     if (mbox == NULL) {
491         (void) sprintf (mailbox, "%s/%s",
492                 mmdfldir[0] ? mmdfldir : pw -> pw_dir,
493                 mmdflfil[0] ? mmdflfil : pw -> pw_name);
494         mbox = mailbox;
495     }
496     if (home == NULL)
497         home = pw -> pw_dir;
498
499     if ((now = dtwstime ()) == NULL)
500         adios (NULLCP, "unable to ascertain local time");
501     (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ());
502
503     if (debug) {
504         fprintf (stderr, "addr=\"%s\" user=\"%s\" info=\"%s\" file=\"%s\"\n",
505                 addr, user, info, file);
506         fprintf (stderr, "sender=\"%s\" mbox=\"%s\" home=\"%s\" from=\"%s\"\n",
507                 sender, mbox, home, from);
508         fprintf (stderr, "ddate=\"%s\" now=%02d:%02d\n",
509                 ddate, now -> tw_hour, now -> tw_min);
510     }
511
512     done (localmail (fd, from, mdlvr) != NOTOK ? RCV_MOK : RCV_MBX);
513 }
514
515 /* \f */
516
517 static int  localmail (fd, from, mdlvr)
518 int     fd;
519 char   *from,
520        *mdlvr;
521 {
522 #ifdef  MSGID
523     struct stat st;
524
525     if (stat (".maildelivery.pag", &st) != NOTOK
526             && check_msgid (fd, ".maildelivery") == DONE)
527         return OK;
528 #endif
529
530     if (usr_delivery (fd, mdlvr ? mdlvr : ".maildelivery", 0, from) != NOTOK)
531         return OK;
532
533     if (usr_delivery (fd, maildelivery, 1, from) != NOTOK)
534         return OK;
535
536 #ifdef  notdef
537     if (verbose)
538         printf ("(invoking hook)\n");
539     if (usr_hook (fd, mbox) != NOTOK)
540         return OK;
541 #endif  /* notdef */
542
543     if (verbose)
544         printf ("(trying normal delivery)\n");
545     return usr_file (fd, mbox, from);
546 }
547
548 /* \f */
549
550 #define matches(a,b)    (stringdex (b, a) >= 0)
551
552 static int  usr_delivery (fd, delivery, su, from)
553 int     fd,
554         su;
555 char   *delivery,
556        *from;
557 {
558     int     i,
559             accept,
560             status,
561             won,
562             vecp,
563             next;
564     register char  *cp,
565                    *action,
566                    *field,
567                    *pattern,
568                    *string;
569     char    buffer[BUFSIZ],
570             tmpbuf[BUFSIZ],
571            *vec[NVEC];
572     struct stat st;
573     register struct pair   *p;
574     register FILE  *fp;
575
576     if ((fp = fopen (delivery, "r")) == NULL)
577         return NOTOK;
578     if (fstat (fileno (fp), &st) == NOTOK
579             || (st.st_uid != 0 && (su || st.st_uid != pw -> pw_uid))
580             || st.st_mode & 0022) {
581         if (verbose) {
582             printf ("%s: ownership/modes bad (%d, %d,%d,0%o)\n",
583                     delivery, su, pw -> pw_uid, st.st_uid, st.st_mode);
584             (void) fflush (stdout);
585         }
586         return NOTOK;
587     }
588
589     won = 0;
590     next = 1;
591     while (fgets (buffer, sizeof buffer, fp) != NULL) {
592         if (*buffer == '#')
593             continue;
594         if (cp = index (buffer, '\n'))
595             *cp = 0;
596         if ((vecp = split (buffer, vec)) < 5)
597             continue;
598         if (debug)
599             for (i = 0; vec[i]; i++)
600                 fprintf (stderr, "vec[%d]: \"%s\"\n", i, vec[i]);
601
602         field = vec[0];
603         pattern = vec[1];
604         action = vec[2];
605
606         switch (vec[3][0]) {
607             case 'N':
608             case 'n':
609                 if (! next)
610                         continue;  /* if previous condition failed, don't
611                                       do this - else fall through */
612
613             case '?': 
614                 if (won)
615                     continue;   /* else fall */
616             case 'A': 
617             case 'a': 
618                 accept = 1;
619                 break;
620
621             case 'R': 
622             case 'r': 
623             default: 
624                 accept = 0;
625                 break;
626         }
627
628         string = vec[4];
629
630         if (vecp > 5) {
631             if (uleq (vec[5], "select")) {
632                 if (logged_in () != NOTOK)
633                     continue;
634                 if (vecp > 7 && timely (vec[6], vec[7]) == NOTOK)
635                     continue;
636             }
637         }
638
639         switch (*field) {
640             case '*': 
641                 break;
642
643             case 'd': 
644                 if (uleq (field, "default")) {
645                     if (won)
646                         continue;
647                     break;
648                 }               /* else fall */
649
650             default: 
651                 if (!parsed && parse (fd) == NOTOK) {
652                     (void) fclose (fp);
653                     return NOTOK;
654                 }
655                 if ((p = lookup (hdrs, field)) == NULL
656                         || (p->p_value == NULL)                 /* XXX */
657                         || !matches (p -> p_value, pattern)) {
658                         next = 0;
659                         continue;
660                 }
661                 else
662                     next = 1;
663                 break;
664         }
665
666         switch (*action) {
667             case 'q':
668                 if (!uleq (action, "qpipe"))
669                     continue;   /* else fall */
670             case '^':
671                 expand (tmpbuf, string, fd);
672                 if (split (tmpbuf, vec) < 1)
673                     continue;
674                 status = usr_pipe (fd, tmpbuf, vec[0], vec);
675                 break;
676
677             case 'p': 
678                 if (!uleq (action, "pipe"))
679                     continue;   /* else fall */
680             case '|': 
681                 vec[2] = "sh";
682                 vec[3] = "-c";
683                 expand (tmpbuf, string, fd);
684                 vec[4] = tmpbuf;
685                 vec[5] = NULL;
686                 status = usr_pipe (fd, tmpbuf, "/bin/sh", vec + 2);
687                 break;
688
689             case 'f': 
690                 if (!uleq (action, "file"))
691                     continue;   /* else fall */
692             case '>': 
693 #ifdef  RPATHS
694                 status = usr_file (fd, string,  from);  /* UUCP format? */
695 #else
696                 status = usr_file (fd, string,  NULLCP);
697 #endif
698                 break;
699
700             case 'm':
701                 if (!uleq (action, "mbox"))
702                     continue;
703                 status = usr_file (fd, string,  NULLCP);
704                 break;
705
706             case 'd': 
707                 if (!uleq (action, "destroy"))
708                     continue;
709                 status = OK;
710                 break;
711         }
712
713         if (accept && status == OK)
714             won++;
715     }
716
717     (void) fclose (fp);
718     return (won ? OK : NOTOK);
719 }
720
721 /* \f */
722
723 #define QUOTE   '\\'
724
725 static int  split (cp, vec)
726 char   *cp,
727       **vec;
728 {
729     register int    i;
730     register char  *s;
731
732     for (i = 0, s = cp; i <= NVEC;) {
733         vec[i] = NULL;
734         while (isspace (*s) || *s == ',')
735             *s++ = 0;
736         if (*s == 0)
737             break;
738
739         if (*s == '"') {
740             for (vec[i++] = ++s; *s != 0 && *s != '"'; s++)
741                 if (*s == QUOTE) {
742                     if (*++s == '"')
743                         (void) strcpy (s - 1, s);
744                     s--;
745                 }
746             if (*s == '"')
747                 *s++ = 0;
748             continue;
749         }
750         if (*s == QUOTE && *++s != '"')
751             s--;
752         vec[i++] = s++;
753
754         while (*s != 0 && !isspace (*s) && *s != ',')
755             s++;
756     }
757     vec[i] = NULL;
758
759     return i;
760 }
761
762 /* \f */
763
764 static int  parse (fd)
765 register int    fd;
766 {
767     register int    i,
768                     state;
769     int     fd1;
770     register char  *cp,
771                    *dp,
772                    *lp;
773     char    name[NAMESZ],
774             field[BUFSIZ];
775     register struct pair   *p,
776                            *q;
777     register FILE  *in;
778
779     if (parsed++)
780         return OK;
781
782     if ((fd1 = dup (fd)) == NOTOK)
783         return NOTOK;
784     if ((in = fdopen (fd1, "r")) == NULL) {
785         (void) close (fd1);
786         return NOTOK;
787     }
788     rewind (in);
789
790     if (p = lookup (hdrs, "source"))
791         p -> p_value = getcpy (sender);
792     if (p = lookup (hdrs, "addr"))
793         p -> p_value = getcpy (addr);
794
795     for (i = 0, state = FLD;;) {
796         switch (state = m_getfld (state, name, field, sizeof field, in)) {
797             case FLD: 
798             case FLDEOF: 
799             case FLDPLUS: 
800                 lp = add (field, NULLCP);
801                 while (state == FLDPLUS) {
802                     state = m_getfld (state, name, field, sizeof field, in);
803                     lp = add (field, lp);
804                 }
805                 for (p = hdrs; p -> p_name; p++)
806                     if (uleq (p -> p_name, name)) {
807                         if (!(p -> p_flags & P_HID)) {
808                             if (cp = p -> p_value)
809                                 if (p -> p_flags & P_ADR) {
810                                     dp = cp + strlen (cp) - 1;
811                                     if (*dp == '\n')
812                                         *dp = 0;
813                                     cp = add (",\n\t", cp);
814                                 }
815                                 else
816                                     cp = add ("\t", cp);
817                             p -> p_value = add (lp, cp);
818                         }
819                         free (lp);
820                         break;
821                     }
822                 if (p -> p_name == NULL && i < NVEC) {
823                     p -> p_name = getcpy (name);
824                     p -> p_value = lp;
825                     p -> p_flags = P_NIL;
826                     p++, i++;
827                     p -> p_name = NULL;
828                 }
829                 if (state != FLDEOF)
830                     continue;
831                 break;
832
833             case BODY: 
834             case BODYEOF: 
835             case FILEEOF: 
836                 break;
837
838             case LENERR: 
839             case FMTERR: 
840                 advise (NULLCP, "format error in message");
841                 break;
842
843             default: 
844                 advise (NULLCP, "internal error");
845                 (void) fclose (in);
846                 return NOTOK;
847         }
848         break;
849     }
850     (void) fclose (in);
851
852     if (p = lookup (vars, "reply-to")) {
853         if ((q = lookup (hdrs, "reply-to")) == NULL || q -> p_value == NULL)
854             q = lookup (hdrs, "from");
855         p -> p_value = getcpy (q ? q -> p_value : "");
856         p -> p_flags &= ~P_CHK;
857         if (debug)
858             fprintf (stderr, "vars[%d]: name=\"%s\" value=\"%s\"\n",
859                     p - vars, p -> p_name, p -> p_value);
860     }
861 #define empty(s)        ((s) ? (s) : "")
862     if (debug)
863         for (p = hdrs; p -> p_name; p++)
864             fprintf (stderr, "hdrs[%d]: name=\"%s\" value=\"%s\"\n",
865                 p - hdrs, p -> p_name, empty(p -> p_value));
866 #undef  empty
867
868     return OK;
869 }
870
871 /* \f */
872
873 #define LPAREN  '('
874 #define RPAREN  ')'
875
876 static  expand (s1, s2, fd)
877 register char  *s1,
878                *s2;
879 int     fd;
880 {
881     register char   c,
882                    *cp;
883     register struct pair   *p;
884
885     if (!globbed)
886         glob (fd);
887
888     while (c = *s2++)
889         if (c != '$' || *s2 != LPAREN)
890             *s1++ = c;
891         else {
892             for (cp = ++s2; *s2 && *s2 != RPAREN; s2++)
893                 continue;
894             if (*s2 != RPAREN) {
895                 s2 = --cp;
896                 continue;
897             }
898             *s2++ = 0;
899             if (p = lookup (vars, cp)) {
900                 if (!parsed && (p -> p_flags & P_CHK))
901                     (void) parse (fd);
902
903                 (void) strcpy (s1, p -> p_value);
904                 s1 += strlen (s1);
905             }
906         }
907     *s1 = 0;
908 }
909
910 /* \f */
911
912 static  glob (fd)
913 register int  fd;
914 {
915     char buffer[BUFSIZ];
916     struct stat st;
917     register struct pair   *p;
918
919     if (globbed++)
920         return;
921
922     if (p = lookup (vars, "sender"))
923         p -> p_value = getcpy (sender);
924     if (p = lookup (vars, "address"))
925         p -> p_value = getcpy (addr);
926     if (p = lookup (vars, "size")) {
927         (void) sprintf (buffer, "%d",
928                 fstat (fd, &st) != NOTOK ? (int) st.st_size : 0);
929         p -> p_value = getcpy (buffer);
930     }
931     if (p = lookup (vars, "info"))
932         p -> p_value = getcpy (info);
933
934     if (debug)
935         for (p = vars; p -> p_name; p++)
936             fprintf (stderr, "vars[%d]: name=\"%s\" value=\"%s\"\n",
937                     p - vars, p -> p_name, p -> p_value);
938 }
939
940 /* \f */
941
942 static struct pair *lookup (pairs, key)
943 register struct pair   *pairs;
944 register char  *key;
945 {
946     register char  *cp;
947
948     for (; cp = pairs -> p_name; pairs++)
949         if (uleq (cp, key))
950             return pairs;
951
952     return NULL;
953 }
954
955 /* \f */
956
957 static int  logged_in () {
958     struct utmp ut;
959     register FILE  *uf;
960
961     if (utmped)
962         return utmped;
963
964     if ((uf = fopen ("/etc/utmp", "r")) == NULL)
965         return NOTOK;
966
967     while (fread ((char *) &ut, sizeof ut, 1, uf) == 1)
968         if (ut.ut_name[0] != 0
969                 && strncmp (user, ut.ut_name, sizeof ut.ut_name) == 0) {
970             if (debug)
971                 continue;
972             (void) fclose (uf);
973             return (utmped = DONE);
974         }
975
976     (void) fclose (uf);
977     return (utmped = NOTOK);
978 }
979
980
981 static int  timely (t1, t2)
982 char   *t1,
983        *t2;
984 {
985 #define check(t,a,b)            if (t < a || t > b) return NOTOK
986 #define cmpar(h1,m1,h2,m2)      if (h1 < h2 || (h1 == h2 && m1 < m2)) return OK
987
988     int     t1hours,
989             t1mins,
990             t2hours,
991             t2mins;
992
993     if (sscanf (t1, "%d:%d", &t1hours, &t1mins) != 2)
994         return NOTOK;
995     check (t1hours, 0, 23);
996     check (t1mins, 0, 59);
997
998     if (sscanf (t2, "%d:%d", &t2hours, &t2mins) != 2)
999         return NOTOK;
1000     check (t2hours, 0, 23);
1001     check (t2mins, 0, 59);
1002
1003     cmpar (now -> tw_hour, now -> tw_min, t1hours, t1mins);
1004     cmpar (t2hours, t2mins, now -> tw_hour, now -> tw_min);
1005
1006     return NOTOK;
1007 }
1008
1009 /* \f */
1010
1011 static int  usr_file (fd, mailbox, from)
1012 int     fd;
1013 char   *mailbox,
1014        *from;
1015 {
1016     int     md,
1017             mapping;
1018     register char  *bp;
1019     char    buffer[BUFSIZ];
1020
1021     if (verbose)
1022         printf ("\tdelivering to file \"%s\"", mailbox);
1023     if (from && *from) {
1024         (void) mbx_uucp ();
1025         if (verbose)
1026             printf (" (uucp style)");
1027         (void) sprintf (buffer, "%s%s", from, ddate);
1028         bp = buffer;
1029         mapping = 0;
1030     }
1031     else {
1032         bp = ddate;
1033         mapping = 1;
1034     }
1035     if (verbose)
1036         (void) fflush (stdout);
1037
1038     if ((md = mbx_open (mailbox, pw -> pw_uid, pw -> pw_gid, m_gmprot ()))
1039             == NOTOK) {
1040         adorn ("", "unable to open:");
1041         return NOTOK;
1042     }
1043
1044     (void) lseek (fd, (off_t)0, 0);
1045     if (mbx_copy (mailbox, md, fd, mapping, bp, verbose) == NOTOK) {
1046         adorn ("", "error writing to:");
1047         return NOTOK;
1048     }
1049
1050     (void) mbx_close (mailbox, md);
1051     if (verbose) {
1052         printf (", done.\n");
1053         (void) fflush (stdout);
1054     }
1055     return OK;
1056 }
1057
1058 /* \f */
1059
1060 #ifdef  notdef
1061 static int  usr_hook (fd, mailbox)
1062 int     fd;
1063 char   *mailbox;
1064 {
1065     int     i,
1066             vecp;
1067     char    receive[BUFSIZ],
1068             tmpfil[BUFSIZ],
1069            *vec[NVEC];
1070
1071     if ((fd = copyfile (fd, tmpfil, 0)) == NOTOK) {
1072         if (verbose)
1073             adorn ("unable to copy message; skipping hook\n");
1074         return NOTOK;
1075     }
1076     (void) chown (tmpfil, pw -> pw_uid, pw -> pw_gid);
1077
1078     vecp = 1;
1079     (void) sprintf (receive, "%s/.mh_receive", pw -> pw_dir);
1080     switch (access (receive, 01)) {
1081         case NOTOK: 
1082             (void) sprintf (receive, "%s/bin/rcvmail", pw -> pw_dir);
1083             if (access (receive, 01) == NOTOK) {
1084                 (void) unlink (tmpfil);
1085                 if (verbose) {
1086                     printf ("\tnot present\n");
1087                     (void) fflush (stdout);
1088                 }
1089                 return NOTOK;
1090             }
1091             vec[vecp++] = addr;
1092             vec[vecp++] = tmpfil;
1093             vec[vecp++] = sender;
1094             break;
1095
1096         default: 
1097             vec[vecp++] = tmpfil;
1098             vec[vecp++] = mailbox;
1099             vec[vecp++] = home;
1100             vec[vecp++] = addr;
1101             vec[vecp++] = sender;
1102             break;
1103     }
1104     vec[0] = r1bindex (receive, '/');
1105     vec[vecp] = NULL;
1106
1107     i = usr_pipe (fd, "rcvmail", receive, vec);
1108     (void) unlink (tmpfil);
1109
1110     return i;
1111 }
1112 #endif  /* notdef */
1113
1114 /* \f */
1115
1116 static int  usr_pipe (fd, cmd, pgm, vec)
1117 int     fd;
1118 char   *cmd,
1119        *pgm,
1120       **vec;
1121 {
1122     int     bytes,
1123             i,
1124             child_id,
1125             status;
1126     struct stat st;
1127
1128     if (verbose) {
1129         printf ("\tdelivering to pipe \"%s\"", cmd);
1130         (void) fflush (stdout);
1131     }
1132     (void) lseek (fd, (off_t)0, 0);
1133
1134     for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
1135         sleep (5);
1136     switch (child_id) {
1137         case NOTOK: 
1138             adorn ("fork", "unable to");
1139             return NOTOK;
1140
1141         case OK: 
1142             if (fd != 0)
1143                 (void) dup2 (fd, 0);
1144             (void) freopen ("/dev/null", "w", stdout);
1145             (void) freopen ("/dev/null", "w", stderr);
1146             if (fd != 3)
1147                 (void) dup2 (fd, 3);
1148             closefds (4);
1149 #ifdef  TIOCNOTTY
1150             if ((fd = open ("/dev/tty", 2)) != NOTOK) {
1151                 (void) ioctl (fd, TIOCNOTTY, NULLCP);
1152                 (void) close (fd);
1153             }
1154 #endif  /* TIOCNOTTY */
1155 #ifdef  BSD42
1156             (void) setpgrp (0, getpid ());
1157 #endif  /* BSD42 */
1158
1159             *environ = NULL;
1160             (void) m_putenv ("USER", pw -> pw_name);
1161             (void) m_putenv ("HOME", pw -> pw_dir);
1162             (void) m_putenv ("SHELL", pw -> pw_shell);
1163
1164             execvp (pgm, vec);
1165             _exit (-1);
1166
1167         default: 
1168             switch (setjmp (myctx)) {
1169                 case OK: 
1170                     (void) signal (SIGALRM, alrmser);
1171                     bytes = fstat (fd, &st) != NOTOK ? (int) st.st_size : 100;
1172                     if (bytes <= 0)
1173                         bytes = 100;
1174                     (void) alarm ((unsigned) (bytes * 60 + 300));
1175
1176                     status = pidwait (child_id, OK);
1177
1178                     (void) alarm (0);
1179 #ifdef  MMDFI
1180                     if (status == RP_MOK || status == RP_OK)
1181                         status = 0;
1182 #endif  /* MMDFI */
1183                     if (verbose) {
1184                         if (status == 0)
1185                             printf (", wins.\n");
1186                         else
1187                             if ((status & 0xff00) == 0xff00)
1188                                 printf (", system error\n");
1189                             else
1190                                 (void) pidstatus (status, stdout, ", loses");
1191                         (void) fflush (stdout);
1192                     }
1193                     return (status == 0 ? OK : NOTOK);
1194
1195                 default: 
1196 #ifndef BSD42
1197                     (void) kill (child_id, SIGKILL);
1198 #else   /* BSD42 */
1199                     (void) killpg (child_id, SIGKILL);
1200 #endif  /* BSD42 */
1201                     if (verbose) {
1202                         printf (", timed-out; terminated\n");
1203                         (void) fflush (stdout);
1204                     }
1205                     return NOTOK;
1206             }
1207     }
1208 }
1209
1210 /* \f */
1211
1212 /* ARGSUSED */
1213
1214 static  TYPESIG alrmser (i)
1215 int     i;
1216 {
1217     longjmp (myctx, DONE);
1218 }
1219
1220 /* \f */
1221
1222 static  copyinfo (fp, from)
1223 register FILE   *fp;
1224 char    *from;
1225 {
1226     int     i;
1227     register char  *cp;
1228     static char buffer[BUFSIZ];
1229
1230     if (unixfrom)       /* interface from copyfile */
1231         strcpy (from, unixfrom);
1232     else if (fgets (from, BUFSIZ, fp) == NULL)
1233         adios (NULLCP, "no message");
1234
1235     if (strncmp (from, "From ", i = strlen ("From "))) {
1236         rewind (fp);
1237         *from = 0;
1238         return;
1239     }
1240
1241     (void) strcpy (buffer, from + i);
1242     if (cp = index (buffer, '\n')) {
1243         *cp = 0;
1244         cp -= 24;
1245         if (cp < buffer)
1246             cp = buffer;
1247     }
1248     else
1249         cp = buffer;
1250     *cp = 0;
1251
1252     for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)
1253         if (isspace (*cp))
1254             *cp = 0;
1255         else
1256             break;
1257     sender = buffer;
1258     rewind (fp);
1259 }
1260
1261 /* \f */
1262
1263 static int  copyfile (qd, tmpfil, fold)
1264 int     qd,
1265         fold;
1266 register char   *tmpfil;
1267 {
1268     register int    i,
1269                     first = 0,
1270                     fd1,
1271                     fd2;
1272     char    buffer[BUFSIZ];
1273     register FILE  *qfp,
1274                    *ffp;
1275
1276     (void) strcpy (tmpfil, m_tmpfil (invo_name));
1277     if ((fd1 = creat (tmpfil, 0600)) == NOTOK)
1278         return NOTOK;
1279     (void) close (fd1);
1280     if ((fd1 = open (tmpfil, 2)) == NOTOK)
1281         return NOTOK;
1282
1283     if (!fold) {
1284         while ((i = read (qd, buffer, sizeof buffer)) > 0)
1285             if (write (fd1, buffer, i) != i) {
1286 you_lose: ;
1287                 (void) close (fd1);
1288                 (void) unlink (tmpfil);
1289                 return NOTOK;
1290             }
1291         if (i == NOTOK)
1292             goto you_lose;
1293         (void) lseek (fd1, (off_t)0, 0);
1294         return fd1;
1295     }
1296
1297     if ((fd2 = dup (qd)) == NOTOK) {
1298         (void) close (fd1);
1299         return NOTOK;
1300     }
1301     if ((qfp = fdopen (fd2, "r")) == NULL) {
1302         (void) close (fd1);
1303         (void) close (fd2);
1304         return NOTOK;
1305     }
1306
1307     if ((fd2 = dup (fd1)) == NOTOK) {
1308         (void) close (fd1);
1309         (void) fclose (qfp);
1310         return NOTOK;
1311     }
1312     if ((ffp = fdopen (fd2, "r+")) == NULL) {
1313         (void) close (fd1);
1314         (void) close (fd2);
1315         (void) fclose (qfp);
1316         return NOTOK;
1317     }
1318
1319     i = strlen ("From ");
1320     while (fgets (buffer, sizeof buffer, qfp)) {
1321         if (!strncmp (buffer, "From ", i))
1322             if (first == 0) {
1323 #ifdef  RPATHS
1324                 register char *fp, *cp, *hp, *ep;
1325 #endif
1326                 unixfrom = getcpy (buffer);     /* save for later */
1327 #ifndef RPATHS
1328                 continue;                       /* but don't put in file */
1329 #else
1330                 hp = cp = index (fp = unixfrom + i, ' ');
1331                 while (hp = index (++hp, 'r'))
1332                     if (uprf (hp, "remote from")) {
1333                         hp = rindex (hp, ' ');
1334                         break;
1335                     }
1336                 if (hp) {
1337                     ep = rindex (++hp, '\n');
1338                     sprintf (buffer, "Return-Path: %.*s!%.*s\n",
1339                             ep - hp, hp,
1340                             cp - fp, fp);
1341                 }
1342                 else
1343                     sprintf (buffer, "Return-Path: %.*s\n",
1344                             cp - fp, fp);
1345 #endif
1346             }
1347 #ifdef  notdef          /* mbx_copy does this */
1348             else
1349                 putc ('>', ffp);
1350 #endif  /* notdef */
1351         first++;
1352         fputs (buffer, ffp);
1353         if (ferror (ffp)) {
1354             (void) close (fd1);
1355             (void) fclose (ffp);
1356             (void) fclose (qfp);
1357             return NOTOK;
1358         }
1359     }
1360
1361     (void) fclose (ffp);
1362     if (ferror (qfp)) {
1363         (void) close (fd1);
1364         (void) fclose (qfp);
1365         return NOTOK;
1366     }
1367     (void) fclose (qfp);
1368
1369     (void) lseek (fd1, (off_t)0, 0);
1370
1371     return fd1;
1372 }
1373
1374 /* \f */
1375
1376 /* VARARGS2 */
1377
1378 static void  adorn (what, fmt, a, b, c, d, e, f)
1379 char   *what,
1380        *fmt,
1381        *a,
1382        *b,
1383        *c,
1384        *d,
1385        *e,
1386        *f;
1387 {
1388     char   *cp = invo_name;
1389
1390     if (!verbose)
1391         return;
1392     printf (", ");
1393
1394     invo_name = NULL;
1395     advise (what, fmt, a, b, c, d, e, f);
1396     invo_name = cp;
1397 }
1398
1399 /* \f */
1400
1401 #ifdef  MSGID
1402
1403 static int  check_msgid (fd, file)
1404 int     fd;
1405 char   *file;
1406 {
1407     int     fd1,
1408             state;
1409     char   *cp,
1410             buf[BUFSIZ],
1411             name[NAMESZ];
1412     datum   key,
1413             value;
1414     DBM    *db;
1415     FILE   *in;
1416
1417     if ((fd1 = dup (fd)) == NOTOK)
1418         return NOTOK;
1419     if ((in = fdopen (fd1, "r")) == NULL) {
1420         (void) close (fd1);
1421         return NOTOK;
1422     }
1423     rewind (in);
1424
1425     for (state = FLD;;) {
1426         switch (state = m_getfld (state, name, buf, sizeof buf, in)) {
1427             case FLD:
1428             case FLDPLUS:
1429             case FLDEOF:
1430                 if (!uleq (name, "Message-ID")) {
1431                     while (state == FLDPLUS)
1432                         state = m_getfld (state, name, buf, sizeof buf, in);
1433                     continue;
1434                 }
1435
1436                 cp = add (buf, NULLCP);
1437                 while (state == FLDPLUS) {
1438                     state = m_getfld (state, name, buf, sizeof buf, in);
1439                     cp = add (buf, cp);
1440                 }
1441                 key.dsize = strlen (key.dptr = trimcpy (cp)) + 1;
1442                 free (cp);
1443                 cp = key.dptr;
1444
1445                 if ((db = dbm_open (file, O_RDWR | O_CREAT, 0600)) == NULL) {
1446                     advise (file, "unable to perform dbm_open on");
1447 out: ;
1448                     free (cp);
1449                     (void) fclose (in);
1450                     return NOTOK;
1451                 }
1452 #ifdef FCNTL
1453                 {
1454                     struct flock fl;
1455
1456                     fl.l_type = F_WRLCK;
1457                     fl.l_whence = 0;
1458                     fl.l_start = 0;
1459                     fl.l_len = 0;
1460                     if (fcntl (dbm_pagfno (db), F_SETLK, &fl) == -1) {
1461                         advise (file, "unable to perform flock on");
1462                         goto out;
1463                     }
1464                 }
1465 #else
1466 #ifdef LOCKF
1467                 if (lockf (dbm_pagfno (db), F_LOCK) == NOTOK) {
1468                     advise (file, "unable to perform lockf on");
1469                     goto out;
1470                 }
1471 #else
1472                 if (flock (dbm_pagfno (db), LOCK_EX) == NOTOK) {
1473                     advise (file, "unable to perform flock on");
1474                     goto out;
1475                 }
1476 #endif
1477 #endif
1478
1479                 value = dbm_fetch (db, key);
1480                 if (value.dptr != NULL) {
1481                     if (debug)
1482                         advise (NULLCP,
1483                                 "Message-ID: %s already received on\n\tDate:       %s",
1484                                 cp, value.dptr);
1485                     free (cp);
1486                     (void) fclose (in);
1487                     return DONE;
1488                 }
1489                            
1490                 value.dsize = strlen (value.dptr =
1491                                       ddate + sizeof "Delivery-Date:") + 1;
1492
1493                 if (dbm_store (db, key, value, DBM_INSERT))
1494                     advise (file, "possibly corrupt file");
1495
1496                 dbm_close (db);
1497
1498                 free (cp);
1499                 break;
1500
1501            case BODY:
1502            case BODYEOF:
1503            case FILEEOF:
1504                 break;
1505
1506            case LENERR:
1507            case FMTERR:
1508            default:
1509                 break;
1510         }
1511
1512         break;
1513     }
1514
1515     (void) fclose (in);
1516     return OK;
1517 }
1518 #endif
1519 @
1520
1521
1522 1.24
1523 log
1524 @off_t fixes for BSD44
1525 @
1526 text
1527 @d3 1
1528 a3 1
1529 static char ident[] = "@@(#)$Id: slocal.c,v 1.23 1992/12/15 00:20:22 jromine Exp jromine $";
1530 d718 1
1531 d722 2
1532 a723 1
1533                 p - hdrs, p -> p_name, p -> p_value);
1534 @
1535
1536
1537 1.23
1538 log
1539 @endif sugar
1540 @
1541 text
1542 @d3 1
1543 a3 1
1544 static char ident[] = "@@(#)$Id: slocal.c,v 1.22 1992/12/11 19:00:32 jromine Exp jromine $";
1545 d184 1
1546 a184 1
1547 long    lseek ();
1548 d899 1
1549 a899 1
1550     (void) lseek (fd, 0L, 0);
1551 d987 1
1552 a987 1
1553     (void) lseek (fd, 0L, 0);
1554 d1148 1
1555 a1148 1
1556         (void) lseek (fd1, 0L, 0);
1557 d1224 1
1558 a1224 1
1559     (void) lseek (fd1, 0L, 0);
1560 @
1561
1562
1563 1.22
1564 log
1565 @include sys/fcntl.h under LOCKF
1566 @
1567 text
1568 @d3 2
1569 a4 2
1570 static char ident[] = "@@(#)$Id: slocal.c,v 1.21 1992/12/11 18:26:10 jromine Exp jromine $";
1571 #endif  lint
1572 d36 2
1573 a37 2
1574 #endif  NOIOCTLH
1575 #endif  not V7
1576 d316 1
1577 a316 1
1578 #endif  BSD41A
1579 d320 1
1580 a320 1
1581 #endif  BSD42
1582 d398 1
1583 a398 1
1584 #endif  notdef
1585 d967 1
1586 a967 1
1587 #endif  notdef
1588 d1009 1
1589 a1009 1
1590 #endif  TIOCNOTTY
1591 d1012 1
1592 a1012 1
1593 #endif  BSD42
1594 d1037 1
1595 a1037 1
1596 #endif  MMDFI
1597 d1053 1
1598 a1053 1
1599 #else   BSD42
1600 d1055 1
1601 a1055 1
1602 #endif  BSD42
1603 d1205 1
1604 a1205 1
1605 #endif  notdef
1606 @
1607
1608
1609 1.21
1610 log
1611 @LOCKF (may not work on all systems)
1612 @
1613 text
1614 @d3 1
1615 a3 1
1616 static char ident[] = "@@(#)$Id: slocal.c,v 1.20 1992/11/25 04:20:30 jromine Exp jromine $";
1617 d58 3
1618 @
1619
1620
1621 1.20
1622 log
1623 @fixes from Stephen Gildea
1624 @
1625 text
1626 @d3 1
1627 a3 1
1628 static char ident[] = "@@(#)$Id: slocal.c,v 1.19 1992/11/11 23:10:37 jromine Exp jromine $";
1629 d55 3
1630 d1318 6
1631 d1328 1
1632 @
1633
1634
1635 1.19
1636 log
1637 @attempt to use FCNTL locking for MSGID under SVR4
1638 @
1639 text
1640 @d3 1
1641 a3 1
1642 static char ident[] = "@@(#)$Id: slocal.c,v 1.18 1992/11/04 01:03:18 jromine Exp jromine $";
1643 d45 14
1644 a1251 10
1645 #undef  DBM             /* used by ndbm.h */
1646 #include <ndbm.h>
1647 #include <stdio.h>
1648 #include <sys/types.h>
1649 #include <sys/file.h>
1650 #ifdef  SYS5
1651 #include <fcntl.h>
1652 #endif
1653
1654
1655 d1301 1
1656 a1301 1
1657 #if defined(SVR4) && defined(FCNTL)
1658 @
1659
1660
1661 1.18
1662 log
1663 @LOCALE
1664 putenv
1665 TYPESIG
1666 @
1667 text
1668 @d3 1
1669 a3 1
1670 static char ident[] = "@@(#)$Id: slocal.c,v 1.17 1992/10/27 16:43:48 jromine Exp jromine $";
1671 d1297 14
1672 d1315 1
1673 @
1674
1675
1676 1.17
1677 log
1678 @fixup
1679 @
1680 text
1681 @d3 1
1682 a3 1
1683 static char ident[] = "@@(#)$Id: slocal.c,v 1.16 1992/10/26 16:47:04 jromine Exp jromine $";
1684 d40 3
1685 d161 1
1686 a161 1
1687 static int      alrmser ();
1688 d193 3
1689 d995 3
1690 a997 3
1691             (void) putenv ("USER", pw -> pw_name);
1692             (void) putenv ("HOME", pw -> pw_dir);
1693             (void) putenv ("SHELL", pw -> pw_shell);
1694 d1049 1
1695 a1049 1
1696 static  int alrmser (i)
1697 @
1698
1699
1700 1.16
1701 log
1702 @added MSGID option
1703 @
1704 text
1705 @d3 1
1706 a3 1
1707 static char ident[] = "@@(#)$Id: slocal.c,v 1.15 1992/02/15 00:53:47 jromine Exp jromine $";
1708 d109 1
1709 a109 1
1710 static struct pair {
1711 a1235 1
1712 #include <sys/stat.h>
1713 @
1714
1715
1716 1.15
1717 log
1718 @fix for "From " lines
1719 @
1720 text
1721 @d3 1
1722 a3 1
1723 static char ident[] = "@@(#)$Id: slocal.c,v 1.14 1992/02/12 17:18:19 jromine Exp jromine $";
1724 d353 8
1725 d1227 110
1726 @
1727
1728
1729 1.14
1730 log
1731 @add -info
1732 make -home invisible
1733 @
1734 text
1735 @d3 1
1736 a3 1
1737 static char ident[] = "@@(#)$Id: slocal.c,v 1.13 1992/02/03 18:12:31 jromine Exp jromine $";
1738 d1168 1
1739 d1171 1
1740 @
1741
1742
1743 1.13
1744 log
1745 @add mbox format
1746 @
1747 text
1748 @d3 1
1749 a3 1
1750 static char ident[] = "@@(#)$Id: slocal.c,v 1.12 1992/02/03 17:57:22 jromine Exp jromine $";
1751 d58 3
1752 a60 1
1753     "home directory", 0,
1754 d62 1
1755 a62 1
1756 #define MAILSW  6
1757 d65 1
1758 a65 1
1759 #define VERBSW  7
1760 d67 1
1761 a67 1
1762 #define NVERBSW 8
1763 d70 1
1764 a70 1
1765 #define DEBUGSW 9
1766 d73 1
1767 a73 1
1768 #define HELPSW  10
1769 d212 4
1770 @
1771
1772
1773 1.12
1774 log
1775 @STDC/SYS5/getpw
1776 @
1777 text
1778 @d3 1
1779 a3 1
1780 static char ident[] = "@@(#)$Id: slocal.c,v 1.11 1992/01/31 22:27:43 jromine Exp jromine $";
1781 d510 1
1782 a510 1
1783 #ifndef RPATHS
1784 d515 6
1785 @
1786
1787
1788 1.11
1789 log
1790 @kerberos
1791 @
1792 text
1793 @d3 1
1794 a3 1
1795 static char ident[] = "@@(#)$Id: slocal.c,v 1.10 1992/01/30 00:06:00 jromine Exp jromine $";
1796 d160 1
1797 d163 2
1798 a164 1
1799 #endif  SYS5
1800 @
1801
1802
1803 1.10
1804 log
1805 @fix from MTR re: slocal & SendMail
1806 @
1807 text
1808 @d3 1
1809 a3 1
1810 static char ident[] = "@@(#)$Id: slocal.c,v 1.9 1991/01/10 14:39:00 mh Exp jromine $";
1811 d74 1
1812 a74 1
1813     NULL, NULL
1814 d308 1
1815 a308 1
1816     from[0] = NULL;
1817 d410 1
1818 a410 1
1819             *cp = NULL;
1820 d544 2
1821 a545 2
1822             *s++ = NULL;
1823         if (*s == NULL)
1824 d549 1
1825 a549 1
1826             for (vec[i++] = ++s; *s != NULL && *s != '"'; s++)
1827 d556 1
1828 a556 1
1829                 *s++ = NULL;
1830 d563 1
1831 a563 1
1832         while (*s != NULL && !isspace (*s) && *s != ',')
1833 d621 1
1834 a621 1
1835                                         *dp = NULL;
1836 d705 1
1837 a705 1
1838             *s2++ = NULL;
1839 d714 1
1840 a714 1
1841     *s1 = NULL;
1842 d775 1
1843 a775 1
1844         if (ut.ut_name[0] != NULL
1845 d1044 1
1846 a1044 1
1847         *from = NULL;
1848 d1050 1
1849 a1050 1
1850         *cp = NULL;
1851 d1057 1
1852 a1057 1
1853     *cp = NULL;
1854 d1061 1
1855 a1061 1
1856             *cp = NULL;
1857 @
1858
1859
1860 1.9
1861 log
1862 @fix logic error in "?"/"A" result code
1863 @
1864 text
1865 @d3 1
1866 a3 1
1867 static char ident[] = "@@(#)$Id: slocal.c,v 1.8 90/04/05 14:58:46 sources Exp Locker: mh $";
1868 d508 1
1869 d510 3
1870 @
1871
1872
1873 1.8
1874 log
1875 @add ID
1876 @
1877 text
1878 @d3 1
1879 a3 1
1880 static char ident[] = "@@(#)$Id:$";
1881 d518 1
1882 a518 5
1883         if (accept) {
1884             if (status == NOTOK) {
1885                 won = 0;
1886                 break;
1887             }
1888 a519 1
1889         }
1890 @
1891
1892
1893 1.7
1894 log
1895 @use "From_" format in usr_file if appropriate
1896 new "N" condition -- do this if prev condition succeeded
1897 @
1898 text
1899 @d2 3
1900 @
1901
1902
1903 1.6
1904 log
1905 @fixup
1906 @
1907 text
1908 @d342 1
1909 a342 1
1910     if (usr_delivery (fd, mdlvr ? mdlvr : ".maildelivery", 0) != NOTOK)
1911 d345 1
1912 a345 1
1913     if (usr_delivery (fd, maildelivery, 1) != NOTOK)
1914 d364 1
1915 a364 1
1916 static int  usr_delivery (fd, delivery, su)
1917 d367 2
1918 a368 1
1919 char   *delivery;
1920 d374 2
1921 a375 1
1922             vecp;
1923 d402 1
1924 d419 6
1925 d469 6
1926 a474 2
1927                         || !matches (p -> p_value, pattern))
1928                     continue;
1929 d505 1
1930 a505 1
1931                 status = usr_file (fd, string, NULLCP);
1932 @
1933
1934
1935 1.5
1936 log
1937 @do some Return-Path stuff
1938 @
1939 text
1940 @d1022 1
1941 a1022 1
1942     if (unixfrom)
1943 d1116 1
1944 a1116 2
1945                 int n;
1946                 char *fp, *cp, *hp, *ep;
1947 @
1948
1949
1950 1.4
1951 log
1952 @ANSI Compilance
1953 @
1954 text
1955 @d87 1
1956 d1022 3
1957 a1024 1
1958     if (fgets (from, BUFSIZ, fp) == NULL)
1959 d1061 1
1960 d1114 29
1961 a1142 1
1962             putc ('>', ffp);
1963 @
1964
1965
1966 1.3
1967 log
1968 @*** empty log message ***
1969 @
1970 text
1971 @d114 1
1972 a114 1
1973 struct pair *lookup ();
1974 d151 2
1975 a152 2
1976 void    adorn ();
1977 int     alrmser ();
1978 d159 3
1979 @
1980
1981
1982 1.2
1983 log
1984 @nil value problem
1985 @
1986 text
1987 @d31 1
1988 d33 1
1989 @
1990
1991
1992 1.1
1993 log
1994 @Initial revision
1995 @
1996 text
1997 @d453 1
1998 @