#!/usr/bin/perl use strict; use warnings; use IO::Socket::SSL; use IO::All; use Mail::IMAPTalk; use Shell::Command qw(mkpath rm_rf); use Date::Parse; my $maildir = '/home//.mailbackup'; # IMAP folders will be placed here my $host = 'mail.messagingengine.com'; # IMAP server my $user = ''; # IMAP username my $pass = ''; # IMAP password mkpath($maildir), chmod 0700, $maildir if !-e $maildir; chdir $maildir or die "Could not change to directory $maildir: $!\n"; my $sock = IO::Socket::SSL->new("$host:993") or die "Could not connect to IMAP server\n"; $sock->autoflush(1); my $imap = Mail::IMAPTalk->new( Socket => $sock, Username => $user, Password => $pass, Uid => 1, UseBlocking => 1, RootFolder => 'INBOX', Separator => '.', ) or die "Could not login to IMAP server\n"; my %folders; # remote for my $folder (map { $_->[2] } $imap->list('*', '*')) { next if $folder =~ /^(Junk|Trash)/; $imap->select($folder) or die "Could not select folder '$folder'\n"; my $res = $imap->search('all'); $folders{$folder} = {map { $_ => 1 } @{$res}}; mkpath($folder), chmod 0700, $folder if !-e $folder; } # local for my $dir (io($maildir)->all_dirs) { if (!exists $folders{$dir->filename}) { rm_rf($dir->name); next; } my $folder = $folders{$dir->filename}; for my $file (io($dir->name)->all_files) { if (exists $folder->{$file->filename}) { delete $folder->{$file->filename}; } else { unlink $file->name; } } } # remote for my $folder (keys %folders) { $imap->select($folder) or die "Could not select folder '$folder'\n"; print "Syncing messages in folder '$folder'\n"; for my $uid (sort { $a <=> $b } keys %{$folders{$folder}}) { print "Fetching message $uid\n"; my $res = $imap->fetch($uid, '(internaldate rfc822)'); my $timestamp = str2time($res->{$uid}->{'internaldate'}); my $x = "$maildir/$folder/$uid"; io("$x.tmp")->println($res->{$uid}->{'rfc822'})->rename($x); chmod 600, $x; utime time, $timestamp, $x; } } $imap->logout();