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.
This commit is contained in:
Oswald Buddenhagen 2022-05-30 23:04:21 +02:00
parent 8bb679ea06
commit cf13630a00
3 changed files with 56 additions and 9 deletions

5
NEWS
View File

@ -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.

View File

@ -11,6 +11,8 @@
#include <pwd.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#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 );
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;
}

View File

@ -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)