imapsync_cron.pl 4.6 KB

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