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