]> diplodocus.org Git - nmh/blobdiff - sbr/mts.c
Remove X.400 address parsing
[nmh] / sbr / mts.c
index c7378c7188b2dbc9f310cb546c2f0a1153cf2d2c..4c95f481c60959c56bf086e0d18cf3f5b1ec0c4f 100644 (file)
--- a/sbr/mts.c
+++ b/sbr/mts.c
@@ -5,12 +5,15 @@
  * 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);
 
 /*
@@ -35,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  = "";
@@ -46,15 +47,15 @@ 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
@@ -95,8 +96,6 @@ static struct bind binds[] = {
     { "spoollocking", &spoollocking },
     { "uucpldir", &uucpldir },
     { "uucplfil", &uucplfil },
-    { "mmdelim1", &mmdlm1 },
-    { "mmdelim2", &mmdlm2 },
     { "mts",      &mts_method },
     { "sendmail", &sendmail  },
     { "clientname",  &clientname },
@@ -110,7 +109,8 @@ static struct bind binds[] = {
 
 /* 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;
@@ -122,7 +122,7 @@ save_mts_method (const char *value) {
         mts_method = "sendmail/pipe";
         sm_mts = MTS_SENDMAIL_PIPE;
     } else {
-        adios (NULL, "unsupported mts selection \"%s\"", value);
+        die("unsupported mts selection \"%s\"", value);
     }
 }
 
@@ -135,26 +135,39 @@ save_mts_method (const char *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   '\\'
 
 /*
@@ -181,11 +194,11 @@ tailor_value (char *s)
 
                case 0: s--;
                    /* FALLTHRU */
-               case QUOTE: 
+               case QUOTE:
                    *bp = QUOTE;
                    break;
 
-               default: 
+               default:
                    if (!isdigit ((unsigned char) *s)) {
                        *bp++ = QUOTE;
                        *bp = *s;
@@ -221,7 +234,7 @@ LocalName (int flag)
     struct addrinfo hints, *res;
 
     if (flag < 0 || flag > 1)
-       return NULL;
+       return NULL;
 
     buf = buffer[flag];
 
@@ -240,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) {
@@ -292,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;
 }
 
 
@@ -329,13 +346,13 @@ 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
@@ -353,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 <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;
 
@@ -398,47 +389,58 @@ 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 <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)
 {