Mercurial > hg > Applications > mh
comparison zotnet/mts/mts.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | a6481689f99c |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
1 /* mts.c - definitions for the mail transport system */ | |
2 #ifndef lint | |
3 static char ident[] = "@(#)$Id$"; | |
4 #endif /* lint */ | |
5 | |
6 /* LINTLIBRARY */ | |
7 | |
8 #undef NETWORK | |
9 #if defined(BSD41A) || defined(BSD42) || defined(SOCKETS) | |
10 #define NETWORK | |
11 #endif | |
12 | |
13 #include "../h/strings.h" | |
14 #include <ctype.h> | |
15 #include <stdio.h> | |
16 #include "mts.h" | |
17 #ifdef NETWORK | |
18 #if defined(BSD42) || defined(SOCKETS) | |
19 #include <netdb.h> | |
20 #endif | |
21 #else /* NETWORK */ | |
22 #ifndef SYS5 | |
23 #include <whoami.h> | |
24 #else | |
25 #include <sys/utsname.h> | |
26 #endif /* SYS5 */ | |
27 #endif /* NETWORK */ | |
28 #include <pwd.h> | |
29 | |
30 | |
31 #define NOTOK (-1) | |
32 #define OK 0 | |
33 | |
34 #define NULLCP ((char *) 0) | |
35 | |
36 #ifdef __CYGWIN32__ | |
37 #include <errno.h> | |
38 #endif | |
39 extern int errno; | |
40 | |
41 static char *tailor_value (); | |
42 | |
43 | |
44 #if defined(SYS5) && !defined(_AIX) | |
45 #define index strchr | |
46 #define rindex strrchr | |
47 #endif /* SYS5 */ | |
48 | |
49 #if !defined(__STDC__) && !defined(_AIX) && !defined(_POSIX_SOURCE) | |
50 char *index (), *malloc (), *mktemp (), *rindex (), *strcpy (); | |
51 | |
52 #ifdef SYS5 | |
53 struct passwd *getpwuid (); | |
54 #endif | |
55 #endif /* !__STDC__ */ | |
56 | |
57 /* */ | |
58 | |
59 /* | |
60 *mmdfldir and *uucpldir are the maildrop directories. If maildrops | |
61 are kept in the user's home directory, then these should be empty | |
62 strings. In this case, the appropriate ...lfil array should contain | |
63 the name of the file in the user's home directory. Usually, this is | |
64 something like ".mail". | |
65 */ | |
66 | |
67 static char *mtstailor = "/usr/local/mh/lib/mtstailor"; | |
68 | |
69 static char *localname = ""; | |
70 static char *localdomain = ""; | |
71 static char *systemname = ""; | |
72 #ifdef MF | |
73 static char *UUCPchan = ""; | |
74 #endif /* MF */ | |
75 char *mmdfldir = "/var/mail"; | |
76 char *mmdflfil = ""; | |
77 #ifdef MF | |
78 char *uucpldir = "/usr/spool/mail"; | |
79 #else /* MF */ | |
80 char *uucpldir = ""; | |
81 #endif /* MF */ | |
82 char *uucplfil = ""; | |
83 | |
84 | |
85 char *mmdlm1 = "\001\001\001\001\n"; | |
86 char *mmdlm2 = "\001\001\001\001\n"; | |
87 | |
88 | |
89 static int MMailids = 0; | |
90 static char *mmailid = "0"; | |
91 | |
92 | |
93 #ifdef MF | |
94 char *umincproc = "/usr/local/mh/lib/uminc"; | |
95 #else /* MF */ | |
96 char *umincproc = NULL; | |
97 #endif /* MF */ | |
98 | |
99 | |
100 int lockstyle = LOK_UNIX; | |
101 static char *lkstyle = "0"; | |
102 char *lockldir = ""; | |
103 | |
104 /* */ | |
105 | |
106 /* MTS specific variables */ | |
107 | |
108 #ifdef MHMTS | |
109 char *Mailqdir = "/usr/spool/netmail"; | |
110 char *TMailqdir = "/usr/tmp"; | |
111 int Syscpy = 1; | |
112 static char *syscpy = "1"; | |
113 char *Overseer = "root"; | |
114 char *Mailer = "root"; | |
115 char *Fromtmp = "/tmp/rml.f.XXXXXX"; | |
116 char *Msgtmp = "/tmp/rml.m.XXXXXX"; | |
117 char *Errtmp = "/tmp/rml.e.XXXXXX"; | |
118 int Tmpmode = 0600; | |
119 static char *tmpmode = "0600"; | |
120 char *Okhosts = "/usr/local/mh/lib/Rmail.OkHosts"; | |
121 char *Okdests = "/usr/local/mh/lib/Rmail.OkDests"; | |
122 #endif /* MHMTS */ | |
123 | |
124 #ifdef MMDFMTS | |
125 #endif /* MMDFMTS */ | |
126 | |
127 #ifdef SENDMTS | |
128 char *hostable = "/usr/local/mh/lib/hosts"; | |
129 char *sendmail = "/usr/sbin/sendmail"; | |
130 #endif /* SENDMTS */ | |
131 | |
132 | |
133 /* SMTP/POP stuff */ | |
134 | |
135 char *clientname = (char *)0; | |
136 char *servers = "localhost \01localnet"; | |
137 char *pophost = ""; | |
138 #ifdef MH_PLUS | |
139 char *rpop_default = ""; | |
140 #endif /* MH_PLUS */ | |
141 | |
142 | |
143 /* BBoards-specific variables */ | |
144 | |
145 char *bb_domain = ""; | |
146 | |
147 | |
148 /* POP BBoards-specific variables */ | |
149 | |
150 #if defined(BPOP) || defined(NNTP) | |
151 char *popbbhost = ""; | |
152 #endif /* BPOP || NNTP */ | |
153 #ifdef BPOP | |
154 char *popbbuser = ""; | |
155 char *popbblist = "/usr/local/mh/lib/hosts.popbb"; | |
156 #endif /* BPOP */ | |
157 | |
158 | |
159 /* MailDelivery */ | |
160 | |
161 char *maildelivery = "/usr/local/mh/lib/maildelivery"; | |
162 | |
163 | |
164 /* Aliasing Facility (doesn't belong here) */ | |
165 | |
166 int Everyone = NOTOK; | |
167 static char *everyone = "-1"; | |
168 char *NoShell = ""; | |
169 | |
170 #ifdef MH_PLUS | |
171 int LocalUser = 0; | |
172 static char *localuser = "0"; | |
173 #endif /* MH_PLUS */ | |
174 | |
175 /* */ | |
176 | |
177 /* customize the MTS settings for MH by reading /usr/local/mh/lib/mtstailor */ | |
178 | |
179 static struct bind { | |
180 char *keyword; | |
181 char **value; | |
182 } binds[] = { | |
183 "localname", &localname, | |
184 "localdomain", &localdomain, | |
185 "systemname", &systemname, | |
186 #ifdef MF | |
187 "uucpchan", &UUCPchan, | |
188 #endif /* MF */ | |
189 "mmdfldir", &mmdfldir, | |
190 "mmdflfil", &mmdflfil, | |
191 "uucpldir", &uucpldir, | |
192 "uucplfil", &uucplfil, | |
193 "mmdelim1", &mmdlm1, | |
194 "mmdelim2", &mmdlm2, | |
195 "mmailid", &mmailid, | |
196 "umincproc", &umincproc, | |
197 "lockstyle", &lkstyle, | |
198 "lockldir", &lockldir, | |
199 | |
200 #ifdef MHMTS | |
201 "mailqdir", &Mailqdir, | |
202 "tmailqdir", &TMailqdir, | |
203 "syscpy", &syscpy, | |
204 "overseer", &Overseer, | |
205 "mailer", &Mailer, | |
206 "fromtmp", &Fromtmp, | |
207 "msgtmp", &Msgtmp, | |
208 "errtmp", &Errtmp, | |
209 "tmpmode", &tmpmode, | |
210 "okhosts", &Okhosts, | |
211 "okdests", &Okdests, | |
212 #endif /* MHMTS */ | |
213 | |
214 #ifdef MMDFMTS | |
215 #endif /* MMDFMTS */ | |
216 | |
217 #ifdef SENDMTS | |
218 "hostable", &hostable, | |
219 "sendmail", &sendmail, | |
220 #endif /* SENDMTS */ | |
221 | |
222 "clientname", &clientname, | |
223 "servers", &servers, | |
224 "pophost", &pophost, | |
225 #ifdef MH_PLUS | |
226 "rpop", &rpop_default, | |
227 #endif /* MH_PLUS */ | |
228 | |
229 "bbdomain", &bb_domain, | |
230 | |
231 #ifdef BPOP | |
232 "popbbhost", &popbbhost, | |
233 "popbbuser", &popbbuser, | |
234 "popbblist", &popbblist, | |
235 #endif /* BPOP */ | |
236 #ifdef NNTP | |
237 "nntphost", &popbbhost, | |
238 #endif /* NNTP */ | |
239 | |
240 "maildelivery", &maildelivery, | |
241 | |
242 "everyone", &everyone, | |
243 "noshell", &NoShell, | |
244 | |
245 #ifdef MH_PLUS | |
246 "localuser", &localuser, | |
247 #endif /* MH_PLUS */ | |
248 | |
249 NULL | |
250 }; | |
251 | |
252 /* */ | |
253 | |
254 /* I'd like to use m_getfld() here, but not all programs loading mts.o may be | |
255 MH-style programs... */ | |
256 | |
257 /* ARGSUSED */ | |
258 | |
259 mts_init (name) | |
260 char *name; | |
261 { | |
262 register char *bp, | |
263 *cp; | |
264 char buffer[BUFSIZ]; | |
265 register struct bind *b; | |
266 register FILE *fp; | |
267 static int inited = 0; | |
268 | |
269 if (inited++ || (fp = fopen (mtstailor, "r")) == NULL) | |
270 return; | |
271 | |
272 while (fgets (buffer, sizeof buffer, fp)) { | |
273 if ((cp = index (buffer, '\n')) == NULL) | |
274 break; | |
275 *cp = 0; | |
276 if (*buffer == '#' || *buffer == '\0') | |
277 continue; | |
278 if ((bp = index (buffer, ':')) == NULL) | |
279 break; | |
280 *bp++ = 0; | |
281 while (isspace (*bp)) | |
282 *bp++ = 0; | |
283 | |
284 for (b = binds; b -> keyword; b++) | |
285 if (strcmp (buffer, b -> keyword) == 0) | |
286 break; | |
287 if (b -> keyword && (cp = tailor_value (bp))) | |
288 *b -> value = cp; | |
289 } | |
290 | |
291 (void) fclose (fp); | |
292 | |
293 MMailids = atoi (mmailid); | |
294 if ((lockstyle = atoi (lkstyle)) < LOK_UNIX || lockstyle > LOK_MMDF) | |
295 lockstyle = LOK_UNIX; | |
296 #ifdef MHMTS | |
297 Syscpy = atoi (syscpy); | |
298 (void) sscanf (tmpmode, "0%o", &Tmpmode); | |
299 #endif /* MHMTS */ | |
300 Everyone = atoi (everyone); | |
301 #ifdef MH_PLUS | |
302 LocalUser = atoi (localuser); | |
303 #endif /* MH_PLUS */ | |
304 } | |
305 | |
306 /* */ | |
307 | |
308 #define QUOTE '\\' | |
309 | |
310 static char *tailor_value (s) | |
311 register char *s; | |
312 { | |
313 register int i, | |
314 r; | |
315 register char *bp; | |
316 char buffer[BUFSIZ]; | |
317 | |
318 for (bp = buffer; *s; bp++, s++) | |
319 if (*s != QUOTE) | |
320 *bp = *s; | |
321 else | |
322 switch (*++s) { | |
323 #define grot(y,z) case y: *bp = z; break; | |
324 grot ('b', '\b'); | |
325 grot ('f', '\f'); | |
326 grot ('n', '\n'); | |
327 grot ('t', '\t'); | |
328 #undef grot | |
329 | |
330 case 0: s--; | |
331 case QUOTE: | |
332 *bp = QUOTE; | |
333 break; | |
334 | |
335 default: | |
336 if (!isdigit (*s)) { | |
337 *bp++ = QUOTE; | |
338 *bp = *s; | |
339 } | |
340 r = *s != '0' ? 10 : 8; | |
341 for (i = 0; isdigit (*s); s++) | |
342 i = i * r + *s - '0'; | |
343 s--; | |
344 *bp = toascii (i); | |
345 break; | |
346 } | |
347 *bp = 0; | |
348 | |
349 bp = malloc ((unsigned) (strlen (buffer) + 1)); | |
350 if (bp != NULL) | |
351 (void) strcpy (bp, buffer); | |
352 | |
353 return bp; | |
354 } | |
355 | |
356 /* */ | |
357 | |
358 struct hostent *mh_gethostbyname(); | |
359 | |
360 char *LocalName () { | |
361 #ifdef BSD41A | |
362 char *myname; | |
363 #endif /* BSD41A */ | |
364 #if defined(BSD42) || defined(SOCKETS) | |
365 register struct hostent *hp; | |
366 #endif /* BSD42 or SOCKETS */ | |
367 #if defined(SYS5) && !defined(NETWORK) | |
368 struct utsname name; | |
369 #endif /* SYS5 and not NETWORK */ | |
370 static char buffer[BUFSIZ] = ""; | |
371 | |
372 if (buffer[0]) | |
373 return buffer; | |
374 | |
375 mts_init ("mts"); | |
376 if (*localname) | |
377 strcpy (buffer, localname); | |
378 else { | |
379 | |
380 #ifdef locname | |
381 (void) strcpy (buffer, locname); | |
382 #else /* not locname */ | |
383 #ifdef NETWORK | |
384 #ifdef BSD41A | |
385 myname = "myname"; | |
386 if (rhost (&myname) == -1) | |
387 (void) gethostname (buffer, sizeof buffer); | |
388 else { | |
389 (void) strcpy (buffer, myname); | |
390 free (myname); | |
391 } | |
392 #endif /* BSD41A */ | |
393 #if defined(BSD42) || defined(SOCKETS) | |
394 (void) gethostname (buffer, sizeof buffer); | |
395 #ifndef BIND | |
396 sethostent (1); | |
397 #endif | |
398 if (hp = mh_gethostbyname (buffer)) | |
399 (void) strcpy (buffer, hp -> h_name); | |
400 #endif /* BSD42 or SOCKETS */ | |
401 #else /* not NETWORK */ | |
402 #ifndef SYS5 | |
403 (void) strcpy (buffer, SystemName ()); | |
404 #else /* SYS5 */ | |
405 (void) uname (&name); | |
406 (void) strcpy (buffer, name.nodename); | |
407 #endif /* SYS5 */ | |
408 #endif /* not NETWORK */ | |
409 #endif /* not locname */ | |
410 } | |
411 if (*localdomain) { | |
412 strcat (buffer, "."); | |
413 strcat (buffer, localdomain); | |
414 } | |
415 return buffer; | |
416 } | |
417 | |
418 /* */ | |
419 | |
420 char *SystemName () { | |
421 #if defined(SYS5) && !defined(NETWORK) | |
422 struct utsname name; | |
423 #endif /* SYS5 and not NETWORK */ | |
424 static char buffer[BUFSIZ] = ""; | |
425 | |
426 if (buffer[0]) | |
427 return buffer; | |
428 | |
429 mts_init ("mts"); | |
430 if (*systemname) | |
431 return strcpy (buffer, systemname); | |
432 | |
433 #ifdef sysname | |
434 (void) strcpy (buffer, sysname); | |
435 #else /* sysname */ | |
436 #if !defined(SYS5) || defined(NETWORK) | |
437 (void) gethostname (buffer, sizeof buffer); | |
438 #else /* SYS5 and not NETWORK */ | |
439 #ifdef SYS5 | |
440 (void) uname (&name); | |
441 (void) strcpy (buffer, name.nodename); | |
442 #endif /* SYS5 */ | |
443 #endif /* SYS5 and not NETWORK */ | |
444 #endif /* sysname */ | |
445 | |
446 return buffer; | |
447 } | |
448 | |
449 /* */ | |
450 | |
451 char *UucpChan () { | |
452 #ifdef MF | |
453 static char buffer[BUFSIZ] = ""; | |
454 #endif /* MF */ | |
455 | |
456 #ifndef MF | |
457 return NULL; | |
458 #else /* MF */ | |
459 if (buffer[0]) | |
460 return buffer; | |
461 | |
462 mts_init ("mts"); | |
463 if (*UUCPchan) | |
464 return strcpy (buffer, UUCPchan); | |
465 | |
466 #ifdef uucpchan | |
467 (void) strcpy (buffer, uucpchan); | |
468 #else /* uucpchan */ | |
469 (void) strcpy (buffer, "uucp"); | |
470 #endif /* uucpchan */ | |
471 return buffer; | |
472 #endif /* MF */ | |
473 } | |
474 | |
475 /* */ | |
476 | |
477 #ifdef ALTOS | |
478 gethostname (name, len) | |
479 register char *name; | |
480 register int len; | |
481 { | |
482 register char *cp; | |
483 register FILE *fp; | |
484 | |
485 if (fp = fopen ("/etc/systemid", "r")) { | |
486 if (fgets (name, len, fp)) { | |
487 if (cp = index (name, '\n')) | |
488 *cp = 0; | |
489 (void) fclose (fp); | |
490 return OK; | |
491 } | |
492 (void) fclose (fp); | |
493 } | |
494 (void) strncpy (name, "altos", len); | |
495 | |
496 return OK; | |
497 } | |
498 #endif /* ALTOS */ | |
499 | |
500 /* */ | |
501 | |
502 static char username[BUFSIZ]; | |
503 static char fullname[BUFSIZ]; | |
504 | |
505 | |
506 char *getusr () { | |
507 register char *cp, | |
508 *np; | |
509 #ifdef KPOP | |
510 int uid; | |
511 #endif /* KPOP */ | |
512 register struct passwd *pw; | |
513 | |
514 if (username[0]) | |
515 return username; | |
516 | |
517 #ifndef KPOP | |
518 #ifdef __CYGWIN32__ | |
519 if ((cp = getenv ("USERNAME")) != NULL | |
520 && (pw = getpwnam (cp)) != NULL) | |
521 strcpy (username, cp); | |
522 else if ((pw = getpwuid (getuid ())) == NULL | |
523 || pw -> pw_name == NULL | |
524 || *pw -> pw_name == '\0') { | |
525 #else /* __CYGWIN32__ */ | |
526 if ((pw = getpwuid (getuid ())) == NULL | |
527 || pw -> pw_name == NULL | |
528 || *pw -> pw_name == '\0') { | |
529 #endif /* __CYGWIN32__ */ | |
530 #else /* KPOP */ | |
531 uid = getuid (); | |
532 if (uid == geteuid () && (cp = getenv ("USER")) != NULL | |
533 && (pw = getpwnam (cp)) != NULL) | |
534 strcpy (username, cp); | |
535 else if ((pw = getpwuid (uid)) == NULL | |
536 || pw -> pw_name == NULL | |
537 || *pw -> pw_name == '\0') { | |
538 #endif /* KPOP */ | |
539 (void) strcpy (username, "unknown"); | |
540 (void) sprintf (fullname, "The Unknown User-ID (%d)", getuid ()); | |
541 return username; | |
542 } | |
543 | |
544 np = pw -> pw_gecos; | |
545 #ifndef GCOS_HACK | |
546 for (cp = fullname; *np && *np != (MMailids ? '<' : ','); *cp++ = *np++) | |
547 continue; | |
548 #else | |
549 for (cp = fullname; *np && *np != (MMailids ? '<' : ','); ) | |
550 if (*np == '&') { /* blech! */ | |
551 (void) strcpy(cp, pw -> pw_name); | |
552 *cp = toupper(*cp); | |
553 while (*cp) | |
554 cp++; | |
555 np++; | |
556 } | |
557 else | |
558 *cp++ = *np++; | |
559 #endif | |
560 *cp = '\0'; | |
561 if (MMailids) { | |
562 if (*np) | |
563 np++; | |
564 for (cp = username; *np && *np != '>'; *cp++ = *np++) | |
565 continue; | |
566 *cp = '\0'; | |
567 } | |
568 if (MMailids == 0 || *np == '\0') | |
569 (void) strcpy (username, pw -> pw_name); | |
570 | |
571 if ((cp = getenv ("SIGNATURE")) && *cp) { | |
572 if (strlen(cp) > BUFSIZ / 4) { | |
573 fprintf(stderr, "SIGNATURE envariable too long\n"); | |
574 exit(1); | |
575 } | |
576 (void) strcpy (fullname, cp); | |
577 } | |
578 if (index(fullname, '.')) { /* quote any .'s */ | |
579 char tmp[BUFSIZ]; | |
580 sprintf (tmp, "\"%s\"", fullname);/* should quote "'s too */ | |
581 strcpy (fullname, tmp); | |
582 } | |
583 | |
584 return username; | |
585 } | |
586 | |
587 | |
588 char *getfullname () { | |
589 if (username[0] == '\0') | |
590 (void) getusr (); | |
591 | |
592 return fullname; | |
593 } | |
594 | |
595 /* */ | |
596 | |
597 #ifdef SYS5 | |
598 #ifndef notdef /* Supposedly this works, I prefer the | |
599 recursive solution... */ | |
600 | |
601 #include <fcntl.h> | |
602 | |
603 int dup2 (d1, d2) | |
604 register int d1, | |
605 d2; | |
606 { | |
607 int d; | |
608 | |
609 if (d1 == d2) | |
610 return OK; | |
611 | |
612 (void) close (d2); | |
613 if ((d = fcntl (d1, F_DUPFD, d2)) == NOTOK) | |
614 return NOTOK; | |
615 if (d == d2) | |
616 return OK; | |
617 | |
618 errno = 0; | |
619 return NOTOK; | |
620 } | |
621 | |
622 #else /* notdef */ | |
623 int dup2 (d1, d2) | |
624 register int d1, | |
625 d2; | |
626 { | |
627 if (d1 == d2) | |
628 return OK; | |
629 | |
630 (void) close (d2); | |
631 return dup2aux (d1, d2); | |
632 } | |
633 | |
634 | |
635 static int dup2aux (d1, d2) | |
636 register int d1, | |
637 d2; | |
638 { | |
639 int d, | |
640 i, | |
641 eindex; | |
642 | |
643 if ((d = dup (d1)) == NOTOK) | |
644 return NOTOK; | |
645 if (d == d2) | |
646 return OK; | |
647 | |
648 i = dup2aux (d1, d2); | |
649 eindex = errno; | |
650 (void) close (d); | |
651 errno = eindex; | |
652 return i; | |
653 } | |
654 #endif /* notdef */ | |
655 #endif /* SYS5 */ | |
656 | |
657 struct hostent * | |
658 mh_gethostbyname(name) | |
659 char *name; | |
660 { | |
661 struct hostent *xx; | |
662 #if (defined(SOLARIS) && SOLARIS < 20400) || (defined(sony_news) && defined(__svr4)) | |
663 # if SOLARIS == 20300 | |
664 static struct hostent hp; | |
665 static char buf[1000]; | |
666 extern struct hostent *_switch_gethostbyname_r(); | |
667 | |
668 xx = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); | |
669 # else | |
670 extern struct hostent *__switch_gethostbyname(); | |
671 | |
672 xx = __switch_gethostbyname(name); | |
673 # endif /* Solaris 2.3 */ | |
674 #else /* SOLARIS */ | |
675 | |
676 xx = gethostbyname(name); | |
677 #endif /* SOLARIS */ | |
678 | |
679 return xx; | |
680 } | |
681 | |
682 #ifdef __CYGWIN32__ | |
683 void sethostent(x) | |
684 int x; | |
685 { | |
686 } | |
687 #endif |