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