Compare commits

...

40 commits

Author SHA1 Message Date
Oswald Buddenhagen
9f1320ff0c disable debian stuff when shadow-building
the stuff needs to be run in the source dir and modifies it, which is a
bit against the idea of a shadow build.
fixes "make distcheck".
2012-04-28 12:10:30 +02:00
Oswald Buddenhagen
e895cd11f7 cvsignore => gitignore
(cherry picked from commit 4729b1ee23)
2012-04-28 11:38:14 +02:00
Oswald Buddenhagen
b6ae600419 adjust ChangeLog generation to git
now that log generation is cheap, don't store it in the SCM any more.
(cherry picked from commit 474ce08b3a)
2012-04-28 11:36:22 +02:00
Oswald Buddenhagen
2074a7ab03 backport: memmove for overlapping mem copies. 2011-11-29 22:40:39 +01:00
Oswald Buddenhagen
1af2cfde4f fix UIDNEXT handling
UIDNEXT *can* be legally zero, so deal with it.

-REFMAIL: 4CA62BA1.4020104@lemma.co.uk
2010-10-03 14:34:16 +02:00
Oswald Buddenhagen
2d5a73c55d don't hang after failed start_tls()
we'd send a LOGOUT command in plain text while the server was already
expecting an encrypted command, which would typically lead to waiting
for more data and thus an indefinite hang.
so close the socket immediately instead of letting the normal shutdown
path take care of it.
inspired by a patch by Steven Flintham.

-REFMAIL: 4C9AB98E.3000400@lemma.co.uk
2010-10-03 12:05:40 +02:00
Oswald Buddenhagen
608a2863e0 handle failure to store message. this helps with invalid messages like
0-byte files after crashes.
2009-03-21 16:05:51 +00:00
Oswald Buddenhagen
b546877d70 bump version 2009-03-21 14:11:07 +00:00
Oswald Buddenhagen
d47cca7dd9 backport: deal with UIDVALIDITY of 0 properly.
CCMAIL: skinner@destiny-denied.co.uk
-REF: 20080822094543.GA3528@ugly.local
2008-08-23 07:55:15 +00:00
Oswald Buddenhagen
d2ccc93584 backport: give the implicitly created imap account config the name of
the store.
2008-04-13 09:57:27 +00:00
Oswald Buddenhagen
dff2f6a9f5 backport: compat wrapper: don't crash if neither host nor tunnel are
specified.
2008-02-23 14:19:13 +00:00
Oswald Buddenhagen
5e43508aec bump version 2008-02-23 09:41:19 +00:00
Oswald Buddenhagen
8616ed393d regen 2008-02-23 09:39:10 +00:00
Oswald Buddenhagen
6636d7ebb7 backport: quote user name in generated config. 2008-02-23 09:38:00 +00:00
Oswald Buddenhagen
e161af47bb backport: don't overlook 2nd and later single-letter options in last
argument.
2008-02-23 09:22:06 +00:00
Oswald Buddenhagen
1b9b5f8bfd backport: put pointers to bdb open() into parentheses, so they won't be
macro-expanded as libc open.
2008-02-23 09:03:22 +00:00
Oswald Buddenhagen
5d03247bec backport: don't use #ifdef inside htons() arguments - it can be a macro. 2007-09-22 08:49:05 +00:00
Oswald Buddenhagen
0d27c5f4cb avoid crash in case of a rather weird (==misconfigured?) sync state
location.
2007-04-04 17:55:13 +00:00
Oswald Buddenhagen
0eb399c672 accept empty SEARCH IMAP responses - reasonable servers omit them
alltogether, but this is allowed, too. patch by
CCMAIL: Alexander Gerasiov <gq@cs.msu.su>
fixes debian bug #413336

fixed in HEAD a year ago - accidentally ...
2007-04-04 13:27:24 +00:00
Oswald Buddenhagen
9a0539868a backport: fix crash due to uninited var when parsing IMAPServer.
-REF: <E1HFuIM-00041h-Nn@sc8-pr-cvs2.sourceforge.net>
2007-02-10 15:41:32 +00:00
Oswald Buddenhagen
43f23fb180 backport: reverse-map <Inbox> to INBOX when encountered during listing. 2006-11-18 13:17:31 +00:00
Oswald Buddenhagen
d51a91aeba backport: make compat wrapper default to current user for imap login 2006-11-09 18:01:27 +00:00
Oswald Buddenhagen
f7ba199d35 re-gen 2006-11-03 13:06:01 +00:00
Oswald Buddenhagen
a54459af1c add target for creating signed package 2006-11-03 13:05:34 +00:00
Oswald Buddenhagen
3759f0c802 backport:
- un-document "Host imaps:[...]" syntax and introduce new option UseIMAPS
  instead
- apply ted's patch to support UseIMAPS in conjunction with Tunnel
- document that SSLv2 is No Good (TM)
2006-11-01 07:19:26 +00:00
Oswald Buddenhagen
6494cfc438 backport: move assigning default port to the place of use 2006-11-01 07:14:50 +00:00
Oswald Buddenhagen
afc48600fa bump version 2006-11-01 06:33:37 +00:00
Oswald Buddenhagen
4b70d9b96c backport: put INBOX in Maildir 2006-11-01 06:20:56 +00:00
Oswald Buddenhagen
41c4e0d681 backport: don't crash on truncating db 2006-10-24 17:39:24 +00:00
Oswald Buddenhagen
b6c6299ea6 another attempt at working around glibc breakage. 2006-07-31 05:31:17 +00:00
Oswald Buddenhagen
2e39fa9930 work around glibc bug: printf("%.*s", INT_MAX, s) tries to allocate 2G. 2006-07-29 11:53:47 +00:00
Oswald Buddenhagen
927feae988 make config parsing more robust against bogus input and report errors
more clearly.
2006-03-19 10:46:33 +00:00
Oswald Buddenhagen
3f1009a839 regen 2006-01-31 16:17:18 +00:00
Oswald Buddenhagen
fd3f4f33ff bump version 2006-01-31 15:45:15 +00:00
Oswald Buddenhagen
314287cbb4 backport: deal with branches in "make log" 2006-01-31 15:21:35 +00:00
Oswald Buddenhagen
b40fb7f281 backport: fix 'isync -w' writing .mbsyncrc to a wrong directory 2006-01-31 15:17:43 +00:00
Oswald Buddenhagen
534ccb326a backport: less confusing uid ranges in debug 2006-01-31 15:16:27 +00:00
Oswald Buddenhagen
63c065a127 backport: compile fixes 2006-01-31 15:15:00 +00:00
Oswald Buddenhagen
161a4b1159 backport:
- sanitize flag handling of expired messages
- don't record we synced flags if we didn't
- remove now superfluous temporary rflags
2006-01-31 15:12:34 +00:00
Oswald Buddenhagen
9a5920c028 backport: flush debug output 2006-01-31 14:25:18 +00:00
17 changed files with 238 additions and 1549 deletions

View file

@ -1,4 +1,6 @@
.autoconf_trace
ChangeLog
INSTALL
Makefile
Makefile.in
autom4te.cache
@ -14,9 +16,13 @@ config.sub
configure
configure.lineno
configure-stamp
depcomp
install-sh
isync.spec
isync-*.tar.gz
missing
patch-stamp
stamp-h
stamp-h.in
stamp-h1
*~

1445
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -2,11 +2,59 @@ SUBDIRS = src
bin_SCRIPTS = get-cert
EXTRA_DIST = debian isync.spec $(bin_SCRIPTS)
log:
@perl -p -e "s/^(\\S+)\\s+(\\S.+\\S)\\s+(\\S+)\\s*\$$/\$$1:'\$$2 <\$$3>'\\n/" < ../CVSROOT/accounts > .usermap
cvs2cl -U .usermap --no-wrap --separate-header -I ChangeLog -I NEWS -I TODO -I debian/
@rm -f .usermap ChangeLog.bak
LOG_PL = \
use POSIX qw(strftime); \
use Date::Parse; \
use Text::Wrap; \
$$Text::Wrap::columns = 72; \
while (defined($$_ = <>)) { \
/^commit / or die "commit missing: $$_"; \
<> =~ /^log size (\d+)$$/ or die "wrong size"; \
$$len = $$1; \
read(STDIN, $$log, $$len) == $$len or die "unexpected EOF"; \
$$log =~ s/^Author: ([^>]+>)\nDate: (\d{4}-\d\d-\d\d \d\d:\d\d:\d\d [-+]\d{4})\n(.*)$$/$$3/s or die "unexpected log format"; \
$$author = $$1; $$date = str2time($$2); \
scalar(<>); \
@files = (); \
$$pfx = ""; \
while (defined($$l = <>) and $$l ne "\n") { \
chomp $$l; \
next if ($$l =~ m,^(ChangeLog$$|NEWS$$|TODO$$|debian/),); \
if (!@files) { \
$$pfx = $$l; \
$$pfx =~ s,/?[^/]+$$,,; \
} else { \
while (length($$pfx)) { \
$$l =~ m,^\Q$$pfx/\E, and last; \
$$pfx =~ s,/?[^/]+$$,,; \
} \
} \
push @files, $$l; \
} \
next if (!@files); \
print strftime("%F %H:%M", gmtime($$date))." ".$$author."\n\n"; \
if (@files > 1 and ($$len = length($$pfx))) { \
@efiles = (); \
for $$f (@files) { push @efiles, substr($$f, $$len + 1); } \
$$fstr = $$pfx."/: "; \
} else { \
@efiles = @files; \
$$fstr = ""; \
} \
print wrap("\t* ", "\t ", $$fstr.join(", ", @efiles).":")."\n"; \
$$log =~ s, +$$,,gm; \
$$log =~ s,^ ,\t,gm; \
print $$log."\n"; \
}
$(srcdir)/ChangeLog: log
log:
@test -z "$(srcdir)" || cd $(srcdir) && \
( ! test -d .git || \
git log --date=iso --log-size --name-only | \
perl -e '$(LOG_PL)' > ChangeLog )
if in_source_build
deb:
CFLAGS="-O2 -mcpu=i686" fakeroot debian/rules binary
@ -17,7 +65,11 @@ deb-clean:
distdir distclean: deb-clean
dist-hook:
find $(distdir)/debian \( -name CVS -o -name .cvsignore -o -name .#\*# -o -type l \) -print0 | xargs -0r rm -rf
find $(distdir)/debian \( -name .git -o -name .gitignore -o -name .#\*# -o -type l \) -print0 | xargs -0r rm -rf
endif
dist-sign: dist
gpg -b -a $(PACKAGE)-$(VERSION).tar.gz
rpm:
make dist

View file

@ -1,5 +1,6 @@
#! /bin/sh
set -e -v
make -f Makefile.am log
aclocal
autoheader
automake --add-missing

View file

@ -1,6 +1,6 @@
AC_INIT(src/isync.h)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(isync, 1.0.1)
AM_INIT_AUTOMAKE(isync, 1.0.5)
AM_MAINTAINER_MODE
@ -9,6 +9,7 @@ if test "$GCC" = yes; then
CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes"
fi
AC_CHECK_HEADERS([sys/filio.h])
AC_CHECK_FUNCS(vasprintf)
AC_CHECK_LIB(socket, socket, [SOCK_LIBS="-lsocket"])
@ -93,6 +94,8 @@ if test "x$ob_cv_enable_compat" != xno; then
fi
AM_CONDITIONAL(with_compat, test "x$ob_cv_enable_compat" != xno)
AM_CONDITIONAL(in_source_build, test "x$srcdir" = x.)
AC_OUTPUT(Makefile src/Makefile src/compat/Makefile isync.spec)
if test -n "$have_ssl_paths"; then

View file

@ -3,3 +3,4 @@ Makefile
Makefile.in
mbsync
mdconvert
*.o

View file

@ -2,3 +2,4 @@
Makefile
Makefile.in
isync
*.o

View file

@ -250,8 +250,9 @@ write_imap_server( FILE *fp, config_t *cfg )
cfg->server_name, cfg->tunnel );
} else {
if (sscanf( cfg->host, "%d.%d.%d.%d", &a1, &a2, &a3, &a4 ) == 4)
/* XXX this does not avoid clashes. add port? */
cfg->server_name = nfstrdup( cfg->host );
else {
else if (cfg->host) {
p = strrchr( cfg->host, '.' );
if (!p)
hl = nfsnprintf( buf, sizeof(buf), "%s", cfg->host );
@ -270,6 +271,9 @@ write_imap_server( FILE *fp, config_t *cfg )
cfg->server_name = nfstrdup( buf );
cfg->servers = 1;
gotsrv: ;
} else {
fprintf( stderr, "ERROR: Neither host nor tunnel specified for mailbox %s.\n", cfg->path );
exit( 1 );
}
fprintf( fp, "IMAPAccount %s\n", cfg->server_name );
if (cfg->use_imaps)
@ -279,7 +283,7 @@ write_imap_server( FILE *fp, config_t *cfg )
fprintf( fp, "Port %d\n", cfg->port );
}
if (cfg->user)
fprintf( fp, "User %s\n", cfg->user );
fprintf( fp, "User \"%s\"\n", cfg->user );
if (cfg->pass)
fprintf( fp, "Pass \"%s\"\n", cfg->pass );
fprintf( fp, "RequireCRAM %s\nRequireSSL %s\n"
@ -350,7 +354,8 @@ write_config( int fd )
fprintf( fp, "SyncState *\n\n" );
if (local_home || o2o)
fprintf( fp, "MaildirStore local\nPath \"%s/\"\nAltMap %s\n\n", maildir, tb( altmap > 0 ) );
fprintf( fp, "MaildirStore local\nPath \"%s/\"\nInbox \"%s/INBOX\"\nAltMap %s\n\n",
maildir, maildir, tb( altmap > 0 ) );
if (local_root)
fprintf( fp, "MaildirStore local_root\nPath /\nAltMap %s\n\n", tb( altmap > 0 ) );
if (o2o) {

View file

@ -145,7 +145,7 @@ convert( config_t *box )
fputs( "dbcreate failed\n", stderr );
goto err2;
}
if (db->open( db, 0, iumname, 0, DB_HASH, 0, 0 )) {
if ((db->open)( db, 0, iumname, 0, DB_HASH, 0, 0 )) {
fputs( "cannot open db\n", stderr );
db->close( db, 0 );
goto err2;

View file

@ -22,6 +22,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
@ -167,6 +168,11 @@ main( int argc, char **argv )
/* defaults */
/* XXX the precedence is borked:
it's defaults < cmdline < file instead of defaults < file < cmdline */
#ifdef BSD
global.user = getenv( "USER" );
#else
global.user = getenv( "LOGNAME" );
#endif
global.port = 143;
global.box = "INBOX";
global.use_namespace = 1;
@ -331,8 +337,8 @@ main( int argc, char **argv )
while ((de = readdir( dir ))) {
if (*de->d_name == '.')
continue;
nfsnprintf( path1, sizeof(path1), "%s/%s/cur", xmaildir, de->d_name );
if (stat( path1, &st ) || !S_ISDIR( st.st_mode ))
nfsnprintf( path2, sizeof(path2), "%s/%s/cur", xmaildir, de->d_name );
if (stat( path2, &st ) || !S_ISDIR( st.st_mode ))
continue;
global.path = de->d_name;
global.box = (inbox && !strcmp( inbox, global.path )) ?

View file

@ -31,11 +31,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
@ -250,11 +254,9 @@ init_ssl_ctx( imap_store_t *ctx )
if (!srvc->cert_file) {
fprintf( stderr, "Error, CertificateFile not defined\n" );
return -1;
} else if (access( srvc->cert_file, R_OK ))
warn( "*** Warning: can't read CertificateFile, so can't verify server certificates\n" );
else if (!SSL_CTX_load_verify_locations( imap->SSLContext, srvc->cert_file, NULL )) {
fprintf( stderr, "Error, SSL_CTX_load_verify_locations: %s\n",
ERR_error_string( ERR_get_error(), 0 ) );
} else if (!SSL_CTX_load_verify_locations( imap->SSLContext, srvc->cert_file, NULL )) {
fprintf( stderr, "Error while loading certificate file '%s': %s\n",
srvc->cert_file, ERR_error_string( ERR_get_error(), 0 ) );
return -1;
}
@ -374,7 +376,7 @@ buffer_gets( buffer_t * b, char **s )
n = b->bytes - start;
if (n)
memcpy( b->buf, b->buf + start, n );
memmove( b->buf, b->buf + start, n );
b->offset -= start;
b->bytes = n;
start = 0;
@ -815,7 +817,7 @@ static int
parse_response_code( imap_store_t *ctx, struct imap_cmd_cb *cb, char *s )
{
imap_t *imap = ctx->imap;
char *arg, *p;
char *arg, *earg, *p;
if (*s != '[')
return RESP_OK; /* no response code */
@ -827,12 +829,14 @@ parse_response_code( imap_store_t *ctx, struct imap_cmd_cb *cb, char *s )
*p++ = 0;
arg = next_arg( &s );
if (!strcmp( "UIDVALIDITY", arg )) {
if (!(arg = next_arg( &s )) || !(ctx->gen.uidvalidity = atoi( arg ))) {
if (!(arg = next_arg( &s )) ||
(ctx->gen.uidvalidity = strtoll( arg, &earg, 10 ), *earg))
{
fprintf( stderr, "IMAP error: malformed UIDVALIDITY status\n" );
return RESP_BAD;
}
} else if (!strcmp( "UIDNEXT", arg )) {
if (!(arg = next_arg( &s )) || !(imap->uidnext = atoi( arg ))) {
if (!(arg = next_arg( &s )) || (imap->uidnext = strtol( arg, &p, 10 ), *p)) {
fprintf( stderr, "IMAP error: malformed NEXTUID status\n" );
return RESP_BAD;
}
@ -845,7 +849,8 @@ parse_response_code( imap_store_t *ctx, struct imap_cmd_cb *cb, char *s )
for (; isspace( (unsigned char)*p ); p++);
fprintf( stderr, "*** IMAP ALERT *** %s\n", p );
} else if (cb && cb->ctx && !strcmp( "APPENDUID", arg )) {
if (!(arg = next_arg( &s )) || !(ctx->gen.uidvalidity = atoi( arg )) ||
if (!(arg = next_arg( &s )) ||
(ctx->gen.uidvalidity = strtoll( arg, &earg, 10 ), *earg) ||
!(arg = next_arg( &s )) || !(*(int *)cb->ctx = atoi( arg )))
{
fprintf( stderr, "IMAP error: malformed APPENDUID status\n" );
@ -863,7 +868,9 @@ parse_search( imap_t *imap, char *cmd )
int uid;
arg = next_arg( &cmd );
if (!arg || !(uid = atoi( arg ))) {
if (!arg)
return;
if (!(uid = atoi( arg ))) {
fprintf( stderr, "IMAP error: malformed SEARCH response\n" );
return;
}
@ -1240,7 +1247,11 @@ imap_open_store( store_conf_t *conf, store_t *oldctx )
info( "ok\n" );
} else {
memset( &addr, 0, sizeof(addr) );
addr.sin_port = htons( srvc->port );
addr.sin_port = srvc->port ? htons( srvc->port ) :
#ifdef HAVE_LIBSSL
srvc->use_imaps ? htons( 993 ) :
#endif
htons( 143 );
addr.sin_family = AF_INET;
info( "Resolving %s... ", srvc->host );
@ -1264,15 +1275,15 @@ imap_open_store( store_conf_t *conf, store_t *oldctx )
info( "ok\n" );
imap->buf.sock.fd = s;
}
#if HAVE_LIBSSL
if (srvc->use_imaps) {
if (start_tls( ctx ))
goto bail;
use_ssl = 1;
}
#endif
if (srvc->use_imaps) {
if (start_tls( ctx ))
goto ssl_bail;
use_ssl = 1;
}
#endif
/* read the greeting string */
if (buffer_gets( &imap->buf, &rsp )) {
@ -1303,7 +1314,7 @@ imap_open_store( store_conf_t *conf, store_t *oldctx )
if (imap_exec( ctx, 0, "STARTTLS" ) != RESP_OK)
goto bail;
if (start_tls( ctx ))
goto bail;
goto ssl_bail;
use_ssl = 1;
if (imap_exec( ctx, 0, "CAPABILITY" ) != RESP_OK)
@ -1388,6 +1399,12 @@ imap_open_store( store_conf_t *conf, store_t *oldctx )
ctx->trashnc = 1;
return (store_t *)ctx;
#if HAVE_LIBSSL
ssl_bail:
/* This avoids that we try to send LOGOUT to an unusable socket. */
close( imap->buf.sock.fd );
imap->buf.sock.fd = -1;
#endif
bail:
imap_close_store( &ctx->gen );
return 0;
@ -1420,6 +1437,8 @@ imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs )
prefix = ctx->prefix;
}
imap->uidnext = -1;
memset( &cb, 0, sizeof(cb) );
cb.create = (gctx->opts & OPEN_CREATE) != 0;
cb.trycreate = 1;
@ -1445,7 +1464,7 @@ imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs )
goto bail;
}
if (maxuid == INT_MAX)
maxuid = imap->uidnext ? imap->uidnext - 1 : 1000000000;
maxuid = imap->uidnext >= 0 ? imap->uidnext - 1 : 1000000000;
if (maxuid >= minuid &&
(ret = imap_exec_b( ctx, 0, "UID FETCH %d:%d (UID%s%s)", minuid, maxuid,
(gctx->opts & OPEN_FLAGS) ? " FLAGS" : "",
@ -1575,6 +1594,7 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
}
/* invalid message */
free( fmap );
fprintf( stderr, "IMAP warning: storing message with incomplete header.\n" );
return DRV_MSG_BAD;
mktid:
for (j = 0; j < TUIDL; j++)
@ -1691,6 +1711,7 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep, int *err )
{
imap_store_conf_t *store;
imap_server_conf_t *server, *srv, sserver;
int acc_opt = 0;
if (!strcasecmp( "IMAPAccount", cfg->cmd )) {
server = nfcalloc( sizeof(*server) );
@ -1698,11 +1719,13 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep, int *err )
*serverapp = server;
serverapp = &server->next;
store = 0;
*storep = 0;
} else if (!strcasecmp( "IMAPStore", cfg->cmd )) {
store = nfcalloc( sizeof(*store) );
store->gen.driver = &imap_driver;
store->gen.name = nfstrdup( cfg->val );
store->use_namespace = 1;
*storep = &store->gen;
memset( &sserver, 0, sizeof(sserver) );
server = &sserver;
} else
@ -1717,32 +1740,19 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep, int *err )
#endif
while (getcline( cfg ) && cfg->cmd) {
if (!strcasecmp( "Account", cfg->cmd )) {
for (srv = servers; srv; srv = srv->next)
if (srv->name && !strcmp( srv->name, cfg->val ))
goto gotsrv;
fprintf( stderr, "%s:%d: unknown IMAP account '%s'\n",
cfg->file, cfg->line, cfg->val );
*err = 1;
continue;
gotsrv:
store->server = srv;
} else if (!strcasecmp( "Host", cfg->cmd )) {
if (!strcasecmp( "Host", cfg->cmd )) {
/* The imap[s]: syntax is just a backwards compat hack. */
#if HAVE_LIBSSL
if (!memcmp( "imaps:", cfg->val, 6 )) {
cfg->val += 6;
server->use_imaps = 1;
server->use_sslv2 = 1;
server->use_sslv3 = 1;
if (!server->port)
server->port = 993;
} else
#endif
{
if (!memcmp( "imap:", cfg->val, 5 ))
cfg->val += 5;
if (!server->port)
server->port = 143;
}
if (!memcmp( "//", cfg->val, 2 ))
cfg->val += 2;
@ -1755,10 +1765,17 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep, int *err )
else if (!strcasecmp( "Port", cfg->cmd ))
server->port = parse_int( cfg );
#if HAVE_LIBSSL
else if (!strcasecmp( "CertificateFile", cfg->cmd ))
else if (!strcasecmp( "CertificateFile", cfg->cmd )) {
server->cert_file = expand_strdup( cfg->val );
else if (!strcasecmp( "RequireSSL", cfg->cmd ))
if (access( server->cert_file, R_OK )) {
fprintf( stderr, "%s:%d: CertificateFile '%s': %s\n",
cfg->file, cfg->line, server->cert_file, strerror( errno ) );
*err = 1;
}
} else if (!strcasecmp( "RequireSSL", cfg->cmd ))
server->require_ssl = parse_bool( cfg );
else if (!strcasecmp( "UseIMAPS", cfg->cmd ))
server->use_imaps = parse_bool( cfg );
else if (!strcasecmp( "UseSSLv2", cfg->cmd ))
server->use_sslv2 = parse_bool( cfg );
else if (!strcasecmp( "UseSSLv3", cfg->cmd ))
@ -1771,34 +1788,50 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep, int *err )
else if (!strcasecmp( "Tunnel", cfg->cmd ))
server->tunnel = nfstrdup( cfg->val );
else if (store) {
if (!strcasecmp( "UseNamespace", cfg->cmd ))
if (!strcasecmp( "Account", cfg->cmd )) {
for (srv = servers; srv; srv = srv->next)
if (srv->name && !strcmp( srv->name, cfg->val ))
goto gotsrv;
fprintf( stderr, "%s:%d: unknown IMAP account '%s'\n",
cfg->file, cfg->line, cfg->val );
*err = 1;
continue;
gotsrv:
store->server = srv;
} else if (!strcasecmp( "UseNamespace", cfg->cmd ))
store->use_namespace = parse_bool( cfg );
else if (!strcasecmp( "Path", cfg->cmd ))
store->gen.path = nfstrdup( cfg->val );
else
parse_generic_store( &store->gen, cfg, err );
continue;
} else {
fprintf( stderr, "%s:%d: unknown keyword '%s'\n",
fprintf( stderr, "%s:%d: unknown/misplaced keyword '%s'\n",
cfg->file, cfg->line, cfg->cmd );
*err = 1;
continue;
}
acc_opt = 1;
}
if (!store || !store->server) {
if (!server->tunnel && !server->host) {
if (store)
fprintf( stderr, "IMAP store '%s' has incomplete connection details\n", store->gen.name );
fprintf( stderr, "IMAP store '%s' has incomplete/missing connection details\n", store->gen.name );
else
fprintf( stderr, "IMAP account '%s' has incomplete connection details\n", server->name );
fprintf( stderr, "IMAP account '%s' has incomplete/missing connection details\n", server->name );
*err = 1;
/* leaking server/store */
*storep = 0;
return 1;
}
}
*storep = &store->gen;
if (store && !store->server) {
store->server = nfmalloc( sizeof(sserver) );
memcpy( store->server, &sserver, sizeof(sserver) );
if (store) {
if (!store->server) {
store->server = nfmalloc( sizeof(sserver) );
memcpy( store->server, &sserver, sizeof(sserver) );
store->server->name = store->gen.name;
} else if (acc_opt) {
fprintf( stderr, "IMAP store '%s' has both Account and account-specific options\n", store->gen.name );
*err = 1;
}
}
return 1;
}

View file

@ -161,15 +161,17 @@ maildir_list( store_t *gctx, string_list_t **retb )
}
*retb = 0;
while ((de = readdir( dir ))) {
const char *inbox = ((maildir_store_conf_t *)gctx->conf)->inbox;
int bl;
struct stat st;
char buf[PATH_MAX];
if (*de->d_name == '.')
continue;
nfsnprintf( buf, sizeof(buf), "%s%s/cur", gctx->conf->path, de->d_name );
bl = nfsnprintf( buf, sizeof(buf), "%s%s/cur", gctx->conf->path, de->d_name );
if (stat( buf, &st ) || !S_ISDIR(st.st_mode))
continue;
add_string_list( retb, de->d_name );
add_string_list( retb, !memcmp( buf, inbox, bl - 4 ) && !inbox[bl - 4] ? "INBOX" : de->d_name );
}
closedir (dir);
@ -345,7 +347,8 @@ maildir_init_uid( maildir_store_t *ctx, const char *msg )
ctx->uvok = 0;
#ifdef USE_DB
if (ctx->db) {
ctx->db->truncate( ctx->db, 0, 0 /* &u_int32_t_dummy */, 0 );
u_int32_t count;
ctx->db->truncate( ctx->db, 0, &count, 0 );
return maildir_set_uid( ctx, 0, 0 );
}
#endif /* USE_DB */
@ -475,7 +478,7 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
DBC *dbc;
#endif /* USE_DB */
msg_t *entry;
int i, j, uid, bl, ml, fnl, ret;
int i, j, uid, bl, fnl, ret;
struct stat st;
char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX];
@ -496,7 +499,7 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
fputs( "Maildir error: db_create() failed\n", stderr );
return DRV_BOX_BAD;
}
if (tdb->open( tdb, 0, 0, 0, DB_HASH, DB_CREATE, 0 )) {
if ((tdb->open)( tdb, 0, 0, 0, DB_HASH, DB_CREATE, 0 )) {
fputs( "Maildir error: tdb->open() failed\n", stderr );
tdb->close( tdb, 0 );
return DRV_BOX_BAD;
@ -637,11 +640,10 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
for (ru = u + 3; isdigit( (unsigned char)*ru ); ru++);
else
u = ru = strchr( entry->base, ':' );
if (u)
ml = u - entry->base;
else
ru = "", ml = INT_MAX;
fnl = nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%.*s,U=%d%s", subdirs[entry->recent], ml, entry->base, uid, ru ) + 1 - 4;
fnl = (u ?
nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%.*s,U=%d%s", subdirs[entry->recent], u - entry->base, entry->base, uid, ru ) :
nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s,U=%d", subdirs[entry->recent], entry->base, uid ))
+ 1 - 4;
memcpy( nbuf, buf, bl + 4 );
nfsnprintf( nbuf + bl + 4, sizeof(nbuf) - bl - 4, "%s", entry->base );
if (rename( nbuf, buf )) {
@ -781,7 +783,7 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs )
fputs( "Maildir error: db_create() failed\n", stderr );
goto bork;
}
if ((ret = ctx->db->open( ctx->db, 0, uvpath, 0, DB_HASH, DB_CREATE, 0 ))) {
if ((ret = (ctx->db->open)( ctx->db, 0, uvpath, 0, DB_HASH, DB_CREATE, 0 ))) {
ctx->db->err( ctx->db, ret, "Maildir error: db->open(%s)", uvpath );
dbork:
ctx->db->close( ctx->db, 0 );

View file

@ -178,8 +178,10 @@ main( int argc, char **argv )
}
arc4_init();
for (oind = 1, ochar = 0; oind < argc; ) {
for (oind = 1, ochar = 0; ; ) {
if (!ochar || !*ochar) {
if (oind >= argc)
break;
if (argv[oind][0] != '-')
break;
if (argv[oind][1] == '-') {

View file

@ -210,17 +210,13 @@ The location of the \fBINBOX\fR. This is \fInot\fR relative to \fBPath\fR.
Define the IMAP4 Account \fIname\fR, opening a section for its parameters.
..
.TP
\fBHost\fR [\fBimaps:\fR]\fIhost\fR
Specify the DNS name or IP address of the IMAP server. If \fIhost\fR is
prefixed with \fBimaps:\fR the connection is assumed to be an SSL connection
to port 993.
Note that modern servers support SSL on the default port 143 via the
STARTTLS extension, which will be used automatically by default.
\fBHost\fR \fIhost\fR
Specify the DNS name or IP address of the IMAP server.
..
.TP
\fBPort\fR \fIport\fR
Specify the TCP port number of the IMAP server. (Default: 143 for imap,
993 for imaps)
Specify the TCP port number of the IMAP server. (Default: 143 for IMAP,
993 for IMAPS)
..
.TP
\fBUser\fR \fIusername\fR
@ -245,6 +241,15 @@ If set to \fIyes\fR, \fBmbsync\fR will abort the connection if no CRAM-MD5
authentication is possible. (Default: \fIno\fR)
..
.TP
\fBUseIMAPS\fR \fIyes\fR|\fIno\fR
If set to \fIyes\fR, the default for \fBPort\fR is changed to 993 and
\fBmbsync\fR will start SSL negotiation immediately after establishing
the connection to the server.
.br
Note that modern servers support SSL on the regular IMAP port 143 via the
STARTTLS extension, which will be used automatically by default.
..
.TP
\fBRequireSSL\fR \fIyes\fR|\fIno\fR
\fBmbsync\fR will abort the connection if a TLS/SSL session cannot be
established with the IMAP server. (Default: \fIyes\fR)
@ -257,12 +262,14 @@ This option is \fImandatory\fR if SSL is used. See \fBSSL CERTIFICATES\fR below.
.TP
\fBUseSSLv2\fR \fIyes\fR|\fIno\fR
Use SSLv2 for communication with the IMAP server over SSL?
(Default: \fIyes\fR if an imaps \fBHost\fR is used, otherwise \fIno\fR)
.br
Note that this option is deprecated for security reasons.
(Default: \fIno\fR)
..
.TP
\fBUseSSLv3\fR \fIyes\fR|\fIno\fR
Use SSLv3 for communication with the IMAP server over SSL?
(Default: \fIyes\fR if an imaps \fBHost\fR is used, otherwise \fIno\fR)
(Default: \fIno\fR)
..
.TP
\fBUseTLSv1\fR \fIyes\fR|\fIno\fR

View file

@ -96,7 +96,7 @@ convert( const char *box, int altmap )
fputs( "Error: db_create() failed\n", stderr );
goto tbork;
}
if ((ret = db->open( db, 0, dbpath, 0, DB_HASH, DB_CREATE, 0 ))) {
if ((ret = (db->open)( db, 0, dbpath, 0, DB_HASH, DB_CREATE, 0 ))) {
db->err( db, ret, "Error: db->open(%s)", dbpath );
dbork:
db->close( db, 0 );
@ -154,7 +154,7 @@ convert( const char *box, int altmap )
if (u)
ml = u - e->d_name;
else
ru = "", ml = INT_MAX;
ru = "", ml = sizeof(buf);
if (altmap) {
if (!p)
continue;

View file

@ -251,7 +251,7 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
{
driver_t *tdriver = tctx->conf->driver, *sdriver = sctx->conf->driver;
int uid, tuid, unex;
unsigned char sflags, aflags, dflags, rflags;
unsigned char sflags, aflags, dflags;
msg_data_t msgdata;
/* excludes (push) c.3) d.2) d.3) d.4) / (pull) b.3) d.7) d.8) d.9) */
@ -301,6 +301,13 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
case DRV_OK:
smsg->flags = msgdata.flags;
switch (tdriver->store_msg( tctx, &msgdata, &uid )) {
case DRV_MSG_BAD:
warn( pull ?
"Warning: Slave refuses to store message %d from master.\n" :
"Warning: Master refuses to store message %d from slave.\n",
smsg->uid );
smsg->status |= M_NOT_SYNCED;
break;
case DRV_STORE_BAD: return pull ? SYNC_SLAVE_BAD : SYNC_MASTER_BAD;
default: return SYNC_FAIL;
case DRV_OK:
@ -332,20 +339,18 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
unex = 0;
if (srec->status & S_EXPIRED) {
if (!pull) {
if (sflags & F_DELETED) {
if (!(sflags & F_FLAGGED))
aflags &= ~F_DELETED;
} else
unex = 1;
if ((aflags & ~F_DELETED) || dflags)
info( "Info: Flags of expired message changed in (%d,%d)\n", srec->muid, srec->suid );
return SYNC_OK;
} else {
if ((sflags & F_FLAGGED) && !(sflags & F_DELETED)) {
unex = 1;
dflags |= F_DELETED;
}
} else
return SYNC_OK;
}
}
rflags = (*nflags | aflags) & ~dflags;
if ((tops & OP_EXPUNGE) && (rflags & F_DELETED) &&
if ((tops & OP_EXPUNGE) && (sflags & F_DELETED) &&
(!tctx->conf->trash || tctx->conf->trash_only_new))
{
aflags &= F_DELETED;
@ -356,7 +361,7 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
case DRV_BOX_BAD: return SYNC_FAIL;
default: /* ok */ break;
case DRV_OK:
*nflags = rflags;
*nflags = (*nflags | aflags) & ~dflags;
if (unex) {
debug( "unexpiring pair(%d,%d)\n", srec->muid, srec->suid );
/* log last, so deletion can't be misinterpreted! */
@ -401,6 +406,13 @@ sync_new( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
}
msg->flags = msgdata.flags;
switch (tdriver->store_msg( tctx, &msgdata, &uid )) {
case DRV_MSG_BAD:
warn( pull ?
"Warning: Slave refuses to store message %d from master.\n" :
"Warning: Master refuses to store message %d from slave.\n",
msg->uid );
msg->status |= M_NOT_SYNCED;
continue;
case DRV_STORE_BAD: return pull ? SYNC_SLAVE_BAD : SYNC_MASTER_BAD;
default: return SYNC_FAIL;
case DRV_OK: break;
@ -476,7 +488,7 @@ sync_boxes( store_t *mctx, const char *mname,
nmmsg = nsmsg = 0;
mctx->uidvalidity = sctx->uidvalidity = 0;
mctx->uidvalidity = sctx->uidvalidity = -1;
mopts = sopts = 0;
makeopts( chan->sops, chan->slave, &sopts, chan->master, &mopts );
makeopts( chan->mops, chan->master, &mopts, chan->slave, &sopts );
@ -512,7 +524,8 @@ sync_boxes( store_t *mctx, const char *mname,
nfasprintf( &jname, "%s.journal", dname );
nfasprintf( &nname, "%s.new", dname );
nfasprintf( &lname, "%s.lock", dname );
muidval = suidval = smaxxuid = mmaxuid = smaxuid = 0;
muidval = suidval = -1;
smaxxuid = mmaxuid = smaxuid = 0;
memset( &lck, 0, sizeof(lck) );
#if SEEK_SET != 0
lck.l_whence = SEEK_SET;
@ -699,7 +712,7 @@ sync_boxes( store_t *mctx, const char *mname,
} else
maxwuid = 0;
info( "Selecting slave %s... ", sname );
debug( "selecting slave [1,%d]\n", maxwuid );
debug( maxwuid == INT_MAX ? "selecting slave [1,inf]\n" : "selecting slave [1,%d]\n", maxwuid );
switch (sdriver->select( sctx, (sctx->opts & OPEN_OLD) ? 1 : smaxuid + 1, maxwuid, 0, 0 )) {
case DRV_STORE_BAD: ret = SYNC_SLAVE_BAD; goto bail;
case DRV_BOX_BAD: ret = SYNC_FAIL; goto bail;
@ -707,16 +720,17 @@ sync_boxes( store_t *mctx, const char *mname,
info( "%d messages, %d recent\n", sctx->count, sctx->recent );
dump_box( sctx );
if (suidval && suidval != sctx->uidvalidity) {
if (suidval >= 0 && suidval != sctx->uidvalidity) {
fprintf( stderr, "Error: UIDVALIDITY of slave changed\n" );
ret = SYNC_FAIL;
goto bail;
}
s = strrchr( dname, '/' );
*s = 0;
mkdir( dname, 0700 );
*s = '/';
if ((s = strrchr( dname, '/' ))) {
*s = 0;
mkdir( dname, 0700 );
*s = '/';
}
if (lfd < 0) {
if ((lfd = open( lname, O_WRONLY|O_CREAT, 0666 )) < 0)
goto lferr;
@ -802,7 +816,7 @@ sync_boxes( store_t *mctx, const char *mname,
} else
maxwuid = 0;
info( "Selecting master %s... ", mname );
debug( "selecting master [%d,%d]\n", minwuid, maxwuid );
debug( maxwuid == INT_MAX ? "selecting master [%d,inf]\n" : "selecting master [%d,%d]\n", minwuid, maxwuid );
switch (mdriver->select( mctx, minwuid, maxwuid, mexcs, nmexcs )) {
case DRV_STORE_BAD: ret = SYNC_MASTER_BAD; goto finish;
case DRV_BOX_BAD: ret = SYNC_FAIL; goto finish;
@ -810,13 +824,13 @@ sync_boxes( store_t *mctx, const char *mname,
info( "%d messages, %d recent\n", mctx->count, mctx->recent );
dump_box( mctx );
if (muidval && muidval != mctx->uidvalidity) {
if (muidval >= 0 && muidval != mctx->uidvalidity) {
fprintf( stderr, "Error: UIDVALIDITY of master changed\n" );
ret = SYNC_FAIL;
goto finish;
}
if (!muidval || !suidval) {
if (muidval < 0 || suidval < 0) {
muidval = mctx->uidvalidity;
suidval = sctx->uidvalidity;
Fprintf( jfp, "| %d %d\n", muidval, suidval );

View file

@ -41,6 +41,7 @@ debug( const char *msg, ... )
va_start( va, msg );
vprintf( msg, va );
va_end( va );
fflush( stdout );
}
}