]> diplodocus.org Git - nmh/blob - zotnet/mts/mts.c
sunos/solaris modifications
[nmh] / zotnet / mts / mts.c
1
2 /*
3 * mts.c -- definitions for the mail transport system
4 *
5 * $Id$
6 */
7
8 #include <h/nmh.h>
9
10 #define nmhetcdir(file) NMHETCDIR#file
11
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <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 extern int errno;
26
27 /*
28 * static prototypes
29 */
30 static char *tailor_value (char *);
31 static void getuserinfo (void);
32
33 /*
34 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
35 * are kept in the user's home directory, then these should be empty
36 * strings. In this case, the appropriate ...lfil array should contain
37 * the name of the file in the user's home directory. Usually, this is
38 * something like ".mail".
39 */
40
41 /*
42 * nmh mail transport interface customization file
43 */
44 static char *mtsconf = nmhetcdir(/mts.conf);
45
46 static char *localname = "";
47 static char *localdomain = "";
48 static char *systemname = "";
49
50 char *mmdfldir = MAILSPOOL;
51 char *mmdflfil = "";
52 char *uucpldir = "/usr/spool/mail";
53 char *uucplfil = "";
54
55 char *mmdlm1 = "\001\001\001\001\n";
56 char *mmdlm2 = "\001\001\001\001\n";
57
58 /* Cache the username and fullname of the user */
59 static char username[BUFSIZ];
60 static char fullname[BUFSIZ];
61
62 /* variables for username masquerading */
63 static int MMailids = 0;
64 static char *mmailid = "0";
65
66
67 /*
68 * MTS specific variables
69 */
70 #if defined(SENDMTS) || defined(SMTPMTS)
71 char *hostable = nmhetcdir(/hosts);
72 char *sendmail = SENDMAILPATH;
73 #endif
74
75 /*
76 * SMTP/POP stuff
77 */
78 char *clientname = NULL;
79 char *servers = "localhost \01localnet";
80 char *pophost = "";
81
82 /*
83 * BBoards-specific variables
84 */
85 char *bb_domain = "";
86
87
88 /*
89 * POP BBoards-specific variables
90 */
91 #ifdef BPOP
92 char *popbbhost = "";
93 char *popbbuser = "";
94 char *popbblist = nmhetcdir(/hosts.popbb);
95 #endif /* BPOP */
96
97 /*
98 * Global MailDelivery file
99 */
100 char *maildelivery = nmhetcdir(/maildelivery);
101
102
103 /*
104 * Aliasing Facility (doesn't belong here)
105 */
106 int Everyone = NOTOK;
107 static char *everyone = "-1";
108 char *NoShell = "";
109
110 /*
111 * Customize the MTS settings for nmh by adjusting
112 * the file mts.conf in the nmh etc directory.
113 */
114
115 struct bind {
116 char *keyword;
117 char **value;
118 };
119
120 static struct bind binds[] = {
121 { "localname", &localname },
122 { "localdomain", &localdomain },
123 { "systemname", &systemname },
124 { "mmdfldir", &mmdfldir },
125 { "mmdflfil", &mmdflfil },
126 { "uucpldir", &uucpldir },
127 { "uucplfil", &uucplfil },
128 { "mmdelim1", &mmdlm1 },
129 { "mmdelim2", &mmdlm2 },
130 { "mmailid", &mmailid },
131
132 #if defined(SENDMTS) || defined(SMTPMTS)
133 { "hostable", &hostable },
134 #endif
135
136 #ifdef SENDMTS
137 { "sendmail", &sendmail },
138 #endif
139
140 { "clientname", &clientname },
141 { "servers", &servers },
142 { "pophost", &pophost },
143 { "bbdomain", &bb_domain },
144
145 #ifdef BPOP
146 { "popbbhost", &popbbhost },
147 { "popbbuser", &popbbuser },
148 { "popbblist", &popbblist },
149 #endif
150
151 #ifdef NNTP
152 { "nntphost", &popbbhost },
153 #endif
154
155 { "maildelivery", &maildelivery },
156 { "everyone", &everyone },
157 { "noshell", &NoShell },
158 { NULL, NULL }
159 };
160
161
162 /*
163 * Read the configuration file for the nmh interface
164 * to the mail transport system (MTS).
165 */
166
167 void
168 mts_init (char *name)
169 {
170 char *bp, *cp, buffer[BUFSIZ];
171 struct bind *b;
172 FILE *fp;
173 static int inited = 0;
174
175 if (inited++ || (fp = fopen (mtsconf, "r")) == NULL)
176 return;
177
178 while (fgets (buffer, sizeof(buffer), fp)) {
179 if (!(cp = strchr(buffer, '\n')))
180 break;
181 *cp = 0;
182 if (*buffer == '#' || *buffer == '\0')
183 continue;
184 if (!(bp = strchr(buffer, ':')))
185 break;
186 *bp++ = 0;
187 while (isspace (*bp))
188 *bp++ = 0;
189
190 for (b = binds; b->keyword; b++)
191 if (!strcmp (buffer, b->keyword))
192 break;
193 if (b->keyword && (cp = tailor_value (bp)))
194 *b->value = cp;
195 }
196
197 fclose (fp);
198 MMailids = atoi (mmailid);
199 Everyone = atoi (everyone);
200 }
201
202
203 #define QUOTE '\\'
204
205 /*
206 * Convert escaped values, malloc some new space,
207 * and copy string to malloc'ed memory.
208 */
209
210 static char *
211 tailor_value (char *s)
212 {
213 int i, r;
214 char *bp;
215 char buffer[BUFSIZ];
216 size_t len;
217
218 for (bp = buffer; *s; bp++, s++) {
219 if (*s != QUOTE) {
220 *bp = *s;
221 } else {
222 switch (*++s) {
223 case 'b': *bp = '\b'; break;
224 case 'f': *bp = '\f'; break;
225 case 'n': *bp = '\n'; break;
226 case 't': *bp = '\t'; break;
227
228 case 0: s--;
229 case QUOTE:
230 *bp = QUOTE;
231 break;
232
233 default:
234 if (!isdigit (*s)) {
235 *bp++ = QUOTE;
236 *bp = *s;
237 }
238 r = *s != '0' ? 10 : 8;
239 for (i = 0; isdigit (*s); s++)
240 i = i * r + *s - '0';
241 s--;
242 *bp = toascii (i);
243 break;
244 }
245 }
246 }
247 *bp = 0;
248
249 len = strlen (buffer) + 1;
250 if ((bp = malloc (len)))
251 memcpy (bp, buffer, len);
252
253 return bp;
254 }
255
256 /*
257 * Get the fully qualified name of the local host.
258 */
259
260 char *
261 LocalName (void)
262 {
263 static char buffer[BUFSIZ] = "";
264 struct hostent *hp;
265
266 #ifdef HAVE_UNAME
267 struct utsname name;
268 #endif
269
270 /* check if we have cached the local name */
271 if (buffer[0])
272 return buffer;
273
274 mts_init ("mts");
275
276 /* check if the mts.conf file specifies a "localname" */
277 if (*localname) {
278 strncpy (buffer, localname, sizeof(buffer));
279 } else {
280 #ifdef HAVE_UNAME
281 /* first get our local name */
282 uname (&name);
283 strncpy (buffer, name.nodename, sizeof(buffer));
284 #else
285 /* first get our local name */
286 gethostname (buffer, sizeof(buffer));
287 #endif
288 #ifdef HAVE_SETHOSTENT
289 sethostent (1);
290 #endif
291 /* now fully qualify our name */
292 if ((hp = gethostbyname (buffer)))
293 strncpy (buffer, hp->h_name, sizeof(buffer));
294 }
295
296 /*
297 * If the mts.conf file specifies a "localdomain",
298 * we append that now. This should rarely be needed.
299 */
300 if (*localdomain) {
301 strcat (buffer, ".");
302 strcat (buffer, localdomain);
303 }
304
305 return buffer;
306 }
307
308
309 /*
310 * This is only for UUCP mail. It gets the hostname
311 * as part of the UUCP "domain".
312 */
313
314 char *
315 SystemName (void)
316 {
317 static char buffer[BUFSIZ] = "";
318
319 #ifdef HAVE_UNAME
320 struct utsname name;
321 #endif
322
323 /* check if we have cached the system name */
324 if (buffer[0])
325 return buffer;
326
327 mts_init ("mts");
328
329 /* check if mts.conf file specifies a "systemname" */
330 if (*systemname) {
331 strncpy (buffer, systemname, sizeof(buffer));
332 return buffer;
333 }
334
335 #ifdef HAVE_UNAME
336 uname (&name);
337 strncpy (buffer, name.nodename, sizeof(buffer));
338 #else
339 gethostname (buffer, sizeof(buffer));
340 #endif
341
342 return buffer;
343 }
344
345
346 /*
347 * Get the username of current user
348 */
349
350 char *
351 getusername (void)
352 {
353 if (username[0] == '\0')
354 getuserinfo();
355
356 return username;
357 }
358
359
360 /*
361 * Get full name of current user (typically from GECOS
362 * field of password file).
363 */
364
365 char *
366 getfullname (void)
367 {
368 if (username[0] == '\0')
369 getuserinfo();
370
371 return fullname;
372 }
373
374
375 /*
376 * Find the user's username and full name, and cache them.
377 * It also handles mmailid processing (username masquerading)
378 */
379
380 static void
381 getuserinfo (void)
382 {
383 register char *cp, *np;
384 register struct passwd *pw;
385
386 #ifdef KPOP
387 uid_t uid;
388
389 uid = getuid ();
390 if (uid == geteuid () && (cp = getenv ("USER")) != NULL
391 && (pw = getpwnam (cp)) != NULL)
392 strncpy (username, cp, sizeof(username));
393 else if ((pw = getpwuid (uid)) == NULL
394 || pw->pw_name == NULL
395 || *pw->pw_name == '\0') {
396 #else /* KPOP */
397 if ((pw = getpwuid (getuid ())) == NULL
398 || pw->pw_name == NULL
399 || *pw->pw_name == '\0') {
400 #endif /* KPOP */
401
402 strncpy (username, "unknown", sizeof(username));
403 snprintf (fullname, sizeof(fullname), "The Unknown User-ID (%d)",
404 (int) getuid ());
405 return;
406 }
407
408 np = pw->pw_gecos;
409
410 /*
411 * Do mmailid (username masquerading) processing. The GECOS
412 * field should have the form "Full Name <fakeusername>".
413 */
414 #ifndef GCOS_HACK
415 for (cp = fullname; *np && *np != (MMailids ? '<' : ','); *cp++ = *np++)
416 continue;
417 #else
418 for (cp = fullname; *np && *np != (MMailids ? '<' : ','); ) {
419 if (*np == '&') { /* blech! */
420 strcpy (cp, pw->pw_name);
421 *cp = toupper(*cp);
422 while (*cp)
423 cp++;
424 np++;
425 } else {
426 *cp++ = *np++;
427 }
428 }
429 #endif
430
431 *cp = '\0';
432 if (MMailids) {
433 if (*np)
434 np++;
435 for (cp = username; *np && *np != '>'; *cp++ = *np++)
436 continue;
437 *cp = '\0';
438 }
439 if (MMailids == 0 || *np == '\0')
440 strncpy (username, pw->pw_name, sizeof(username));
441
442 if ((cp = getenv ("SIGNATURE")) && *cp)
443 strncpy (fullname, cp, sizeof(fullname));
444
445 if (strchr(fullname, '.')) { /* quote any .'s */
446 char tmp[BUFSIZ];
447
448 /* should quote "'s too */
449 snprintf (tmp, sizeof(tmp), "\"%s\"", fullname);
450 strncpy (fullname, tmp, sizeof(fullname));
451 }
452
453 return;
454 }