From 15cd4f6ea5074ffb33de8670bd1877603e504289 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 10 May 2018 17:56:45 +0200 Subject: pullimap: use extended SEARCH (RFC 4731) when available --- pullimap | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'pullimap') diff --git a/pullimap b/pullimap index dca8c49..736bbff 100755 --- a/pullimap +++ b/pullimap @@ -249,10 +249,20 @@ sub purge() { my @now = gmtime($now - $days*86400); my @m = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; # RFC 3501's date-month my $date = sprintf("%02d-%s-%04d", $now[3], $m[$now[4]], $now[5]+1900); - my @uid = $IMAP->search("UID $set BEFORE $date"); - - $set = @uid ? compact_set(@uid) : undef; - $IMAP->log("Removing ".($#uid+1)." UID(s) $set") if defined $set and !$CONFIG{quiet}; + my $ext = $IMAP->incapable('ESEARCH') ? undef : [qw/COUNT ALL/]; + my @uid = $IMAP->search((defined $ext ? "RETURN (".join(' ', @$ext).') ' : '') + ."UID $set BEFORE $date"); + my $count; + if (defined $ext) { + my ($uid_indicator, %resp) = @uid; + $IMAP->panic() unless defined $uid_indicator and $uid_indicator = 'UID'; + $count = $resp{COUNT} // $IMAP->panic(); + $set = $resp{ALL}; # MUST NOT be present if there are no matches + } else { + $count = $#uid+1; + $set = $count == 0 ? undef : compact_set(@uid); + } + $IMAP->log("Removing $count UID(s) $set") if $count > 0 and !$CONFIG{quiet}; } if (defined $set) { -- cgit v1.2.3 From dd7edb8eac0c11fb8168f5028c8b6d8706cc8fdb Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 20 Jan 2019 19:55:33 +0100 Subject: pullimap, interimap: Use $XDG_CONFIG_HOME/$NAME/config as config file. --- Changelog | 4 ++++ README | 2 +- interimap | 35 +++++++++++++++-------------------- interimap.md | 10 +++++----- lib/Net/IMAP/InterIMAP.pm | 36 +++++++++++++++++++++++++++++++----- pullimap | 35 +++++++++++++++-------------------- pullimap.md | 10 +++++----- 7 files changed, 76 insertions(+), 56 deletions(-) (limited to 'pullimap') diff --git a/Changelog b/Changelog index 7939fa2..7f033c8 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,10 @@ interimap (0.4) UNRELEASED * pullimap: replace non RFC 5321-compliant envelope sender addresses (received by the IMAP FETCH ENVELOPE command) with the null address <>. + * pullimap, interimap: take configuration filename (default: "config") + relative to $XDG_CONFIG_HOME/$NAME (or ~/.config/$NAME), to comply + with the XDG specification. Thus the previous default config file + $XDG_CONFIG_HOME/$NAME should become $XDG_CONFIG_HOME/$NAME/config. + Library: new API idle_start() and idle_stop(). + Add support for untagged ESEARCH responses from RFC 4731. + pullimap: Use extended SEARCH commands (RFC 4731) if supported by diff --git a/README b/README index 6c3ae34..70bf1df 100644 --- a/README +++ b/README @@ -52,7 +52,7 @@ the AUTHENTICATE command. For instance the following configuration snippet saves bandwidth and brings a significant speed gain compared to type=imaps. - local: $XDG_CONFIG_HOME/interimap: + local: $XDG_CONFIG_HOME/interimap/config: [remote] type = tunnel command = /usr/bin/ssh user@imap.example.net diff --git a/interimap b/interimap index 049b564..0f34bf9 100755 --- a/interimap +++ b/interimap @@ -30,7 +30,7 @@ use Fcntl qw/F_GETFD F_SETFD FD_CLOEXEC/; use List::Util 'first'; use lib 'lib'; -use Net::IMAP::InterIMAP qw/read_config compact_set/; +use Net::IMAP::InterIMAP qw/xdg_basedir read_config compact_set/; # Clean up PATH $ENV{PATH} = join ':', qw{/usr/bin /bin}; @@ -63,20 +63,24 @@ my $COMMAND = do { }; usage(1) if defined $COMMAND and (($COMMAND eq 'delete' and !@ARGV) or ($COMMAND eq 'rename' and $#ARGV != 1)); usage(1) if defined $COMMAND and (defined $CONFIG{watch} or defined $CONFIG{notify}); -usage(1) if $CONFIG{target} and !(defined $COMMAND and ($COMMAND eq 'delete'or $COMMAND eq 'rename')); +usage(1) if $CONFIG{target} and !(defined $COMMAND and ($COMMAND eq 'delete' or $COMMAND eq 'rename')); $CONFIG{watch} = $CONFIG{notify} ? 900 : 60 if (defined $CONFIG{watch} or $CONFIG{notify}) and !$CONFIG{watch}; @ARGV = map {uc $_ eq 'INBOX' ? 'INBOX' : $_ } @ARGV; # INBOX is case-insensitive die "Invalid mailbox name $_" foreach grep !/\A([\x01-\x7F]+)\z/, @ARGV; -my $CONF = read_config( delete $CONFIG{config} // $NAME - , [qw/_ local remote/] - , database => qr/\A(\P{Control}+)\z/ - , logfile => qr/\A(\/\P{Control}+)\z/ - , 'list-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/ - , 'list-select-opts' => qr/\A([\x21\x23\x24\x26\x27\x2B-\x5B\x5E-\x7A\x7C-\x7E]+)\z/ - , 'ignore-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/ - ); +my $CONF = do { + my $conffile = delete($CONFIG{config}) // "config"; + $conffile = xdg_basedir( XDG_CONFIG_HOME => ".config", $NAME, $conffile ); + read_config( $conffile + , [qw/_ local remote/] + , database => qr/\A(\P{Control}+)\z/ + , logfile => qr/\A(\/\P{Control}+)\z/ + , 'list-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/ + , 'list-select-opts' => qr/\A([\x21\x23\x24\x26\x27\x2B-\x5B\x5E-\x7A\x7C-\x7E]+)\z/ + , 'ignore-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/ + ); +}; my ($DBFILE, $LOGGER_FD); { @@ -84,16 +88,7 @@ my ($DBFILE, $LOGGER_FD); $DBFILE //= $CONF->{remote}->{host}.'.db' if defined $CONF->{remote}; $DBFILE //= $CONF->{local}->{host}. '.db' if defined $CONF->{local}; die "Missing option database" unless defined $DBFILE; - - unless ($DBFILE =~ /\A\//) { - my $dir = ($ENV{XDG_DATA_HOME} // "$ENV{HOME}/.local/share") .'/'. $NAME; - $dir =~ /\A(\/\p{Print}+)\z/ or die "Insecure $dir"; - $dir = $1; - $DBFILE = $dir .'/'. $DBFILE; - unless (-d $dir) { - mkdir $dir, 0700 or die "Can't mkdir $dir: $!\n"; - } - } + $DBFILE = xdg_basedir( XDG_DATA_HOME => ".local/share", $NAME, $DBFILE ); if (defined $CONF->{_} and defined $CONF->{_}->{logfile}) { require 'POSIX.pm'; diff --git a/interimap.md b/interimap.md index 4a321f1..ca83dba 100644 --- a/interimap.md +++ b/interimap.md @@ -140,8 +140,8 @@ Options `--config=`*FILE* : Specify an alternate [configuration file](#configuration-file). - Relative paths start from *$XDG_CONFIG_HOME*, or *~/.config* if the - `XDG_CONFIG_HOME` environment variable is unset. + Relative paths start from *$XDG_CONFIG_HOME/interimap*, or *~/.config/interimap* + if the `XDG_CONFIG_HOME` environment variable is unset. `--target={local,remote,database}` @@ -192,9 +192,9 @@ Configuration file ================== Unless told otherwise by the `--config=FILE` command-line option, -`interimap` reads its configuration from *$XDG_CONFIG_HOME/interimap* -(or *~/.config/interimap* if the `XDG_CONFIG_HOME` environment variable -is unset) as an [INI file]. +`interimap` reads its configuration from *$XDG_CONFIG_HOME/interimap/config* +(or *~/.config/interimap/config* if the `XDG_CONFIG_HOME` environment +variable is unset) as an [INI file]. The syntax of the configuration file is a series of `OPTION=VALUE` lines organized under some `[SECTION]`; lines starting with a ‘#’ or ‘;’ character are ignored as comments. diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 67b3ce5..7b0a2be 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -22,7 +22,7 @@ use strict; use Compress::Raw::Zlib qw/Z_OK Z_FULL_FLUSH Z_SYNC_FLUSH MAX_WBITS/; use Config::Tiny (); -use Errno 'EINTR'; +use Errno qw/EEXIST EINTR/; use Fcntl qw/F_GETFD F_SETFD FD_CLOEXEC/; use Net::SSLeay (); use List::Util qw/all first/; @@ -35,7 +35,7 @@ BEGIN { Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::randomize(); - our @EXPORT_OK = qw/read_config compact_set $IMAP_text $IMAP_cond + our @EXPORT_OK = qw/xdg_basedir read_config compact_set $IMAP_text $IMAP_cond slurp is_dirty has_new_mails/; } @@ -76,6 +76,35 @@ my $CRLF = "\x0D\x0A"; ############################################################################# # Utilities +# xdg_basedir($xdg_variable, $default, $subdir, $path) +# Return $path if $path is absolute. Otherwise, return +# "$ENV{$xdg_variable}/$subdir/$path" (resp. "~/$default/$subdir/path" +# if the "$xdg_variable" environment variable is not set). +# An error is raised if "$ENV{$xdg_variable}" (resp. "~/$default") is +# not an existing absolute directory. +# If "$ENV{$xdg_variable}/$subdir" doesn't exist, it is created with +# mode 0700. +sub xdg_basedir($$$$) { + my ($xdg_variable, $default, $subdir, $path) = @_; + $path =~ /\A(\p{Print}+)\z/ or die "Insecure $path"; + $path = $1; + return $path if $path =~ /\A\//; + + my $basedir = $ENV{$xdg_variable}; + unless (defined $basedir) { + my @getent = getpwuid($>); + $basedir = $getent[7] ."/". $default; + } + die "No such directory: ", $basedir unless -d $basedir; + $basedir .= "/".$subdir; + $basedir =~ /\A(\/\p{Print}+)\z/ or die "Insecure $basedir"; + $basedir = $1; + unless (mkdir ($basedir, 0700)) { + die "Couldn't create $basedir: $!\n" unless $! == EEXIST; + } + return $basedir ."/". $path; +} + # read_config($conffile, $sections, %opts) # Read $conffile's default section, then each section in the array # reference $section (which takes precedence). %opts extends %OPTIONS @@ -85,9 +114,6 @@ sub read_config($$%) { my $sections = shift; my %opts = (%OPTIONS, @_); - $conffile = ($ENV{XDG_CONFIG_HOME} // "$ENV{HOME}/.config") .'/'. $conffile - unless $conffile =~ /\A\//; # relative path - die "No such config file $conffile\n" unless defined $conffile and -f $conffile and -r $conffile; diff --git a/pullimap b/pullimap index 736bbff..e666114 100755 --- a/pullimap +++ b/pullimap @@ -31,7 +31,7 @@ use List::Util 'first'; use Socket qw/PF_INET PF_INET6 SOCK_STREAM/; use lib 'lib'; -use Net::IMAP::InterIMAP qw/read_config compact_set/; +use Net::IMAP::InterIMAP qw/xdg_basedir read_config compact_set/; # Clean up PATH $ENV{PATH} = join ':', qw{/usr/bin /bin}; @@ -59,15 +59,19 @@ usage(1) unless $#ARGV == 0 and $ARGV[0] ne '_'; ####################################################################### # Read and validate configuration # -my $CONF = read_config( delete $CONFIG{config} // $NAME, - , [$ARGV[0]] - , statefile => qr/\A(\P{Control}+)\z/ - , mailbox => qr/\A([\x01-\x7F]+)\z/ - , 'deliver-method' => qr/\A([ls]mtp:\[.*\]:\d+)\z/ - , 'deliver-ehlo' => qr/\A(\P{Control}+)\z/ - , 'deliver-rcpt' => qr/\A(\P{Control}+)\z/ - , 'purge-after' => qr/\A(\d*)\z/ - )->{$ARGV[0]}; +my $CONF = do { + my $conffile = delete($CONFIG{config}) // "config"; + $conffile = xdg_basedir( XDG_CONFIG_HOME => ".config", $NAME, $conffile ); + read_config( $conffile + , [$ARGV[0]] + , statefile => qr/\A(\P{Control}+)\z/ + , mailbox => qr/\A([\x01-\x7F]+)\z/ + , 'deliver-method' => qr/\A([ls]mtp:\[.*\]:\d+)\z/ + , 'deliver-ehlo' => qr/\A(\P{Control}+)\z/ + , 'deliver-rcpt' => qr/\A(\P{Control}+)\z/ + , 'purge-after' => qr/\A(\d*)\z/ + )->{$ARGV[0]}; +}; my ($MAILBOX, $STATE); do { @@ -75,16 +79,7 @@ do { my $statefile = $CONF->{statefile} // $ARGV[0]; die "Missing option statefile" unless defined $statefile; - $statefile = $statefile =~ /\A(\p{Print}+)\z/ ? $1 : die "Insecure $statefile"; - - unless ($statefile =~ /\A\//) { - my $dir = ($ENV{XDG_DATA_HOME} // "$ENV{HOME}/.local/share") .'/'. $NAME; - $dir = $dir =~ /\A(\/\p{Print}+)\z/ ? $1 : die "Insecure $dir"; - $statefile = $dir .'/'. $statefile; - unless (-d $dir) { - mkdir $dir, 0700 or die "Can't mkdir $dir: $!\n"; - } - } + $statefile = xdg_basedir( XDG_DATA_HOME => ".local/share", $NAME, $statefile ); sysopen($STATE, $statefile, O_CREAT|O_RDWR|O_DSYNC, 0600) or die "Can't open $statefile: $!"; # XXX we need to pack the struct flock manually: not portable! diff --git a/pullimap.md b/pullimap.md index 06035ac..eac8efa 100644 --- a/pullimap.md +++ b/pullimap.md @@ -32,8 +32,8 @@ Options `--config=`*FILE* : Specify an alternate [configuration file](#configuration-file). - Relative paths start from *$XDG_CONFIG_HOME*, or *~/.config* if the - `XDG_CONFIG_HOME` environment variable is unset. + Relative paths start from *$XDG_CONFIG_HOME/pullimap*, or *~/.config/pullimap* + if the `XDG_CONFIG_HOME` environment variable is unset. `--idle`[`=`*seconds*] @@ -74,9 +74,9 @@ Configuration file ================== Unless told otherwise by the `--config=FILE` command-line option, -`pullimap` reads its configuration from *$XDG_CONFIG_HOME/pullimap* (or -*~/.config/pullimap* if the `XDG_CONFIG_HOME` environment variable is -unset) as an [INI file]. +`pullimap` reads its configuration from *$XDG_CONFIG_HOME/pullimap/config* +(or *~/.config/pullimap/config* if the `XDG_CONFIG_HOME` environment variable +is unset) as an [INI file]. The syntax of the configuration file is a series of `OPTION=VALUE` lines organized under some `[SECTION]`; lines starting with a ‘#’ or ‘;’ character are ignored as comments. -- cgit v1.2.3 From 452ae91f06bec4c21e7ba7b7bc4309b089f7afe3 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 20 Jan 2019 19:55:58 +0100 Subject: Specify minimum Perl and Net::SSLeay versions. --- Changelog | 1 + INSTALL | 4 ++-- interimap | 1 + lib/Net/IMAP/InterIMAP.pm | 2 +- pullimap | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) (limited to 'pullimap') diff --git a/Changelog b/Changelog index 7f033c8..c8a0d51 100644 --- a/Changelog +++ b/Changelog @@ -13,6 +13,7 @@ interimap (0.4) UNRELEASED the server to search old mail and EXPUNGE them. - Ensure the lower bound of UID ranges is at least 1. - Fix manpage generation with pandoc >=2.1. + - Specify minimum Perl and Net::SSLeay versions. -- Guilhem Moulin Tue, 06 Dec 2016 17:37:01 +0100 diff --git a/INSTALL b/INSTALL index 458b7c2..69afb26 100644 --- a/INSTALL +++ b/INSTALL @@ -1,4 +1,4 @@ -InterIMAP depends on the following Perl modules: +InterIMAP depends on Perl >=5.20 and the following Perl modules: - Compress::Raw::Zlib (core module) - Config::Tiny @@ -8,7 +8,7 @@ InterIMAP depends on the following Perl modules: - Getopt::Long (core module) - MIME::Base64 (core module) if authentication is required - List::Util (core module) - - Net::SSLeay + - Net::SSLeay >=1.73 - POSIX (core module) - Socket (core module) - Time::HiRes (core module) if 'logfile' is set diff --git a/interimap b/interimap index 0f34bf9..41a0cb9 100755 --- a/interimap +++ b/interimap @@ -18,6 +18,7 @@ # along with this program. If not, see . #---------------------------------------------------------------------- +use v5.14.2; use strict; use warnings; diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 7b0a2be..f783ea7 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -24,7 +24,7 @@ use Compress::Raw::Zlib qw/Z_OK Z_FULL_FLUSH Z_SYNC_FLUSH MAX_WBITS/; use Config::Tiny (); use Errno qw/EEXIST EINTR/; use Fcntl qw/F_GETFD F_SETFD FD_CLOEXEC/; -use Net::SSLeay (); +use Net::SSLeay 1.73 (); use List::Util qw/all first/; use POSIX ':signal_h'; use Socket qw/SOCK_STREAM IPPROTO_TCP AF_INET AF_INET6 SOCK_RAW :addrinfo/; diff --git a/pullimap b/pullimap index e666114..e044df5 100755 --- a/pullimap +++ b/pullimap @@ -21,6 +21,7 @@ use strict; use warnings; +use v5.20.2; our $VERSION = '0.3'; my $NAME = 'pullimap'; -- cgit v1.2.3 From 8c0f59f3f3add18a9ee8be767f54f43996ddbd78 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 20 Jan 2019 20:16:53 +0100 Subject: Note on migrations. --- README | 2 +- interimap | 4 ++++ interimap.md | 4 +++- pullimap | 5 +++++ 4 files changed, 13 insertions(+), 2 deletions(-) (limited to 'pullimap') diff --git a/README b/README index 70bf1df..cb34ef1 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ InterIMAP is a fast bidirectional synchronization program for QRESYNC-capable IMAP4rev1 servers. PullIMAP retrieves messages a remote IMAP mailbox and -deliver them to a SMTP session. Consult the manuals for more information. +deliver them to an SMTP session. Consult the manuals for more information. https://guilhem.org/man/interimap.1.html https://guilhem.org/man/pullimap.1.html diff --git a/interimap b/interimap index 41a0cb9..0fb6c1c 100755 --- a/interimap +++ b/interimap @@ -162,6 +162,10 @@ $DBH->do('PRAGMA foreign_keys = ON'); # also, lUID < local.UIDNEXT and rUID < remote.UIDNEXT (except for interrupted syncs) # mapping.idx must be found among local.idx (and remote.idx) ], + + # We have no version number in the schema, but if we ever need a + # migration, we'll add a new table, and assume version 1.0 if + # the table is missing. ); # Invariants: diff --git a/interimap.md b/interimap.md index ca83dba..1831d39 100644 --- a/interimap.md +++ b/interimap.md @@ -398,7 +398,9 @@ Known bugs and limitations * Using `interimap` on two identical servers with a non-existent or empty *database* will duplicate each message due to the absence of - local ↔ remote UID association. + local ↔ remote UID association. Hence one needs to manually empty + the mail store on one end when migrating to `interimap` from another + synchronisation solution. * `interimap` is single threaded and doesn't use IMAP command pipelining. Synchronization could be boosted up by sending diff --git a/pullimap b/pullimap index e044df5..bd9b1cf 100755 --- a/pullimap +++ b/pullimap @@ -88,6 +88,11 @@ do { fcntl($STATE, F_SETLK, $struct_flock) or die "Can't lock $statefile: $!"; my $flags = fcntl($STATE, F_GETFD, 0) or die "fcntl F_GETFD: $!"; fcntl($STATE, F_SETFD, $flags | FD_CLOEXEC) or die "fcntl F_SETFD: $!"; + + # We have no version number in the statefile, but if we ever need a + # migration, we'll add a 1-byte header for the version number, and + # assume version 1.0 if the size of the file is a multiple of 4 + # bytes. (We can also use the fact that bytes 5 to 8 are never all 0.) }; -- cgit v1.2.3 From 1492f504316eb506e72f7a84ecd23207bb07e226 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 21 Jan 2019 17:54:53 +0100 Subject: pullimap, interimap: don't autocreate statefile or database in long-lived mode. --- Changelog | 3 +++ interimap | 27 +++++++++++++++++---------- pullimap | 6 +++++- 3 files changed, 25 insertions(+), 11 deletions(-) (limited to 'pullimap') diff --git a/Changelog b/Changelog index eb187b6..b4fb931 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,9 @@ interimap (0.4) UNRELEASED + Add support for untagged ESEARCH responses from RFC 4731. + pullimap: Use extended SEARCH commands (RFC 4731) if supported by the server to search old mail and EXPUNGE them. + + pullimap, interimap: don't autocreate statefile or database in + long-lived mode (when --watch or --idle is set). Instead, an error + is raised if the statefile or database doesn't exist. - Ensure the lower bound of UID ranges is at least 1. - Fix manpage generation with pandoc >=2.1. - Specify minimum Perl and Net::SSLeay versions. diff --git a/interimap b/interimap index 0fb6c1c..7ac6b05 100755 --- a/interimap +++ b/interimap @@ -27,6 +27,7 @@ my $NAME = 'interimap'; use Getopt::Long qw/:config posix_default no_ignore_case gnu_compat bundling auto_version/; use DBI (); +use DBD::SQLite::Constants ':file_open'; use Fcntl qw/F_GETFD F_SETFD FD_CLOEXEC/; use List::Util 'first'; @@ -121,18 +122,24 @@ $SIG{TERM} = sub { cleanup(); exit 0; }; ############################################################################# # Open the database and create tables -$DBH = DBI::->connect("dbi:SQLite:dbname=$DBFILE", undef, undef, { - AutoCommit => 0, - RaiseError => 1, - sqlite_see_if_its_a_number => 1, # see if the bind values are numbers or not - sqlite_use_immediate_transaction => 1, -}); -$DBH->sqlite_busy_timeout(250); -$DBH->do('PRAGMA locking_mode = EXCLUSIVE'); -$DBH->do('PRAGMA foreign_keys = ON'); - { + my $dbi_data_source = "dbi:SQLite:dbname=".$DBFILE; + my %dbi_attrs = ( + AutoCommit => 0, + RaiseError => 1, + sqlite_see_if_its_a_number => 1, # see if the bind values are numbers or not + sqlite_use_immediate_transaction => 1, + sqlite_open_flags => SQLITE_OPEN_READWRITE + ); + # don't auto-create in long-lived mode + $dbi_attrs{sqlite_open_flags} |= SQLITE_OPEN_CREATE unless defined $CONFIG{watch}; + + $DBH = DBI::->connect($dbi_data_source, undef, undef, \%dbi_attrs); + $DBH->sqlite_busy_timeout(250); + $DBH->do('PRAGMA locking_mode = EXCLUSIVE'); + $DBH->do('PRAGMA foreign_keys = ON'); + my @schema = ( mailboxes => [ q{idx INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT}, diff --git a/pullimap b/pullimap index bd9b1cf..b752b14 100755 --- a/pullimap +++ b/pullimap @@ -82,7 +82,11 @@ do { die "Missing option statefile" unless defined $statefile; $statefile = xdg_basedir( XDG_DATA_HOME => ".local/share", $NAME, $statefile ); - sysopen($STATE, $statefile, O_CREAT|O_RDWR|O_DSYNC, 0600) or die "Can't open $statefile: $!"; + my $mode = O_RDWR | O_DSYNC; + # don't auto-create in long-lived mode + $mode |= O_CREAT unless defined $CONFIG{idle}; + + sysopen($STATE, $statefile, $mode, 0600) or die "Can't open $statefile: $!"; # XXX we need to pack the struct flock manually: not portable! my $struct_flock = pack('s!s!l!l!i!', F_WRLCK, SEEK_SET, 0, 0, 0); fcntl($STATE, F_SETLK, $struct_flock) or die "Can't lock $statefile: $!"; -- cgit v1.2.3 From e85db0b140eb2c56fa46231829a1bfe6f98ede7d Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 20 Jan 2019 20:29:58 +0100 Subject: Bump version number. --- interimap | 4 ++-- lib/Net/IMAP/InterIMAP.pm | 2 +- pullimap | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'pullimap') diff --git a/interimap b/interimap index 7ac6b05..deb0949 100755 --- a/interimap +++ b/interimap @@ -22,7 +22,7 @@ use v5.14.2; use strict; use warnings; -our $VERSION = '0.3'; +our $VERSION = '0.4'; my $NAME = 'interimap'; use Getopt::Long qw/:config posix_default no_ignore_case gnu_compat bundling auto_version/; @@ -32,7 +32,7 @@ use Fcntl qw/F_GETFD F_SETFD FD_CLOEXEC/; use List::Util 'first'; use lib 'lib'; -use Net::IMAP::InterIMAP qw/xdg_basedir read_config compact_set/; +use Net::IMAP::InterIMAP 0.0.4 qw/xdg_basedir read_config compact_set/; # Clean up PATH $ENV{PATH} = join ':', qw{/usr/bin /bin}; diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 3d8bd97..8280fb2 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -16,7 +16,7 @@ # along with this program. If not, see . #---------------------------------------------------------------------- -package Net::IMAP::InterIMAP v0.0.3; +package Net::IMAP::InterIMAP v0.0.4; use warnings; use strict; diff --git a/pullimap b/pullimap index b752b14..233172f 100755 --- a/pullimap +++ b/pullimap @@ -22,7 +22,7 @@ use strict; use warnings; use v5.20.2; -our $VERSION = '0.3'; +our $VERSION = '0.4'; my $NAME = 'pullimap'; use Errno 'EINTR'; @@ -32,7 +32,7 @@ use List::Util 'first'; use Socket qw/PF_INET PF_INET6 SOCK_STREAM/; use lib 'lib'; -use Net::IMAP::InterIMAP qw/xdg_basedir read_config compact_set/; +use Net::IMAP::InterIMAP 0.0.4 qw/xdg_basedir read_config compact_set/; # Clean up PATH $ENV{PATH} = join ':', qw{/usr/bin /bin}; -- cgit v1.2.3 From 64dd58fb503c5ee31da3bcbe52313c723730a122 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 20 Jan 2019 20:42:56 +0100 Subject: Bump copyright years. --- README | 4 ++-- interimap | 2 +- lib/Net/IMAP/InterIMAP.pm | 2 +- pullimap | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'pullimap') diff --git a/README b/README index cb34ef1..06f328f 100644 --- a/README +++ b/README @@ -82,6 +82,6 @@ usage with regular INET sockets (type=imaps or type=imap). _______________________________________________________________________ -InterIMAP is Copyright© 2015 Guilhem Moulin ⟨guilhem@fripost.org⟩, and -licensed for use under the GNU General Public License version 3 or +InterIMAP is Copyright© 2015-2018 Guilhem Moulin ⟨guilhem@fripost.org⟩, +and licensed for use under the GNU General Public License version 3 or later. See ‘COPYING’ for specific terms and distribution information. diff --git a/interimap b/interimap index deb0949..454d311 100755 --- a/interimap +++ b/interimap @@ -2,7 +2,7 @@ #---------------------------------------------------------------------- # Fast bidirectional synchronization for QRESYNC-capable IMAP servers -# Copyright © 2015,2016 Guilhem Moulin +# Copyright © 2015-2018 Guilhem Moulin # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 8280fb2..a773f08 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -1,6 +1,6 @@ #---------------------------------------------------------------------- # A minimal IMAP4 client for QRESYNC-capable servers -# Copyright © 2015 Guilhem Moulin +# Copyright © 2015-2018 Guilhem Moulin # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/pullimap b/pullimap index 233172f..495b99e 100755 --- a/pullimap +++ b/pullimap @@ -2,7 +2,7 @@ #---------------------------------------------------------------------- # Pull mails from an IMAP mailbox and deliver them to a SMTP session -# Copyright © 2016 Guilhem Moulin +# Copyright © 2016-2018 Guilhem Moulin # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -- cgit v1.2.3