Backup your gMail Account*

Posted on 29th Mar, 2012 in Uncategorized


Here are the steps that you need to take to backup your gMail account including all the attachments (under Windows).

1.Enable POP in Gmail

2. Download and install Cygwin

  • How to Install Cygwin
  • To download you email you need a program called fetchmail, so during the Cygwin installation go under the “Mail” category and select fetchmail, exim and procmail packages.

3. Setup and run Fetchmail

3.1 Create .fetchmailrc inside your home directory and change its permissions


$ touch .fetchmailrc poll pop.gmail.com with proto POP3 and options no dns user 'your-gmail-user@gmail.com' there with password 'your-gmail-password' is 'your-cygwin-user' here options ssl
$ chmod 0744 .fetchmailrc

3.2 Run fetchmail and find your ‘INBOX’ file (the file that contains all your email messages)


$ fetchmail -vk --service POP3+SSL

You’ll find your gMail INBOX file under /var/spool/mail named your-cygwin-user. If the mail directory doesn’t exists you need to create it and set permissions:


$ mkdir /var/spool/mail
$ chmod 0744 /var/spool/mail

4. Separate messages & pull out attachments

Once you have you downloaded you gMail messages you a ready to pull out the attachments. For this we use a program called mpack which is available for Windows as well.

The program will come up with 2 executable files mpack.exe and munpack.exe (which we are going to use to pull out all the attachments). However, munpack needs each message into separate file, that’s why we need to use some PHP magic to separate the big INBOX file into individual message files.

Here is the PHP script that does the job (you need to modify the ‘your-cygwin-user’ to what you username is):


<?php
    /** script global options */
    ini_set("max_execution_time", "9999");
    ini_set("memory_limit", "-1");
    
    /** default & config values & script init */
    $dir_part   = "parts/";

    /** get all part files inside the parts/directory */
    if ($dih = opendir($dir_part)) {
    
        while (false !== ($file_name = readdir($dih))) {
        
            if ($file_name != "." && $file_name != "..") {

                $full_name = $dir_part . $file_name;
                $total_lines = count(file($full_name));

                get_inbox_message(1, $full_name, $total_lines);
            }
        }
    }

    function get_inbox_message($start, $file, $total) {

        $line            = 0;
        $message         = array();
        $message_content = "";
    
        $fih = new SplFileObject($file);
        $fih->seek($start);

        while(!$fih->eof()) {
        
            if ($fih->current() != "")
                $message[] = $fih->current();
                
            /** exits at the end of the file but don't
                forget to write the last message */
            if ($fih->key() == $total) {

                foreach($message as $message_line) {

                    $message_content .= $message_line;
                }

                $file_tmp = "messages/msg" . base_convert(mt_rand(0x19A100, 0x39AA3FF), 10, 36) . ".tmp";
                $foh = fopen($file_tmp, "w");
                fwrite($foh, $message_content);
                fclose($foh);

                return 1;
            }

            /** marker which is set by fetchmail, this is where the
                start of each gmail message is. NEED TO CHANGE TO YOUR MARKER.
                Sample: From kobra Sun Mar 11 22:15:20 2012 */
            if (preg_match("/From kobra/", $fih->current(), $matches)) {

                foreach($message as $message_line) {

                    $message_content .= $message_line;
                }

                $file_tmp = "messages/msg" . base_convert(mt_rand(0x19A100, 0x39AA3FF), 10, 36) . ".tmp";
                $foh = fopen($file_tmp, "w");
                fwrite($foh, $message_content);
                fclose($foh);

                // go to the next line
                $line++;
                $fih->next();
                

                /** recursion starts here pass all default options
                    + setup new start line */

                return get_inbox_message($start + $line, $file, $total);
            }
            
            $line++;
            $fih->next();
        }
    }
?>

And once we have all gMail messages into separate files we are ready to run the munpack (assuming the the all messages are under /messages directory)


C:>munpack messages/*

Continue reading in Part 2 of the article.


* Okay, I know there are a lot of steps involved and for larger gMail boxes it can take quite a while to do the backup (it took me 2 days to backup my 5GB account, 10-12 hours to download and another 10-12 hours to separate (part 2) the INBOX file into single message files)