Removed mts.conf; the maildelivery option went into slocal directly.
[mmh] / sbr / mts.c
1 /*
2 ** mts.c -- definitions for the mail transport system
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>   /* for snprintf() */
10 #include <h/nmh.h>
11 #include <h/utils.h>
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <h/mts.h>
15 #include <pwd.h>
16 #include <netdb.h>
17
18 #ifdef HAVE_SYS_UTSNAME_H
19 # include <sys/utsname.h>
20 #endif
21
22 #define NOTOK  (-1)
23 #define OK     0
24
25 /*
26 ** static prototypes
27 */
28 static void getuserinfo(void);
29
30 /* Cache the username and fullname of the user */
31 static char username[BUFSIZ];
32 static char fullname[BUFSIZ];
33
34
35 /*
36 ** Get the fully qualified name of the local host.
37 */
38 char *
39 LocalName(void)
40 {
41         static char buffer[BUFSIZ] = "";
42         struct addrinfo hints, *res;
43 #ifdef HAVE_UNAME
44         struct utsname name;
45 #endif
46
47         /* check if we have cached the local name */
48         if (buffer[0])
49                 return buffer;
50
51         memset(buffer, 0, sizeof(buffer));
52 #ifdef HAVE_UNAME
53         /* first get our local name */
54         uname(&name);
55         strncpy(buffer, name.nodename, sizeof(buffer) - 1);
56 #else
57         /* first get our local name */
58         gethostname(buffer, sizeof(buffer) - 1);
59 #endif
60         /* now fully qualify our name */
61
62         memset(&hints, 0, sizeof(hints));
63         hints.ai_flags = AI_CANONNAME;
64         hints.ai_family = PF_UNSPEC;
65         if (getaddrinfo(buffer, NULL, &hints, &res) == 0) {
66                 strncpy(buffer, res->ai_canonname, sizeof(buffer) - 1);
67                 freeaddrinfo(res);
68         }
69
70         return buffer;
71 }
72
73
74 /*
75 ** This is only for UUCP mail.  It gets the hostname
76 ** as part of the UUCP "domain".
77 */
78 char *
79 SystemName(void)
80 {
81         static char buffer[BUFSIZ] = "";
82
83 #ifdef HAVE_UNAME
84         struct utsname name;
85 #endif
86
87         /* check if we have cached the system name */
88         if (buffer[0])
89                 return buffer;
90
91 #ifdef HAVE_UNAME
92         uname(&name);
93         strncpy(buffer, name.nodename, sizeof(buffer));
94 #else
95         gethostname(buffer, sizeof(buffer));
96 #endif
97
98         return buffer;
99 }
100
101
102 /*
103 ** Get the username of current user
104 */
105 char *
106 getusername(void)
107 {
108         if (username[0] == '\0')
109                 getuserinfo();
110
111         return username;
112 }
113
114
115 /*
116 ** Get full name of current user (typically from GECOS
117 ** field of password file).
118 */
119 char *
120 getfullname(void)
121 {
122         if (username[0] == '\0')
123                 getuserinfo();
124
125         return fullname;
126 }
127
128
129 /*
130 ** Find the user's username and full name, and cache them.
131 */
132 static void
133 getuserinfo(void)
134 {
135         register unsigned char *cp;
136         register char *np;
137         register struct passwd *pw;
138
139         if ((pw = getpwuid(getuid())) == NULL
140                 || pw->pw_name == NULL
141                 || *pw->pw_name == '\0') {
142                 strncpy(username, "unknown", sizeof(username));
143                 snprintf(fullname, sizeof(fullname), "The Unknown User-ID (%d)",
144                         (int) getuid());
145                 return;
146         }
147
148         np = pw->pw_gecos;
149
150         /*
151         ** Get the user's real name from the GECOS field.  Stop once
152         ** we hit a ',', which some OSes use to separate other 'finger'
153         ** information in the GECOS field, like phone number.
154         */
155         for (cp = fullname; *np != '\0' && *np != ',';) {
156 #ifndef BSD42
157                 *cp++ = *np++;
158 #else /* BSD42 */
159                 /*
160                 ** On BSD(-derived) systems, the system utilities that
161                 ** deal with the GECOS field (finger, mail, sendmail,
162                 ** etc.) translate any '&' character in it to the login name,
163                 ** with the first letter capitalized.  So, for instance,
164                 ** fingering a user "bob" with the GECOS field "& Jones"
165                 ** would reveal him to be "In real life: Bob Jones".
166                 ** Surprisingly, though, the OS doesn't do the translation
167                 ** for you, so we have to do it manually here.
168                 */
169                 if (*np == '&') {  /* blech! */
170                         strcpy(cp, pw->pw_name);
171                         *cp = toupper(*cp);
172                         while (*cp)
173                                 cp++;
174                         np++;
175                 } else {
176                         *cp++ = *np++;
177                 }
178 #endif /* BSD42 */
179         }
180         *cp = '\0';
181         strncpy(username, pw->pw_name, sizeof(username));
182
183         /*
184         ** The $SIGNATURE environment variable overrides the GECOS field's
185         ** idea of your real name.
186         */
187         if ((cp = getenv("SIGNATURE")) && *cp)
188                 strncpy(fullname, cp, sizeof(fullname));
189
190         if (strchr(fullname, '.')) {  /*  quote any .'s */
191                 char tmp[BUFSIZ];
192
193                 /* should quote "'s too */
194                 snprintf(tmp, sizeof(tmp), "\"%s\"", fullname);
195                 strncpy(fullname, tmp, sizeof(fullname));
196         }
197
198         return;
199 }