imapsync_cron.pl 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/perl
  2. use DBI;
  3. use LockFile::Simple qw(lock trylock unlock);
  4. use Proc::ProcessTable;
  5. use Data::Dumper qw(Dumper);
  6. use IPC::Run 'run';
  7. use File::Temp;
  8. use Try::Tiny;
  9. use sigtrap 'handler' => \&sig_handler, qw(INT TERM KILL QUIT);
  10. sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
  11. my $t = Proc::ProcessTable->new;
  12. my $imapsync_running = grep { $_->{cmndline} =~ /^\/usr\/bin\/perl \/usr\/local\/bin\/imapsync\s/ } @{$t->table};
  13. if ($imapsync_running eq 1)
  14. {
  15. print "imapsync is active, exiting...";
  16. exit;
  17. }
  18. sub qqw($) {
  19. my @params = ();
  20. my @values = split(/(?=--)/, $_[0]);
  21. foreach my $val (@values) {
  22. my @tmpparam = split(/ /, $val, 2);
  23. foreach my $tmpval (@tmpparam) {
  24. if ($tmpval ne '') {
  25. push @params, $tmpval;
  26. }
  27. }
  28. }
  29. foreach my $val (@params) {
  30. $val=trim($val);
  31. }
  32. return @params;
  33. }
  34. $run_dir="/tmp";
  35. $dsn = 'DBI:mysql:database=__DBNAME__;mysql_socket=/var/run/mysqld/mysqld.sock';
  36. $lock_file = $run_dir . "/imapsync_busy";
  37. $lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
  38. $lockmgr->lock($lock_file) || die "can't lock ${lock_file}";
  39. $dbh = DBI->connect($dsn, '__DBUSER__', '__DBPASS__', {
  40. mysql_auto_reconnect => 1,
  41. mysql_enable_utf8mb4 => 1
  42. });
  43. sub sig_handler {
  44. # Send die to force exception in "run"
  45. die "sig_handler received signal, preparing to exit...\n";
  46. };
  47. open my $file, '<', "/etc/sogo/sieve.creds";
  48. my $creds = <$file>;
  49. close $file;
  50. my ($master_user, $master_pass) = split /:/, $creds;
  51. my $sth = $dbh->prepare("SELECT id,
  52. user1,
  53. user2,
  54. host1,
  55. authmech1,
  56. password1,
  57. exclude,
  58. port1,
  59. enc1,
  60. delete2duplicates,
  61. maxage,
  62. subfolder2,
  63. delete1,
  64. delete2,
  65. automap,
  66. skipcrossduplicates,
  67. maxbytespersecond,
  68. custom_params,
  69. subscribeall,
  70. timeout1,
  71. timeout2
  72. FROM imapsync
  73. WHERE active = 1
  74. AND is_running = 0
  75. AND (
  76. UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_run) > mins_interval * 60
  77. OR
  78. last_run IS NULL)
  79. ORDER BY last_run");
  80. $sth->execute();
  81. my $row;
  82. while ($row = $sth->fetchrow_arrayref()) {
  83. $id = @$row[0];
  84. $user1 = @$row[1];
  85. $user2 = @$row[2];
  86. $host1 = @$row[3];
  87. $authmech1 = @$row[4];
  88. $password1 = @$row[5];
  89. $exclude = @$row[6];
  90. $port1 = @$row[7];
  91. $enc1 = @$row[8];
  92. $delete2duplicates = @$row[9];
  93. $maxage = @$row[10];
  94. $subfolder2 = @$row[11];
  95. $delete1 = @$row[12];
  96. $delete2 = @$row[13];
  97. $automap = @$row[14];
  98. $skipcrossduplicates = @$row[15];
  99. $maxbytespersecond = @$row[16];
  100. $custom_params = @$row[17];
  101. $subscribeall = @$row[18];
  102. $timeout1 = @$row[19];
  103. $timeout2 = @$row[20];
  104. if ($enc1 eq "TLS") { $enc1 = "--tls1"; } elsif ($enc1 eq "SSL") { $enc1 = "--ssl1"; } else { undef $enc1; }
  105. my $template = $run_dir . '/imapsync.XXXXXXX';
  106. my $passfile1 = File::Temp->new(TEMPLATE => $template);
  107. my $passfile2 = File::Temp->new(TEMPLATE => $template);
  108. print $passfile1 "$password1\n";
  109. print $passfile2 trim($master_pass) . "\n";
  110. my @custom_params_a = qqw($custom_params);
  111. my $custom_params_ref = \@custom_params_a;
  112. my $generated_cmds = [ "/usr/local/bin/imapsync",
  113. "--tmpdir", "/tmp",
  114. "--nofoldersizes",
  115. ($timeout1 gt "0" ? () : ('--timeout1', $timeout1)),
  116. ($timeout2 gt "0" ? () : ('--timeout2', $timeout2)),
  117. ($exclude eq "" ? () : ("--exclude", $exclude)),
  118. ($subfolder2 eq "" ? () : ('--subfolder2', $subfolder2)),
  119. ($maxage eq "0" ? () : ('--maxage', $maxage)),
  120. ($maxbytespersecond eq "0" ? () : ('--maxbytespersecond', $maxbytespersecond)),
  121. ($delete2duplicates ne "1" ? () : ('--delete2duplicates')),
  122. ($subscribeall ne "1" ? () : ('--subscribeall')),
  123. ($delete1 ne "1" ? () : ('--delete')),
  124. ($delete2 ne "1" ? () : ('--delete2')),
  125. ($automap ne "1" ? () : ('--automap')),
  126. ($skipcrossduplicates ne "1" ? () : ('--skipcrossduplicates')),
  127. (!defined($enc1) ? () : ($enc1)),
  128. "--host1", $host1,
  129. "--user1", $user1,
  130. "--passfile1", $passfile1->filename,
  131. "--port1", $port1,
  132. "--host2", "localhost",
  133. "--user2", $user2 . '*' . trim($master_user),
  134. "--passfile2", $passfile2->filename,
  135. '--no-modulesversion',
  136. '--noreleasecheck'];
  137. try {
  138. $is_running = $dbh->prepare("UPDATE imapsync SET is_running = 1 WHERE id = ?");
  139. $is_running->bind_param( 1, ${id} );
  140. $is_running->execute();
  141. run [@$generated_cmds, @$custom_params_ref], '&>', \my $stdout;
  142. $update = $dbh->prepare("UPDATE imapsync SET returned_text = ? WHERE id = ?");
  143. $update->bind_param( 1, ${stdout} );
  144. $update->bind_param( 2, ${id} );
  145. $update->execute();
  146. } catch {
  147. $update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync' WHERE id = ?");
  148. $update->bind_param( 1, ${id} );
  149. $update->execute();
  150. } finally {
  151. $update = $dbh->prepare("UPDATE imapsync SET last_run = NOW(), is_running = 0 WHERE id = ?");
  152. $update->bind_param( 1, ${id} );
  153. $update->execute();
  154. };
  155. }
  156. $sth->finish();
  157. $dbh->disconnect();
  158. $lockmgr->unlock($lock_file);