blob: 9eaf5f4314d1ea4b308d6b99be4028b11426dd9e [file] [log] [blame]
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +01001#!/usr/bin/perl
2
3use DBI;
4use LockFile::Simple qw(lock trylock unlock);
5use Proc::ProcessTable;
6use Data::Dumper qw(Dumper);
7use IPC::Run 'run';
8use File::Temp;
9use Try::Tiny;
10use sigtrap 'handler' => \&sig_handler, qw(INT TERM KILL QUIT);
11
12sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
13my $t = Proc::ProcessTable->new;
14my $imapsync_running = grep { $_->{cmndline} =~ /imapsync\s/i } @{$t->table};
15if ($imapsync_running ge 1)
16{
17 print "imapsync is active, exiting...";
18 exit;
19}
20
21sub qqw($) {
22 my @params = ();
23 my @values = split(/(?=--)/, $_[0]);
24 foreach my $val (@values) {
25 my @tmpparam = split(/ /, $val, 2);
26 foreach my $tmpval (@tmpparam) {
27 if ($tmpval ne '') {
28 push @params, $tmpval;
29 }
30 }
31 }
32 foreach my $val (@params) {
33 $val=trim($val);
34 }
35 return @params;
36}
37
38$run_dir="/tmp";
Matthias Andreas Benkard8f915942021-08-16 10:57:25 +020039$dsn = 'DBI:mysql:database=' . $ENV{'DBNAME'} . ';mysql_socket=/var/run/mysqld/mysqld.sock';
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +010040$lock_file = $run_dir . "/imapsync_busy";
41$lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
42$lockmgr->lock($lock_file) || die "can't lock ${lock_file}";
Matthias Andreas Benkard8f915942021-08-16 10:57:25 +020043$dbh = DBI->connect($dsn, $ENV{'DBUSER'}, $ENV{'DBPASS'}, {
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +010044 mysql_auto_reconnect => 1,
45 mysql_enable_utf8mb4 => 1
46});
47$dbh->do("UPDATE imapsync SET is_running = 0");
48
49sub sig_handler {
50 # Send die to force exception in "run"
51 die "sig_handler received signal, preparing to exit...\n";
52};
53
54open my $file, '<', "/etc/sogo/sieve.creds";
55my $creds = <$file>;
56close $file;
57my ($master_user, $master_pass) = split /:/, $creds;
58my $sth = $dbh->prepare("SELECT id,
59 user1,
60 user2,
61 host1,
62 authmech1,
63 password1,
64 exclude,
65 port1,
66 enc1,
67 delete2duplicates,
68 maxage,
69 subfolder2,
70 delete1,
71 delete2,
72 automap,
73 skipcrossduplicates,
74 maxbytespersecond,
75 custom_params,
76 subscribeall,
77 timeout1,
Matthias Andreas Benkard9dabdab2024-03-06 13:12:09 +010078 timeout2,
79 dry
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +010080 FROM imapsync
81 WHERE active = 1
82 AND is_running = 0
83 AND (
84 UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_run) > mins_interval * 60
85 OR
86 last_run IS NULL)
87 ORDER BY last_run");
88
89$sth->execute();
90my $row;
91
92while ($row = $sth->fetchrow_arrayref()) {
93
94 $id = @$row[0];
95 $user1 = @$row[1];
96 $user2 = @$row[2];
97 $host1 = @$row[3];
98 $authmech1 = @$row[4];
99 $password1 = @$row[5];
100 $exclude = @$row[6];
101 $port1 = @$row[7];
102 $enc1 = @$row[8];
103 $delete2duplicates = @$row[9];
104 $maxage = @$row[10];
105 $subfolder2 = @$row[11];
106 $delete1 = @$row[12];
107 $delete2 = @$row[13];
108 $automap = @$row[14];
109 $skipcrossduplicates = @$row[15];
110 $maxbytespersecond = @$row[16];
111 $custom_params = @$row[17];
112 $subscribeall = @$row[18];
113 $timeout1 = @$row[19];
114 $timeout2 = @$row[20];
Matthias Andreas Benkard9dabdab2024-03-06 13:12:09 +0100115 $dry = @$row[21];
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100116
117 if ($enc1 eq "TLS") { $enc1 = "--tls1"; } elsif ($enc1 eq "SSL") { $enc1 = "--ssl1"; } else { undef $enc1; }
118
119 my $template = $run_dir . '/imapsync.XXXXXXX';
120 my $passfile1 = File::Temp->new(TEMPLATE => $template);
121 my $passfile2 = File::Temp->new(TEMPLATE => $template);
Matthias Andreas Benkard9dabdab2024-03-06 13:12:09 +0100122
123 binmode( $passfile1, ":utf8" );
124
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100125 print $passfile1 "$password1\n";
126 print $passfile2 trim($master_pass) . "\n";
127
128 my @custom_params_a = qqw($custom_params);
129 my $custom_params_ref = \@custom_params_a;
130
131 my $generated_cmds = [ "/usr/local/bin/imapsync",
132 "--tmpdir", "/tmp",
133 "--nofoldersizes",
Matthias Andreas Benkard8f915942021-08-16 10:57:25 +0200134 "--addheader",
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100135 ($timeout1 gt "0" ? () : ('--timeout1', $timeout1)),
136 ($timeout2 gt "0" ? () : ('--timeout2', $timeout2)),
137 ($exclude eq "" ? () : ("--exclude", $exclude)),
138 ($subfolder2 eq "" ? () : ('--subfolder2', $subfolder2)),
139 ($maxage eq "0" ? () : ('--maxage', $maxage)),
140 ($maxbytespersecond eq "0" ? () : ('--maxbytespersecond', $maxbytespersecond)),
141 ($delete2duplicates ne "1" ? () : ('--delete2duplicates')),
142 ($subscribeall ne "1" ? () : ('--subscribeall')),
143 ($delete1 ne "1" ? () : ('--delete')),
144 ($delete2 ne "1" ? () : ('--delete2')),
145 ($automap ne "1" ? () : ('--automap')),
146 ($skipcrossduplicates ne "1" ? () : ('--skipcrossduplicates')),
147 (!defined($enc1) ? () : ($enc1)),
148 "--host1", $host1,
149 "--user1", $user1,
150 "--passfile1", $passfile1->filename,
151 "--port1", $port1,
152 "--host2", "localhost",
153 "--user2", $user2 . '*' . trim($master_user),
154 "--passfile2", $passfile2->filename,
Matthias Andreas Benkard9dabdab2024-03-06 13:12:09 +0100155 ($dry eq "1" ? ('--dry') : ()),
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100156 '--no-modulesversion',
157 '--noreleasecheck'];
158
159 try {
Matthias Andreas Benkardb4b5cc12021-12-28 18:02:04 +0100160 $is_running = $dbh->prepare("UPDATE imapsync SET is_running = 1, success = NULL, exit_status = NULL WHERE id = ?");
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100161 $is_running->bind_param( 1, ${id} );
162 $is_running->execute();
Matthias Andreas Benkardb4b5cc12021-12-28 18:02:04 +0100163
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100164 run [@$generated_cmds, @$custom_params_ref], '&>', \my $stdout;
Matthias Andreas Benkardb4b5cc12021-12-28 18:02:04 +0100165
166 # check exit code and status
167 ($exit_code, $exit_status) = ($stdout =~ m/Exiting\swith\sreturn\svalue\s(\d+)\s\(([^:)]+)/);
168
169 $success = 0;
170 if (defined $exit_code && $exit_code == 0) {
171 $success = 1;
172 }
173
174 $update = $dbh->prepare("UPDATE imapsync SET returned_text = ?, success = ?, exit_status = ? WHERE id = ?");
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100175 $update->bind_param( 1, ${stdout} );
Matthias Andreas Benkardb4b5cc12021-12-28 18:02:04 +0100176 $update->bind_param( 2, ${success} );
177 $update->bind_param( 3, ${exit_status} );
178 $update->bind_param( 4, ${id} );
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100179 $update->execute();
180 } catch {
Matthias Andreas Benkardb4b5cc12021-12-28 18:02:04 +0100181 $update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync', success = 0 WHERE id = ?");
Matthias Andreas Benkard4edeb9f2021-01-02 15:32:21 +0100182 $update->bind_param( 1, ${id} );
183 $update->execute();
184 } finally {
185 $update = $dbh->prepare("UPDATE imapsync SET last_run = NOW(), is_running = 0 WHERE id = ?");
186 $update->bind_param( 1, ${id} );
187 $update->execute();
188 };
189
190
191}
192
193$sth->finish();
194$dbh->disconnect();
195
196$lockmgr->unlock($lock_file);