introduce FieldDelimiter and InfoDelimiter options
... for windows fs compatibility. the maildir-specific InfoDelimiter inherits the global FieldDelimiter (which affects SyncState), based on the assumption that if the sync state is on a windows FS, the mailboxes certainly will be as well, while the inverse is not necessarily true (when running on unix, anyway). REFMAIL: <CA+m_8J1ynqAjHRJagvKt9sb31yz047Q7NH-ODRmHOKyfru8vtA@mail.gmail.com>
This commit is contained in:
parent
85fd5ceb54
commit
f377e7b696
2
NEWS
2
NEWS
|
@ -8,6 +8,8 @@ Notice: Tunnels are assumed to be secure and thus default to no SSL.
|
||||||
|
|
||||||
Support for SASL (flexible authentication) has been added.
|
Support for SASL (flexible authentication) has been added.
|
||||||
|
|
||||||
|
Support for Windows file systems has been added.
|
||||||
|
|
||||||
[1.1.0]
|
[1.1.0]
|
||||||
|
|
||||||
Support for hierarchical mailboxes in Patterns.
|
Support for hierarchical mailboxes in Patterns.
|
||||||
|
|
3
README
3
README
|
@ -59,9 +59,6 @@ isync executable still exists; it is a compatibility wrapper around mbsync.
|
||||||
At some point, ``isync'' has successfully run on:
|
At some point, ``isync'' has successfully run on:
|
||||||
Linux, Solaris 2.7, OpenBSD 2.8, FreeBSD 4.3.
|
Linux, Solaris 2.7, OpenBSD 2.8, FreeBSD 4.3.
|
||||||
|
|
||||||
Note that Cygwin cannot be reasonably supported due to restrictions
|
|
||||||
of the Windows file system.
|
|
||||||
|
|
||||||
* Requirements
|
* Requirements
|
||||||
|
|
||||||
Berkley DB 4.2+
|
Berkley DB 4.2+
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
|
|
||||||
extern int DFlags;
|
extern int DFlags;
|
||||||
extern int UseFSync;
|
extern int UseFSync;
|
||||||
|
extern char FieldDelimiter;
|
||||||
|
|
||||||
extern int Pid;
|
extern int Pid;
|
||||||
extern char Hostname[256];
|
extern char Hostname[256];
|
||||||
|
|
13
src/config.c
13
src/config.c
|
@ -467,6 +467,19 @@ load_config( const char *where, int pseudo )
|
||||||
{
|
{
|
||||||
UseFSync = parse_bool( &cfile );
|
UseFSync = parse_bool( &cfile );
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp( "FieldDelimiter", cfile.cmd ))
|
||||||
|
{
|
||||||
|
if (strlen( cfile.val ) != 1) {
|
||||||
|
error( "%s:%d: Field delimiter must be exactly one character long\n", cfile.file, cfile.line );
|
||||||
|
cfile.err = 1;
|
||||||
|
} else {
|
||||||
|
FieldDelimiter = cfile.val[0];
|
||||||
|
if (!ispunct( FieldDelimiter )) {
|
||||||
|
error( "%s:%d: Field delimiter must be a punctuation character\n", cfile.file, cfile.line );
|
||||||
|
cfile.err = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (!getopt_helper( &cfile, &gcops, &global_conf ))
|
else if (!getopt_helper( &cfile, &gcops, &global_conf ))
|
||||||
{
|
{
|
||||||
error( "%s:%d: unknown section keyword '%s'\n",
|
error( "%s:%d: unknown section keyword '%s'\n",
|
||||||
|
|
|
@ -57,6 +57,8 @@ typedef struct maildir_store_conf {
|
||||||
#ifdef USE_DB
|
#ifdef USE_DB
|
||||||
int alt_map;
|
int alt_map;
|
||||||
#endif /* USE_DB */
|
#endif /* USE_DB */
|
||||||
|
char info_delimiter;
|
||||||
|
char *info_prefix, *info_stop; /* precalculated from info_delimiter */
|
||||||
} maildir_store_conf_t;
|
} maildir_store_conf_t;
|
||||||
|
|
||||||
typedef struct maildir_message {
|
typedef struct maildir_message {
|
||||||
|
@ -84,14 +86,14 @@ static int MaildirCount;
|
||||||
static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' };
|
static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' };
|
||||||
|
|
||||||
static unsigned char
|
static unsigned char
|
||||||
maildir_parse_flags( const char *base )
|
maildir_parse_flags( const char *info_prefix, const char *base )
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if ((s = strstr( base, ":2," )))
|
if ((s = strstr( base, info_prefix )))
|
||||||
for (s += 3, i = 0; i < as(Flags); i++)
|
for (s += 3, i = 0; i < as(Flags); i++)
|
||||||
if (strchr( s, Flags[i] ))
|
if (strchr( s, Flags[i] ))
|
||||||
flags |= (1 << i);
|
flags |= (1 << i);
|
||||||
|
@ -413,9 +415,9 @@ maildir_validate( const char *box, int create, maildir_store_t *ctx )
|
||||||
|
|
||||||
#ifdef USE_DB
|
#ifdef USE_DB
|
||||||
static void
|
static void
|
||||||
make_key( DBT *tkey, char *name )
|
make_key( const char *info_stop, DBT *tkey, char *name )
|
||||||
{
|
{
|
||||||
char *u = strpbrk( name, ":," );
|
char *u = strpbrk( name, info_stop );
|
||||||
tkey->data = name;
|
tkey->data = name;
|
||||||
tkey->size = u ? (size_t)(u - name) : strlen( name );
|
tkey->size = u ? (size_t)(u - name) : strlen( name );
|
||||||
}
|
}
|
||||||
|
@ -439,7 +441,7 @@ maildir_set_uid( maildir_store_t *ctx, const char *name, int *uid )
|
||||||
return DRV_BOX_BAD;
|
return DRV_BOX_BAD;
|
||||||
}
|
}
|
||||||
if (uid) {
|
if (uid) {
|
||||||
make_key( &key, (char *)name );
|
make_key( ((maildir_store_conf_t *)ctx->gen.conf)->info_stop, &key, (char *)name );
|
||||||
value.data = uid;
|
value.data = uid;
|
||||||
value.size = sizeof(*uid);
|
value.size = sizeof(*uid);
|
||||||
if ((ret = ctx->db->put( ctx->db, 0, &key, &value, 0 )))
|
if ((ret = ctx->db->put( ctx->db, 0, &key, &value, 0 )))
|
||||||
|
@ -615,6 +617,7 @@ maildir_compare( const void *l, const void *r )
|
||||||
static int
|
static int
|
||||||
maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
|
maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
|
||||||
{
|
{
|
||||||
|
maildir_store_conf_t *conf = (maildir_store_conf_t *)ctx->gen.conf;
|
||||||
DIR *d;
|
DIR *d;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
|
@ -694,7 +697,7 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
|
||||||
ctx->gen.recent += i;
|
ctx->gen.recent += i;
|
||||||
#ifdef USE_DB
|
#ifdef USE_DB
|
||||||
if (ctx->db) {
|
if (ctx->db) {
|
||||||
make_key( &key, e->d_name );
|
make_key( conf->info_stop, &key, e->d_name );
|
||||||
if ((ret = ctx->db->get( ctx->db, 0, &key, &value, 0 ))) {
|
if ((ret = ctx->db->get( ctx->db, 0, &key, &value, 0 ))) {
|
||||||
if (ret != DB_NOTFOUND) {
|
if (ret != DB_NOTFOUND) {
|
||||||
ctx->db->err( ctx->db, ret, "Maildir error: db->get()" );
|
ctx->db->err( ctx->db, ret, "Maildir error: db->get()" );
|
||||||
|
@ -834,7 +837,7 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
|
||||||
if ((u = strstr( entry->base, ",U=" )))
|
if ((u = strstr( entry->base, ",U=" )))
|
||||||
for (ru = u + 3; isdigit( (unsigned char)*ru ); ru++);
|
for (ru = u + 3; isdigit( (unsigned char)*ru ); ru++);
|
||||||
else
|
else
|
||||||
u = ru = strchr( entry->base, ':' );
|
u = ru = strchr( entry->base, conf->info_delimiter );
|
||||||
fnl = (u ?
|
fnl = (u ?
|
||||||
nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%.*s,U=%d%s", subdirs[entry->recent], (int)(u - entry->base), entry->base, uid, ru ) :
|
nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%.*s,U=%d%s", subdirs[entry->recent], (int)(u - entry->base), entry->base, uid, ru ) :
|
||||||
nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s,U=%d", subdirs[entry->recent], entry->base, uid ))
|
nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s,U=%d", subdirs[entry->recent], entry->base, uid ))
|
||||||
|
@ -906,7 +909,7 @@ maildir_init_msg( maildir_store_t *ctx, maildir_message_t *msg, msg_t *entry )
|
||||||
msg->gen.status |= M_RECENT;
|
msg->gen.status |= M_RECENT;
|
||||||
if (ctx->gen.opts & OPEN_FLAGS) {
|
if (ctx->gen.opts & OPEN_FLAGS) {
|
||||||
msg->gen.status |= M_FLAGS;
|
msg->gen.status |= M_FLAGS;
|
||||||
msg->gen.flags = maildir_parse_flags( msg->base );
|
msg->gen.flags = maildir_parse_flags( ((maildir_store_conf_t *)ctx->gen.conf)->info_prefix, msg->base );
|
||||||
} else
|
} else
|
||||||
msg->gen.flags = 0;
|
msg->gen.flags = 0;
|
||||||
}
|
}
|
||||||
|
@ -1177,16 +1180,16 @@ maildir_fetch_msg( store_t *gctx, message_t *gmsg, msg_data_t *data,
|
||||||
}
|
}
|
||||||
close( fd );
|
close( fd );
|
||||||
if (!(gmsg->status & M_FLAGS))
|
if (!(gmsg->status & M_FLAGS))
|
||||||
data->flags = maildir_parse_flags( msg->base );
|
data->flags = maildir_parse_flags( ((maildir_store_conf_t *)gctx->conf)->info_prefix, msg->base );
|
||||||
cb( DRV_OK, aux );
|
cb( DRV_OK, aux );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
maildir_make_flags( int flags, char *buf )
|
maildir_make_flags( char info_delimiter, int flags, char *buf )
|
||||||
{
|
{
|
||||||
unsigned i, d;
|
unsigned i, d;
|
||||||
|
|
||||||
buf[0] = ':';
|
buf[0] = info_delimiter;
|
||||||
buf[1] = '2';
|
buf[1] = '2';
|
||||||
buf[2] = ',';
|
buf[2] = ',';
|
||||||
for (d = 3, i = 0; i < as(Flags); i++)
|
for (d = 3, i = 0; i < as(Flags); i++)
|
||||||
|
@ -1231,7 +1234,7 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
|
||||||
box = ctx->trash;
|
box = ctx->trash;
|
||||||
}
|
}
|
||||||
|
|
||||||
maildir_make_flags( data->flags, fbuf );
|
maildir_make_flags( ((maildir_store_conf_t *)gctx->conf)->info_delimiter, data->flags, fbuf );
|
||||||
nfsnprintf( buf, sizeof(buf), "%s/tmp/%s%s", box, base, fbuf );
|
nfsnprintf( buf, sizeof(buf), "%s/tmp/%s%s", box, base, fbuf );
|
||||||
if ((fd = open( buf, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) {
|
if ((fd = open( buf, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) {
|
||||||
if (errno != ENOENT || !to_trash) {
|
if (errno != ENOENT || !to_trash) {
|
||||||
|
@ -1302,6 +1305,7 @@ static void
|
||||||
maildir_set_flags( store_t *gctx, message_t *gmsg, int uid ATTR_UNUSED, int add, int del,
|
maildir_set_flags( store_t *gctx, message_t *gmsg, int uid ATTR_UNUSED, int add, int del,
|
||||||
void (*cb)( int sts, void *aux ), void *aux )
|
void (*cb)( int sts, void *aux ), void *aux )
|
||||||
{
|
{
|
||||||
|
maildir_store_conf_t *conf = (maildir_store_conf_t *)gctx->conf;
|
||||||
maildir_store_t *ctx = (maildir_store_t *)gctx;
|
maildir_store_t *ctx = (maildir_store_t *)gctx;
|
||||||
maildir_message_t *msg = (maildir_message_t *)gmsg;
|
maildir_message_t *msg = (maildir_message_t *)gmsg;
|
||||||
char *s, *p;
|
char *s, *p;
|
||||||
|
@ -1319,7 +1323,7 @@ maildir_set_flags( store_t *gctx, message_t *gmsg, int uid ATTR_UNUSED, int add,
|
||||||
oob();
|
oob();
|
||||||
memcpy( buf + bl, msg->base, ol + 1 );
|
memcpy( buf + bl, msg->base, ol + 1 );
|
||||||
memcpy( nbuf + bl, msg->base, ol + 1 );
|
memcpy( nbuf + bl, msg->base, ol + 1 );
|
||||||
if ((s = strstr( nbuf + bl, ":2," ))) {
|
if ((s = strstr( nbuf + bl, conf->info_prefix ))) {
|
||||||
s += 3;
|
s += 3;
|
||||||
fl = ol - (s - (nbuf + bl));
|
fl = ol - (s - (nbuf + bl));
|
||||||
for (i = 0; i < as(Flags); i++) {
|
for (i = 0; i < as(Flags); i++) {
|
||||||
|
@ -1337,7 +1341,7 @@ maildir_set_flags( store_t *gctx, message_t *gmsg, int uid ATTR_UNUSED, int add,
|
||||||
}
|
}
|
||||||
tl = ol + 3 + fl;
|
tl = ol + 3 + fl;
|
||||||
} else {
|
} else {
|
||||||
tl = ol + maildir_make_flags( msg->gen.flags, nbuf + bl + ol );
|
tl = ol + maildir_make_flags( conf->info_delimiter, msg->gen.flags, nbuf + bl + ol );
|
||||||
}
|
}
|
||||||
if (!rename( buf, nbuf ))
|
if (!rename( buf, nbuf ))
|
||||||
break;
|
break;
|
||||||
|
@ -1362,7 +1366,7 @@ maildir_purge_msg( maildir_store_t *ctx, const char *name )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
make_key( &key, (char *)name );
|
make_key( ((maildir_store_conf_t *)ctx->gen.conf)->info_stop, &key, (char *)name );
|
||||||
if ((ret = ctx->db->del( ctx->db, 0, &key, 0 ))) {
|
if ((ret = ctx->db->del( ctx->db, 0, &key, 0 ))) {
|
||||||
ctx->db->err( ctx->db, ret, "Maildir error: db->del()" );
|
ctx->db->err( ctx->db, ret, "Maildir error: db->del()" );
|
||||||
return DRV_BOX_BAD;
|
return DRV_BOX_BAD;
|
||||||
|
@ -1384,7 +1388,7 @@ maildir_trash_msg( store_t *gctx, message_t *gmsg,
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, subdirs[gmsg->status & M_RECENT], msg->base );
|
nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, subdirs[gmsg->status & M_RECENT], msg->base );
|
||||||
s = strstr( msg->base, ":2," );
|
s = strstr( msg->base, ((maildir_store_conf_t *)gctx->conf)->info_prefix );
|
||||||
nfsnprintf( nbuf, sizeof(nbuf), "%s/%s/%ld.%d_%d.%s%s", ctx->trash,
|
nfsnprintf( nbuf, sizeof(nbuf), "%s/%s/%ld.%d_%d.%s%s", ctx->trash,
|
||||||
subdirs[gmsg->status & M_RECENT], (long)time( 0 ), Pid, ++MaildirCount, Hostname, s ? s : "" );
|
subdirs[gmsg->status & M_RECENT], (long)time( 0 ), Pid, ++MaildirCount, Hostname, s ? s : "" );
|
||||||
if (!rename( buf, nbuf ))
|
if (!rename( buf, nbuf ))
|
||||||
|
@ -1484,6 +1488,7 @@ maildir_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
if (strcasecmp( "MaildirStore", cfg->cmd ))
|
if (strcasecmp( "MaildirStore", cfg->cmd ))
|
||||||
return 0;
|
return 0;
|
||||||
store = nfcalloc( sizeof(*store) );
|
store = nfcalloc( sizeof(*store) );
|
||||||
|
store->info_delimiter = FieldDelimiter;
|
||||||
store->gen.driver = &maildir_driver;
|
store->gen.driver = &maildir_driver;
|
||||||
store->gen.name = nfstrdup( cfg->val );
|
store->gen.name = nfstrdup( cfg->val );
|
||||||
|
|
||||||
|
@ -1496,10 +1501,24 @@ maildir_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
else if (!strcasecmp( "AltMap", cfg->cmd ))
|
else if (!strcasecmp( "AltMap", cfg->cmd ))
|
||||||
store->alt_map = parse_bool( cfg );
|
store->alt_map = parse_bool( cfg );
|
||||||
#endif /* USE_DB */
|
#endif /* USE_DB */
|
||||||
else
|
else if (!strcasecmp( "InfoDelimiter", cfg->cmd )) {
|
||||||
|
if (strlen( cfg->val ) != 1) {
|
||||||
|
error( "%s:%d: Info delimiter must be exactly one character long\n", cfg->file, cfg->line );
|
||||||
|
cfg->err = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
store->info_delimiter = cfg->val[0];
|
||||||
|
if (!ispunct( store->info_delimiter )) {
|
||||||
|
error( "%s:%d: Info delimiter must be a punctuation character\n", cfg->file, cfg->line );
|
||||||
|
cfg->err = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else
|
||||||
parse_generic_store( &store->gen, cfg );
|
parse_generic_store( &store->gen, cfg );
|
||||||
if (!store->inbox)
|
if (!store->inbox)
|
||||||
store->inbox = expand_strdup( "~/Maildir" );
|
store->inbox = expand_strdup( "~/Maildir" );
|
||||||
|
nfasprintf( &store->info_prefix, "%c2,", store->info_delimiter );
|
||||||
|
nfasprintf( &store->info_stop, "%c,", store->info_delimiter );
|
||||||
*storep = &store->gen;
|
*storep = &store->gen;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@
|
||||||
|
|
||||||
int DFlags;
|
int DFlags;
|
||||||
int UseFSync = 1;
|
int UseFSync = 1;
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__)
|
||||||
|
char FieldDelimiter = ';';
|
||||||
|
#else
|
||||||
|
char FieldDelimiter = ':';
|
||||||
|
#endif
|
||||||
|
|
||||||
int Pid; /* for maildir and imap */
|
int Pid; /* for maildir and imap */
|
||||||
char Hostname[256]; /* for maildir */
|
char Hostname[256]; /* for maildir */
|
||||||
|
|
20
src/mbsync.1
20
src/mbsync.1
|
@ -229,6 +229,13 @@ The location of the \fBINBOX\fR. This is \fInot\fR relative to \fBPath\fR,
|
||||||
but it is allowed to place the \fBINBOX\fR inside the \fBPath\fR.
|
but it is allowed to place the \fBINBOX\fR inside the \fBPath\fR.
|
||||||
(Default: \fI~/Maildir\fR)
|
(Default: \fI~/Maildir\fR)
|
||||||
..
|
..
|
||||||
|
.TP
|
||||||
|
\fBInfoDelimiter\fR \fIdelim\fR
|
||||||
|
The character used to delimit the info field from a message's basename.
|
||||||
|
The Maildir standard defines this to be the colon, but this is incompatible
|
||||||
|
with DOS/Windows file systems.
|
||||||
|
(Default: the value of \fBFieldDelimiter\fR)
|
||||||
|
..
|
||||||
.SS IMAP4 Accounts
|
.SS IMAP4 Accounts
|
||||||
.TP
|
.TP
|
||||||
\fBIMAPAccount\fR \fIname\fR
|
\fBIMAPAccount\fR \fIname\fR
|
||||||
|
@ -513,7 +520,8 @@ mailbox name to make up a complete path.
|
||||||
.br
|
.br
|
||||||
This option can be used outside any section for a global effect. In this case
|
This option can be used outside any section for a global effect. In this case
|
||||||
the appended string is made up according to the pattern
|
the appended string is made up according to the pattern
|
||||||
\fB:\fImaster\fB:\fImaster-box\fB_:\fIslave\fB:\fIslave-box\fR.
|
\fB:\fImaster\fB:\fImaster-box\fB_:\fIslave\fB:\fIslave-box\fR
|
||||||
|
(see also \fBFieldDelimiter\fR below).
|
||||||
.br
|
.br
|
||||||
(Global default: \fI~/.mbsync/\fR).
|
(Global default: \fI~/.mbsync/\fR).
|
||||||
..
|
..
|
||||||
|
@ -549,6 +557,16 @@ in particular modern systems like ext4, btrfs and xfs. The performance impact
|
||||||
on older file systems may be disproportionate.
|
on older file systems may be disproportionate.
|
||||||
(Default: \fIyes\fR)
|
(Default: \fIyes\fR)
|
||||||
..
|
..
|
||||||
|
.TP
|
||||||
|
\fBFieldDelimiter\fR \fIdelim\fR
|
||||||
|
The character to use to delimit fields in the string appended to a global
|
||||||
|
\fBSyncState\fR.
|
||||||
|
\fBmbsync\fR prefers to use the colon, but this is incompatible with
|
||||||
|
DOS/Windows file systems.
|
||||||
|
This option is meaningless for \fBSyncState\fR if the latter is \fB*\fR,
|
||||||
|
obviously. However, it also determines the default of \fBInfoDelimiter\fR.
|
||||||
|
(Global default: \fI;\fR on Windows, \fI:\fR everywhere else)
|
||||||
|
..
|
||||||
.SH RECOMMENDATIONS
|
.SH RECOMMENDATIONS
|
||||||
Make sure your IMAP server does not auto-expunge deleted messages - it is
|
Make sure your IMAP server does not auto-expunge deleted messages - it is
|
||||||
slow, and semantically somewhat questionable. Specifically, Gmail needs to
|
slow, and semantically somewhat questionable. Specifically, Gmail needs to
|
||||||
|
|
|
@ -669,9 +669,10 @@ box_selected( int sts, void *aux )
|
||||||
if (chan->sync_state)
|
if (chan->sync_state)
|
||||||
nfasprintf( &svars->dname, "%s%s", chan->sync_state, csname );
|
nfasprintf( &svars->dname, "%s%s", chan->sync_state, csname );
|
||||||
else {
|
else {
|
||||||
|
char c = FieldDelimiter;
|
||||||
cmname = clean_strdup( svars->box_name[M] );
|
cmname = clean_strdup( svars->box_name[M] );
|
||||||
nfasprintf( &svars->dname, "%s:%s:%s_:%s:%s", global_conf.sync_state,
|
nfasprintf( &svars->dname, "%s%c%s%c%s_%c%s%c%s", global_conf.sync_state,
|
||||||
chan->stores[M]->name, cmname, chan->stores[S]->name, csname );
|
c, chan->stores[M]->name, c, cmname, c, chan->stores[S]->name, c, csname );
|
||||||
free( cmname );
|
free( cmname );
|
||||||
}
|
}
|
||||||
free( csname );
|
free( csname );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user