]> granicus.if.org Git - neomutt/commitdiff
Support for $XDG_CONFIG_HOME and $XDG_CONFIG_DIRS
authorMarco Hinz <mh.codebro@gmail.com>
Mon, 8 Aug 2016 12:50:01 +0000 (14:50 +0200)
committerRichard Russon <rich@flatcap.org>
Thu, 18 Aug 2016 21:54:14 +0000 (22:54 +0100)
Add XDG config locations:

  $XDG_CONFIG_HOME/neomutt/config
  $XDG_CONFIG_DIRS/neomutt/config

The default locations are:

  XDG_CONFIG_HOME=$HOME/.config.
  XDG_CONFIG_DIRS=/etc/xdg

Reference:
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

doc/manual.xml.head
init.c
muttlib.c
protos.h

index fd1a9b2f9e81d67c386d0eddb23a721c3b2dc2da..34c4a43353d8df167a2cc621f9f708d0789d1267 100644 (file)
@@ -2361,6 +2361,7 @@ See also the <link linkend="postpone">$postpone</link> quad-option.
       <row><entry>File Location</entry></row>
     </thead>
     <tbody>
+      <row><entry>$XDG_CONFIG_DIRS/neomutt/config</entry></row>
       <row><entry>/etc/NeoMuttrc</entry></row>
       <row><entry>/etc/Muttrc-1.6.2-neo</entry></row>
       <row><entry>/etc/Muttrc</entry></row>
@@ -2370,6 +2371,10 @@ See also the <link linkend="postpone">$postpone</link> quad-option.
   </tgroup>
 </table>
 
+<para>
+  <emphasis>($XDG_CONFIG_DIRS defaults to "/etc/xdg".)</emphasis>
+</para>
+
 <para>
   Mutt will search for a user config file in several places in your home
   directory.  The filenames may depend on the version number of Mutt.  Mutt
@@ -2388,6 +2393,7 @@ See also the <link linkend="postpone">$postpone</link> quad-option.
       <row><entry>File Location</entry></row>
     </thead>
     <tbody>
+      <row><entry>$XDG_CONFIG_HOME/neomutt/config</entry></row>
       <row><entry>~/.neomuttrc</entry></row>
       <row><entry>~/.mutt/neomuttrc</entry></row>
       <row><entry>~/.muttrc-1.6.2-neo</entry></row>
@@ -2398,6 +2404,10 @@ See also the <link linkend="postpone">$postpone</link> quad-option.
   </tgroup>
 </table>
 
+<para>
+  <emphasis>($XDG_CONFIG_HOME defaults to "$HOME/.config".)</emphasis>
+</para>
+
 </sect1>
 
 <sect1 id="muttrc-syntax" xreflabel="Syntax of Initialization Files">
diff --git a/init.c b/init.c
index 59c0a13eff77dff1808268c149c18f8ff18d6b8c..d1ee76d38d991df763f09c3f42ebeee4e55d0ce0 100644 (file)
--- a/init.c
+++ b/init.c
@@ -3420,24 +3420,42 @@ void mutt_init (int skip_sys_rc, LIST *commands)
    */
   add_to_list(&MailtoAllow, "body");
   add_to_list(&MailtoAllow, "subject");
-  
-  
-  
+
   if (!Muttrc)
   {
-    snprintf (buffer, sizeof(buffer), "%s/.neomuttrc", NONULL(Homedir));
-    if (access(buffer, F_OK) == -1)
-      snprintf (buffer, sizeof (buffer), "%s/.mutt/neomuttrc", NONULL(Homedir));
-    if (access(buffer, F_OK) == -1)
-      snprintf (buffer, sizeof(buffer), "%s/.muttrc-%s", NONULL(Homedir), MUTT_VERSION);
-    if (access(buffer, F_OK) == -1)
-      snprintf (buffer, sizeof(buffer), "%s/.muttrc", NONULL(Homedir));
-    if (access(buffer, F_OK) == -1)
-      snprintf (buffer, sizeof (buffer), "%s/.mutt/muttrc-%s", NONULL(Homedir), MUTT_VERSION);
-    if (access(buffer, F_OK) == -1)
-      snprintf (buffer, sizeof (buffer), "%s/.mutt/muttrc", NONULL(Homedir));
-    if (access(buffer, F_OK) == -1) /* default to .muttrc for alias_file */
-      snprintf (buffer, sizeof(buffer), "%s/.muttrc", NONULL(Homedir));
+    do
+    {
+      if (mutt_set_xdg_path (kXDGConfigHome, buffer, sizeof buffer))
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/.neomuttrc", NONULL(Homedir));
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/.mutt/neomuttrc", NONULL(Homedir));
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/.muttrc-%s", NONULL(Homedir), MUTT_VERSION);
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/.muttrc", NONULL(Homedir));
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/.mutt/muttrc-%s", NONULL(Homedir), MUTT_VERSION);
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/.mutt/muttrc", NONULL(Homedir));
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      /* default to .muttrc for alias_file */
+      snprintf (buffer, sizeof buffer, "%s/.muttrc", NONULL(Homedir));
+    }
+    while (0);
 
     default_rc = 1;
     Muttrc = safe_strdup (buffer);
@@ -3456,24 +3474,38 @@ void mutt_init (int skip_sys_rc, LIST *commands)
      requested not to via "-n".  */
   if (!skip_sys_rc)
   {
-    snprintf (buffer, sizeof(buffer), "%s/NeoMuttrc", SYSCONFDIR);
-    if (access (buffer, F_OK) == -1)
-      snprintf (buffer, sizeof(buffer), "%s/Muttrc-%s", SYSCONFDIR, MUTT_VERSION);
-    if (access (buffer, F_OK) == -1)
-      snprintf (buffer, sizeof(buffer), "%s/Muttrc", SYSCONFDIR);
-    if (access (buffer, F_OK) == -1)
-      snprintf (buffer, sizeof (buffer), "%s/Muttrc-%s", PKGDATADIR, MUTT_VERSION);
-    if (access (buffer, F_OK) == -1)
-      snprintf (buffer, sizeof (buffer), "%s/Muttrc", PKGDATADIR);
-    if (access (buffer, F_OK) != -1)
-    {
-      if (source_rc (buffer, &err) != 0)
+    do
+    {
+      if (mutt_set_xdg_path (kXDGConfigDirs, buffer, sizeof buffer))
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/NeoMuttrc", SYSCONFDIR);
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/Muttrc-%s", SYSCONFDIR, MUTT_VERSION);
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/Muttrc", SYSCONFDIR);
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/Muttrc-%s", PKGDATADIR, MUTT_VERSION);
+      if (access (buffer, F_OK) == 0)
+        break;
+
+      snprintf (buffer, sizeof buffer, "%s/Muttrc", PKGDATADIR);
+      if (access (buffer, F_OK) == 0)
       {
-       fputs (err.data, stderr);
-       fputc ('\n', stderr);
-       need_pause = 1;
+        if (source_rc (buffer, &err) != 0)
+        {
+          fputs (err.data, stderr);
+          fputc ('\n', stderr);
+          need_pause = 1;
+        }
       }
-    }
+    } while (0);
   }
 
   /* Read the user's initialization file.  */
index 113d50c3038fdae2f32d5eaf1c70122a5af2e9bc..315dd51ca46f981c8876dd627be6aabbe6986c7c 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
 #include <sys/types.h>
 #include <utime.h>
 
+static const char *xdg_env_vars[] =
+{
+  [kXDGConfigHome] = "XDG_CONFIG_HOME",
+  [kXDGConfigDirs] = "XDG_CONFIG_DIRS",
+};
+
+static const char *xdg_defaults[] =
+{
+  [kXDGConfigHome] = "~/.config",
+  [kXDGConfigDirs] = "/etc/xdg",
+};
+
 BODY *mutt_new_body (void)
 {
   BODY *p = (BODY *) safe_calloc (1, sizeof (BODY));
@@ -2127,3 +2139,31 @@ void mutt_encode_path (char *dest, size_t dlen, const char *src)
   strfcpy (dest, (rc == 0) ? NONULL(p) : NONULL(src), dlen);
   FREE (&p);
 }
+
+/*
+ * Process an XDG environment variable or its fallback.
+ *
+ * Return 1 if an entry was found that actually exists on disk and 0 otherwise.
+ */
+int mutt_set_xdg_path(const XDGType type, char *buf, size_t bufsize)
+{
+  char *xdg_env = getenv (xdg_env_vars[type]);
+  char *xdg     = (xdg_env && *xdg_env) ? safe_strdup (xdg_env) : safe_strdup (xdg_defaults[type]);
+  char *x       = xdg;  /* strsep() changes xdg, so free x instead later */
+  char *token   = NULL;
+
+  while ((token = strsep (&xdg, ":")))
+  {
+    if (snprintf (buf, bufsize, "%s/neomutt/config", token) < 0)
+      continue;
+    mutt_expand_path (buf, bufsize);
+    if (access (buf, F_OK) == 0)
+    {
+      FREE (&x);
+      return 1;
+    }
+  }
+
+  FREE (&x);
+  return 0;
+}
index 8d2fdea9177e4264a017a74ac7da28cad8588980..ec9c0a7f283097eda3acaa9ce71862fdaec2a1ea 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -37,6 +37,11 @@ struct hdr_format_info
   const char *pager_progress;
 };
 
+typedef enum {
+  kXDGConfigHome,  /* $XDG_CONFIG_HOME */
+  kXDGConfigDirs,  /* $XDG_CONFIG_DIRS */
+} XDGType;
+
 void mutt_make_string_info (char *, size_t, int, const char *, struct hdr_format_info *, format_flag);
 
 int mutt_extract_token (BUFFER *, BUFFER *, int);
@@ -155,6 +160,7 @@ char *mutt_get_parameter (const char *, PARAMETER *);
 LIST *mutt_crypt_hook (ADDRESS *);
 char *mutt_make_date (char *, size_t);
 void mutt_timeout_hook (void);
+int mutt_set_xdg_path(const XDGType type, char *buf, size_t bufsize);
 
 const char *mutt_make_version (void);