From cf13630a00e4761e26f054b37875085958800eeb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 30 May 2022 23:04:21 +0200 Subject: [PATCH] make default config & state locations follow the XDG basedir spec there are fallbacks to the old locations for compatibility. the new locations use "isync" instead of "mbsync", which is preparation for renaming the executable back in v1.6. --- NEWS | 5 +++++ src/config.c | 44 +++++++++++++++++++++++++++++++++++++++----- src/mbsync.1 | 16 ++++++++++++---- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index 6e094e6..5513385 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +[1.5.0] + +Changed default config & state locations to follow the XDG basedir spec. +The old locations remain supported. + [1.4.0] The 'isync' compatibility wrapper was removed. diff --git a/src/config.c b/src/config.c index 4cb8361..65e080f 100644 --- a/src/config.c +++ b/src/config.c @@ -11,6 +11,8 @@ #include #include +#include +#include #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) char FieldDelimiter = ';'; @@ -348,12 +350,26 @@ load_config( const char *where ) char *arg, *p; uint len, max_size; int cops, gcops, glob_ok, fn, i; - char path[_POSIX_PATH_MAX]; + char path[_POSIX_PATH_MAX], path2[_POSIX_PATH_MAX]; char buf[1024]; if (!where) { - nfsnprintf( path, sizeof(path), "%s/." EXE "rc", Home ); - cfile.file = path; + const char *config_home = getenv( "XDG_CONFIG_HOME" ); + if (config_home) + nfsnprintf( path, sizeof(path), "%s/isyncrc", config_home ); + else + nfsnprintf( path, sizeof(path), "%s/.config/isyncrc", Home ); + nfsnprintf( path2, sizeof(path2), "%s/.mbsyncrc", Home ); + struct stat st; + int ex = !lstat( path, &st ); + int ex2 = !lstat( path2, &st ); + if (ex2 && !ex) { + cfile.file = path2; + } else { + if (ex && ex2) + warn( "Both %s and %s exist; using the former.\n", path, path2 ); + cfile.file = path; + } } else { cfile.file = where; } @@ -538,7 +554,25 @@ load_config( const char *where ) if (cfile.ms_warn) warn( "Notice: Master/Slave are deprecated; use Far/Near instead.\n" ); cfile.err |= merge_ops( gcops, global_conf.ops ); - if (!global_conf.sync_state) - global_conf.sync_state = expand_strdup( "~/." EXE "/" ); + if (!global_conf.sync_state) { + const char *state_home = getenv( "XDG_STATE_HOME" ); + if (state_home) + nfsnprintf( path, sizeof(path), "%s/isync/", state_home ); + else + nfsnprintf( path, sizeof(path), "%s/.local/state/isync/", Home ); + nfsnprintf( path2, sizeof(path2), "%s/.mbsync/", Home ); + struct stat st; + int ex = !lstat( path, &st ); + int ex2 = !lstat( path2, &st ); + if (ex2 && !ex) { + global_conf.sync_state = nfstrdup( path2 ); + } else { + if (ex && ex2) { + error( "Error: both %s and %s exist; delete one or set SyncState globally.\n", path, path2 ); + cfile.err = 1; + } + global_conf.sync_state = nfstrdup( path ); + } + } return cfile.err; } diff --git a/src/mbsync.1 b/src/mbsync.1 index e39aa69..fe08ccf 100644 --- a/src/mbsync.1 +++ b/src/mbsync.1 @@ -32,7 +32,8 @@ Multiple replicas of each mailbox can be maintained. .TP \fB-c\fR, \fB--config\fR \fIfile\fR Read configuration from \fIfile\fR. -By default, the configuration is read from ~/.mbsyncrc. +By default, the configuration is read from $XDG_CONFIG_HOME/isyncrc, and +if that does not exist, ~/.mbsyncrc is tried in turn. .TP \fB-a\fR, \fB--all\fR Select all configured Channels. Any Channel/Group specifications on the @@ -672,7 +673,8 @@ the appended string is made up according to the pattern \fB:\fIfar-store\fB:\fIfar-box\fB_:\fInear-store\fB:\fInear-box\fR (see also \fBFieldDelimiter\fR below). .br -(Global default: \fI~/.mbsync/\fR). +(Global default: \fI$XDG_STATE_HOME/isync/\fR, with a fallback to +\fI~/.mbsync/\fR if only that exists) . .SS Groups .TP @@ -795,12 +797,18 @@ There is no risk as long as the IMAP mailbox is accessed by only one client . .SH FILES .TP -.B ~/.mbsyncrc +.B $XDG_CONFIG_HOME/isyncrc Default configuration file. See also the example file in the documentation directory. .TP +.B $XDG_STATE_HOME/isync/ +Directory containing synchronization state files. +.TP +.B ~/.mbsyncrc +Legacy configuration file. +.TP .B ~/.mbsync/ -Directory containing synchronization state files +Legacy directory containing synchronization state files. . .SH SEE ALSO mdconvert(1), mutt(1), maildir(5)