]>
diplodocus.org Git - nmh/blob - sbr/mts.c
4c95f481c60959c56bf086e0d18cf3f5b1ec0c4f
1 /* mts.c -- definitions for the mail transport system
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
9 #include "escape_addresses.h"
10 #include "context_find.h"
14 #define nmhetcdir(file) NMHETCDIR#file
18 #include <sys/socket.h>
24 static void read_mts(const char *path
);
25 static char *tailor_value (char *);
26 static void getuserinfo (void);
27 static const char *get_optional_env_var(const char *name
, const char *fallback
);
28 static void mts_read_conf_file (FILE *fp
);
31 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
32 * are kept in the user's home directory, then these should be empty
33 * strings. In this case, the appropriate ...lfil array should contain
34 * the name of the file in the user's home directory. Usually, this is
35 * something like ".mail".
39 * nmh mail transport interface customization file
41 static char *localname
= "";
42 static char *localdomain
= "";
43 static char *systemname
= "";
45 char *mmdfldir
= MAILSPOOL
;
47 char *uucpldir
= "/usr/spool/mail";
50 char *spoollocking
= DEFAULT_LOCKING
;
52 /* Cache the username, fullname, mailbox name, and mailbox of the user */
53 static char username
[BUFSIZ
];
54 static char fullname
[BUFSIZ
];
55 /* mboxname comes from a Local-Mailbox profile component, or if that
56 doesn't exist, the username. */
57 static char mboxname
[BUFSIZ
];
58 static char localmbox
[2*BUFSIZ
+3];
61 * MTS specific variables
63 static char *mts_method
= "smtp";
64 int sm_mts
= MTS_SMTP
;
65 char *sendmail
= SENDMAILPATH
;
70 char *clientname
= NULL
;
71 char *servers
= "localhost";
75 * Global MailDelivery file
77 char *maildelivery
= nmhetcdir(/maildelivery
);
81 * Customize the MTS settings for nmh by adjusting
82 * the file mts.conf in the nmh etc directory.
90 static struct bind binds
[] = {
91 { "localname", &localname
},
92 { "localdomain", &localdomain
},
93 { "systemname", &systemname
},
94 { "mmdfldir", &mmdfldir
},
95 { "mmdflfil", &mmdflfil
},
96 { "spoollocking", &spoollocking
},
97 { "uucpldir", &uucpldir
},
98 { "uucplfil", &uucplfil
},
99 { "mts", &mts_method
},
100 { "sendmail", &sendmail
},
101 { "clientname", &clientname
},
102 { "servers", &servers
},
103 { "pophost", &pophost
},
105 { "maildelivery", &maildelivery
},
110 /* Convert name of mts method to integer value and store it. */
112 save_mts_method (const char *value
)
114 if (! strcasecmp (value
, "smtp")) {
117 } else if (! strcasecmp (value
, "sendmail/smtp") ||
118 ! strcasecmp (value
, "sendmail")) {
119 mts_method
= "sendmail/smtp";
120 sm_mts
= MTS_SENDMAIL_SMTP
;
121 } else if (! strcasecmp (value
, "sendmail/pipe")) {
122 mts_method
= "sendmail/pipe";
123 sm_mts
= MTS_SENDMAIL_PIPE
;
125 die("unsupported mts selection \"%s\"", value
);
131 * Read the configuration file for the nmh interface
132 * to the mail transport system (MTS).
145 path
= get_optional_env_var("MHMTSCONF", NMHETCDIR
"/mts.conf");
148 path
= get_optional_env_var("MHMTSUSERCONF", NULL
);
152 save_mts_method (mts_method
);
156 static void read_mts(const char *path
)
160 fp
= fopen(path
, "r");
162 adios(path
, "error opening mts.conf:");
163 mts_read_conf_file(fp
);
165 adios(path
, "error reading mts.conf:");
167 adios(path
, "error closing mts.conf:");
174 * Convert escaped values, malloc some new space,
175 * and copy string to malloc'ed memory.
179 tailor_value (char *s
)
185 for (bp
= buffer
; *s
; bp
++, s
++) {
190 case 'b': *bp
= '\b'; break;
191 case 'f': *bp
= '\f'; break;
192 case 'n': *bp
= '\n'; break;
193 case 't': *bp
= '\t'; break;
202 if (!isdigit ((unsigned char) *s
)) {
206 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
207 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
208 i
*= r
+ ((unsigned char) *s
) - '0';
217 return mh_xstrdup(buffer
);
221 * Get the fully qualified name of the local host.
223 * If flag is 0, then use anything out of mts.conf (like localname).
224 * If flag is 1, then only use the "proper" local hostname.
230 static char buffer0
[BUFSIZ
] = "";
231 static char buffer1
[BUFSIZ
] = "";
232 static char *buffer
[] = { buffer0
, buffer1
};
234 struct addrinfo hints
, *res
;
236 if (flag
< 0 || flag
> 1)
241 /* check if we have cached the local name */
247 /* check if the mts.conf file specifies a "localname" */
248 if (*localname
&& flag
== 0) {
249 strncpy (buf
, localname
, sizeof(buffer0
));
251 memset(buf
, 0, sizeof(buffer0
));
252 /* first get our local name */
253 gethostname (buf
, sizeof(buffer0
) - 1);
254 /* now fully qualify our name */
257 hints
.ai_flags
= AI_CANONNAME
;
258 hints
.ai_family
= PF_UNSPEC
;
259 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
260 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
266 * If the mts.conf file specifies a "localdomain",
267 * we append that now. This should rarely be needed.
271 strcat (buf
, localdomain
);
279 * This is only for UUCP mail. It gets the hostname
280 * as part of the UUCP "domain".
286 static char buffer
[BUFSIZ
] = "";
288 /* check if we have cached the system name */
294 /* check if mts.conf file specifies a "systemname" */
296 strncpy (buffer
, systemname
, sizeof(buffer
));
300 gethostname (buffer
, sizeof(buffer
));
307 * Get the username of current user
309 * If flag is 0, then attempt to extract username from Local-Mailbox profile
310 * component, if present.
311 * If flag is 1, then only use the "proper" local hostname.
315 getusername (int flag
)
317 if (username
[0] == '\0')
320 return flag
== 0 ? mboxname
: username
;
325 * Get full name of current user (typically from GECOS
326 * field of password file).
332 if (username
[0] == '\0')
340 * Get the full local mailbox name. This is in the form:
342 * User Name <user@name.com>
348 if (username
[0] == '\0')
355 * Find and cache the user's username, full name, and local mbox.
364 if ((pw
= getpwuid (getuid ())) == NULL
365 || pw
->pw_name
== NULL
366 || *pw
->pw_name
== '\0') {
367 strncpy (username
, "unknown", sizeof(username
));
368 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
374 if (username
[0] == '\0') {
375 strncpy (username
, pw
->pw_name
, sizeof(username
));
377 username
[sizeof(username
) - 1] = '\0';
382 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
383 which some OSes use to separate other 'finger' information in the GECOS
384 field, like phone number. */
385 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
389 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
390 your real name. If SIGNATURE isn't set, use the Signature profile
391 setting if it exists.
392 Note that post(8) uses context_foil(), so it won't see the profile
394 if ((cp
= getenv ("SIGNATURE")) && *cp
)
395 strncpy (fullname
, cp
, sizeof(fullname
));
396 else if ((cp
= context_find("Signature")))
397 strncpy (fullname
, cp
, sizeof(fullname
));
398 fullname
[sizeof(fullname
) - 1] = '\0';
399 escape_display_name(fullname
, sizeof(fullname
));
401 /* localmbox and mboxname */
402 /* If there's a Local-Mailbox profile component, try to extract
403 the username from it. But don't try very hard, this assumes
404 the very simple User Name <user@name.com> form.
405 Note that post(8) uses context_foil(), so it won't see the profile
407 if ((np
= context_find("Local-Mailbox")) != NULL
) {
408 char *left_angle_bracket
= strchr (np
, '<');
409 char *at_sign
= strchr (np
, '@');
410 char *right_angle_bracket
= strchr (np
, '>');
412 strncpy(localmbox
, np
, sizeof(localmbox
));
414 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
415 if (at_sign
> left_angle_bracket
&&
416 at_sign
- left_angle_bracket
< BUFSIZ
) {
417 strncpy(mboxname
, left_angle_bracket
+ 1,
418 at_sign
- left_angle_bracket
- 1);
422 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
423 username
, LocalName(0));
425 localmbox
[sizeof(localmbox
) - 1] = '\0';
426 if (mboxname
[0] == '\0') {
427 strncpy (mboxname
, username
, sizeof(mboxname
));
429 mboxname
[sizeof(mboxname
) - 1] = '\0';
430 escape_local_part(mboxname
, sizeof(mboxname
));
435 get_optional_env_var(const char *name
, const char *fallback
)
437 const char *v
= getenv(name
);
445 mts_read_conf_file (FILE *fp
)
447 char *bp
, *cp
, buffer
[BUFSIZ
];
450 while (fgets (buffer
, sizeof(buffer
), fp
)) {
451 if (!(cp
= strchr(buffer
, '\n')))
454 if (*buffer
== '#' || *buffer
== '\0')
456 if (!(bp
= strchr(buffer
, ':')))
459 while (isspace ((unsigned char) *bp
))
462 for (b
= binds
; b
->keyword
; b
++)
463 if (!strcmp (buffer
, b
->keyword
))
465 if (b
->keyword
&& (cp
= tailor_value (bp
)))