X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/374ece2e88368afd6e0a29c4ee4b75ffa9e28b39..9ef6b510ada8a7d3b053ebaef0686570ebf00f63:/sbr/mts.c?ds=inline diff --git a/sbr/mts.c b/sbr/mts.c index bf7d42b1..4c95f481 100644 --- a/sbr/mts.c +++ b/sbr/mts.c @@ -1,21 +1,19 @@ - -/* - * mts.c -- definitions for the mail transport system +/* mts.c -- definitions for the mail transport system * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for * complete copyright information. */ -#include /* for snprintf() */ -#include -#include +#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 -#include -#include +#include "h/mts.h" #include #include #include @@ -23,10 +21,10 @@ /* * static prototypes */ -static char *tailor_value (unsigned char *); +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); /* @@ -40,8 +38,6 @@ 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 = ""; @@ -51,19 +47,21 @@ char *mmdflfil = ""; 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 */ static char *mts_method = "smtp"; -int sm_mts = MTS_SENDMAIL_SMTP; +int sm_mts = MTS_SMTP; char *sendmail = SENDMAILPATH; /* @@ -79,13 +77,6 @@ char *pophost = ""; char *maildelivery = nmhetcdir(/maildelivery); -/* - * Aliasing Facility (doesn't belong here) - */ -int Everyone = NOTOK; -static char *everyone = "-1"; -char *NoShell = ""; - /* * Customize the MTS settings for nmh by adjusting * the file mts.conf in the nmh etc directory. @@ -102,10 +93,9 @@ static struct bind binds[] = { { "systemname", &systemname }, { "mmdfldir", &mmdfldir }, { "mmdflfil", &mmdflfil }, + { "spoollocking", &spoollocking }, { "uucpldir", &uucpldir }, { "uucplfil", &uucplfil }, - { "mmdelim1", &mmdlm1 }, - { "mmdelim2", &mmdlm2 }, { "mts", &mts_method }, { "sendmail", &sendmail }, { "clientname", &clientname }, @@ -113,27 +103,26 @@ static struct bind binds[] = { { "pophost", &pophost }, { "maildelivery", &maildelivery }, - { "everyone", &everyone }, - { "noshell", &NoShell }, { NULL, NULL } }; /* Convert name of mts method to integer value and store it. */ void -save_mts_method (const char *value) { - if (! mh_strcasecmp (value, "smtp")) { +save_mts_method (const char *value) +{ + if (! strcasecmp (value, "smtp")) { mts_method = "smtp"; sm_mts = MTS_SMTP; - } else if (! mh_strcasecmp (value, "sendmail/smtp") || - ! mh_strcasecmp (value, "sendmail")) { + } else if (! strcasecmp (value, "sendmail/smtp") || + ! strcasecmp (value, "sendmail")) { mts_method = "sendmail/smtp"; sm_mts = MTS_SENDMAIL_SMTP; - } else if (! mh_strcasecmp (value, "sendmail/pipe")) { + } else if (! strcasecmp (value, "sendmail/pipe")) { mts_method = "sendmail/pipe"; sm_mts = MTS_SENDMAIL_PIPE; } else { - adios (NULL, "unsupported mts selection \"%s\"", value); + die("unsupported mts selection \"%s\"", value); } } @@ -144,31 +133,41 @@ save_mts_method (const char *value) { */ void -mts_init (char *name) +mts_init (void) { - const char *cp; - FILE *fp; - static int inited = 0; - NMH_UNUSED (name); + 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); - Everyone = atoi (everyone); + 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 '\\' /* @@ -177,12 +176,11 @@ mts_init (char *name) */ static char * -tailor_value (unsigned char *s) +tailor_value (char *s) { int i, r; char *bp; char buffer[BUFSIZ]; - size_t len; for (bp = buffer; *s; bp++, s++) { if (*s != QUOTE) { @@ -195,18 +193,19 @@ tailor_value (unsigned char *s) case 't': *bp = '\t'; break; case 0: s--; - case QUOTE: + /* FALLTHRU */ + case QUOTE: *bp = QUOTE; break; - default: - if (!isdigit (*s)) { + default: + if (!isdigit ((unsigned char) *s)) { *bp++ = QUOTE; *bp = *s; } - r = *s != '0' ? 10 : 8; - for (i = 0; isdigit (*s); s++) - i = i * r + *s - '0'; + r = ((unsigned char) *s) != '0' ? 10 : 8; + for (i = 0; isdigit ((unsigned char) *s); s++) + i *= r + ((unsigned char) *s) - '0'; s--; *bp = toascii (i); break; @@ -215,11 +214,7 @@ tailor_value (unsigned char *s) } *bp = 0; - len = strlen (buffer) + 1; - bp = mh_xmalloc (len); - memcpy (bp, buffer, len); - - return bp; + return mh_xstrdup(buffer); } /* @@ -239,7 +234,7 @@ LocalName (int flag) struct addrinfo hints, *res; if (flag < 0 || flag > 1) - return NULL; + return NULL; buf = buffer[flag]; @@ -247,7 +242,7 @@ LocalName (int flag) if (buf[0]) return buf; - mts_init ("mts"); + mts_init (); /* check if the mts.conf file specifies a "localname" */ if (*localname && flag == 0) { @@ -258,7 +253,7 @@ LocalName (int 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) { @@ -294,7 +289,7 @@ SystemName (void) if (buffer[0]) return buffer; - mts_init ("mts"); + mts_init (); /* check if mts.conf file specifies a "systemname" */ if (*systemname) { @@ -310,15 +305,19 @@ SystemName (void) /* * 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; } @@ -347,21 +346,20 @@ char * 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 getuserinfo (void) { - register unsigned char *cp; - register char *np; - register struct passwd *pw; + char *cp, *np; + struct passwd *pw; if ((pw = getpwuid (getuid ())) == NULL || pw->pw_name == NULL @@ -372,38 +370,12 @@ getuserinfo (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 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; @@ -417,52 +389,62 @@ getuserinfo (void) /* 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 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, '>'); + + strncpy(localmbox, np, sizeof(localmbox)); - /* localmbox, if not using Local-Mailbox */ - if (localmbox[0] == '\0') { + 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) { - unsigned char *bp; - char *cp, buffer[BUFSIZ]; + char *bp, *cp, buffer[BUFSIZ]; struct bind *b; while (fgets (buffer, sizeof(buffer), fp)) { @@ -474,7 +456,7 @@ mts_read_conf_file (FILE *fp) if (!(bp = strchr(buffer, ':'))) break; *bp++ = 0; - while (isspace (*bp)) + while (isspace ((unsigned char) *bp)) *bp++ = 0; for (b = binds; b->keyword; b++)