* complete copyright information.
*/
-#include <h/mh.h> /* for snprintf() */
-#include <h/utils.h>
+#include "h/mh.h"
+#include "escape_addresses.h"
+#include "context_find.h"
+#include "error.h"
+#include "h/utils.h"
#define nmhetcdir(file) NMHETCDIR#file
-#include <h/mts.h>
+#include "h/mts.h"
#include <pwd.h>
#include <sys/socket.h>
#include <netdb.h>
/*
* static prototypes
*/
+static void read_mts(const char *path);
static char *tailor_value (char *);
static void getuserinfo (void);
-static const char *get_mtsconf_pathname(void);
-static const char *get_mtsuserconf_pathname(void);
+static const char *get_optional_env_var(const char *name, const char *fallback);
static void mts_read_conf_file (FILE *fp);
/*
/*
* nmh mail transport interface customization file
*/
-static char *mtsconf = nmhetcdir(/mts.conf);
-
static char *localname = "";
static char *localdomain = "";
static char *systemname = "";
char *uucpldir = "/usr/spool/mail";
char *uucplfil = "";
-char *mmdlm1 = "\001\001\001\001\n";
-char *mmdlm2 = "\001\001\001\001\n";
-
char *spoollocking = DEFAULT_LOCKING;
-/* Cache the username, fullname, and mailbox of the user */
+/* Cache the username, fullname, mailbox name, and mailbox of the user */
static char username[BUFSIZ];
static char fullname[BUFSIZ];
-static char localmbox[BUFSIZ];
+/* mboxname comes from a Local-Mailbox profile component, or if that
+ doesn't exist, the username. */
+static char mboxname[BUFSIZ];
+static char localmbox[2*BUFSIZ+3];
/*
* MTS specific variables
{ "spoollocking", &spoollocking },
{ "uucpldir", &uucpldir },
{ "uucplfil", &uucplfil },
- { "mmdelim1", &mmdlm1 },
- { "mmdelim2", &mmdlm2 },
{ "mts", &mts_method },
{ "sendmail", &sendmail },
{ "clientname", &clientname },
/* Convert name of mts method to integer value and store it. */
void
-save_mts_method (const char *value) {
+save_mts_method (const char *value)
+{
if (! strcasecmp (value, "smtp")) {
mts_method = "smtp";
sm_mts = MTS_SMTP;
mts_method = "sendmail/pipe";
sm_mts = MTS_SENDMAIL_PIPE;
} else {
- adios (NULL, "unsupported mts selection \"%s\"", value);
+ die("unsupported mts selection \"%s\"", value);
}
}
void
mts_init (void)
{
- const char *cp;
- FILE *fp;
- static int inited = 0;
+ static bool deja_vu;
+ const char *path;
- if (inited++ || (fp = fopen (get_mtsconf_pathname(), "r")) == NULL)
- return;
- mts_read_conf_file(fp);
- fclose (fp);
+ if (deja_vu)
+ return;
+ deja_vu = true;
- cp = get_mtsuserconf_pathname();
- if (cp != NULL &&
- ((fp = fopen (get_mtsuserconf_pathname(), "r")) != NULL)) {
- mts_read_conf_file(fp);
- fclose (fp);
- }
+ path = get_optional_env_var("MHMTSCONF", NMHETCDIR "/mts.conf");
+ read_mts(path);
+
+ path = get_optional_env_var("MHMTSUSERCONF", NULL);
+ if (path)
+ read_mts(path);
save_mts_method (mts_method);
}
+static void read_mts(const char *path)
+{
+ FILE *fp;
+
+ fp = fopen(path, "r");
+ if (!fp)
+ adios(path, "error opening mts.conf:");
+ mts_read_conf_file(fp);
+ if (ferror(fp))
+ adios(path, "error reading mts.conf:");
+ if (fclose(fp))
+ adios(path, "error closing mts.conf:");
+}
+
+
#define QUOTE '\\'
/*
case 0: s--;
/* FALLTHRU */
- case QUOTE:
+ case QUOTE:
*bp = QUOTE;
break;
- default:
+ default:
if (!isdigit ((unsigned char) *s)) {
*bp++ = QUOTE;
*bp = *s;
struct addrinfo hints, *res;
if (flag < 0 || flag > 1)
- return NULL;
+ return NULL;
buf = buffer[flag];
gethostname (buf, sizeof(buffer0) - 1);
/* now fully qualify our name */
- memset(&hints, 0, sizeof(hints));
+ ZERO(&hints);
hints.ai_flags = AI_CANONNAME;
hints.ai_family = PF_UNSPEC;
if (getaddrinfo(buf, NULL, &hints, &res) == 0) {
/*
* Get the username of current user
+ *
+ * If flag is 0, then attempt to extract username from Local-Mailbox profile
+ * component, if present.
+ * If flag is 1, then only use the "proper" local hostname.
*/
char *
-getusername (void)
+getusername (int flag)
{
if (username[0] == '\0')
getuserinfo();
- return username;
+ return flag == 0 ? mboxname : username;
}
getlocalmbox (void)
{
if (username[0] == '\0')
- getuserinfo();
+ getuserinfo();
return localmbox;
}
/*
- * Find the user's username and full name, and cache them.
+ * Find and cache the user's username, full name, and local mbox.
*/
static void
return;
}
-
/* username */
- /* If there's a Local-Mailbox profile component, try to extract
- the username from it. But don't try very hard, this assumes
- the very simple User Name <user@name.com> form.
- Note that post(8) and whom(1) use context_foil (), so they
- won't see the profile component. */
- if ((np = context_find("Local-Mailbox")) != NULL) {
- char *left_angle_bracket = strchr (np, '<');
- char *at_sign = strchr (np, '@');
- char *right_angle_bracket = strchr (np, '>');
-
- strncpy(localmbox, np, sizeof(localmbox));
-
- if (left_angle_bracket && at_sign && right_angle_bracket) {
- if (at_sign > left_angle_bracket &&
- at_sign - left_angle_bracket < BUFSIZ) {
- strncpy(username, left_angle_bracket + 1,
- at_sign - left_angle_bracket - 1);
- }
- }
- }
-
if (username[0] == '\0') {
strncpy (username, pw->pw_name, sizeof(username));
}
-
username[sizeof(username) - 1] = '\0';
- escape_local_part(username, sizeof(username));
-
-
/* fullname */
np = pw->pw_gecos;
/* The $SIGNATURE environment variable overrides the GECOS field's idea of
your real name. If SIGNATURE isn't set, use the Signature profile
setting if it exists.
- Note that post(8) and whom(1) use context_foil (), so they
- won't see the profile component. */
+ Note that post(8) uses context_foil(), so it won't see the profile
+ component. */
if ((cp = getenv ("SIGNATURE")) && *cp)
strncpy (fullname, cp, sizeof(fullname));
else if ((cp = context_find("Signature")))
- strncpy (fullname, cp, sizeof(fullname));
-
+ strncpy (fullname, cp, sizeof(fullname));
fullname[sizeof(fullname) - 1] = '\0';
-
escape_display_name(fullname, sizeof(fullname));
+ /* localmbox and mboxname */
+ /* If there's a Local-Mailbox profile component, try to extract
+ the username from it. But don't try very hard, this assumes
+ the very simple User Name <user@name.com> form.
+ Note that post(8) uses context_foil(), so it won't see the profile
+ component. */
+ if ((np = context_find("Local-Mailbox")) != NULL) {
+ char *left_angle_bracket = strchr (np, '<');
+ char *at_sign = strchr (np, '@');
+ char *right_angle_bracket = strchr (np, '>');
- /* localmbox, if not using Local-Mailbox */
- if (localmbox[0] == '\0') {
+ strncpy(localmbox, np, sizeof(localmbox));
+
+ if (left_angle_bracket && at_sign && right_angle_bracket) {
+ if (at_sign > left_angle_bracket &&
+ at_sign - left_angle_bracket < BUFSIZ) {
+ strncpy(mboxname, left_angle_bracket + 1,
+ at_sign - left_angle_bracket - 1);
+ }
+ }
+ } else {
snprintf(localmbox, sizeof(localmbox), "%s <%s@%s>", fullname,
username, LocalName(0));
}
-
localmbox[sizeof(localmbox) - 1] = '\0';
-}
-
-static const char*
-get_mtsconf_pathname (void)
-{
- const char *cp = getenv ( "MHMTSCONF" );
- if (cp != NULL && *cp != '\0') {
- return cp;
+ if (mboxname[0] == '\0') {
+ strncpy (mboxname, username, sizeof(mboxname));
}
- return mtsconf;
+ mboxname[sizeof(mboxname) - 1] = '\0';
+ escape_local_part(mboxname, sizeof(mboxname));
}
-static const char*
-get_mtsuserconf_pathname (void)
+
+static const char *
+get_optional_env_var(const char *name, const char *fallback)
{
- const char *cp = getenv ( "MHMTSUSERCONF" );
- if (cp != NULL && *cp != '\0') {
- return cp;
- }
- return NULL;
+ const char *v = getenv(name);
+ if (v)
+ return v;
+ return fallback;
}
+
static void
mts_read_conf_file (FILE *fp)
{