No description
  • Perl 91.6%
  • Python 8.3%
  • Shell 0.1%
Find a file
Florian Schommertz 9f091cc4f5 Working 1.0
2026-10-16 10:15:12 +02:00
.gitignore Working 1.0 2026-10-16 10:15:12 +02:00
dn-imapsync Working 1.0 2026-10-16 10:15:12 +02:00
imapsync Working 1.0 2026-10-16 10:15:12 +02:00
install.sh Working 1.0 2026-10-16 10:15:12 +02:00
PLAN.md Working 1.0 2026-10-16 10:15:12 +02:00
README.md Working 1.0 2026-10-16 10:15:12 +02:00
STYLE.md Working 1.0 2026-10-16 10:15:12 +02:00
sync.py Working 1.0 2026-10-16 10:15:12 +02:00
test_dn_imapsync.py Working 1.0 2026-10-16 10:15:12 +02:00

dn-imapsync

Copy one email account to another, step by step in a full-screen Terminal window. A guided wrapper around imapsync. Works with normal IMAP providers such as IONOS, Strato, All-Inkl, GMX, web.de, Fastmail, iCloud. Needs nothing from Homebrew: only the Python and Perl that macOS ships.

Use

The first run installs imapsync by itself (about a minute): it downloads imapsync 2.314 next to the script and puts the Perl modules it needs into ~/perl5. No sudo, no shell profile changes. If macOS asks to install the Command Line Tools, accept and run ./dn-imapsync again. ./install.sh does the same install by hand.

./dn-imapsync            # guided copy
./dn-imapsync --dry-run  # log in, show the folders, copy nothing

It needs a real terminal window of at least 80x24. Steps:

  1. Source (the old account) and 2. Destination (the new one): email or username, password, server (guessed from the address; type over it if wrong), port and security. Press F2 to test. Five checks run one after another: server found, port open, secure connection, login, folders found. A failed check says what is wrong and what to do. [ Next ] unlocks when all five pass.
  2. Folders: tick the folders to copy. Gmail's [Gmail]/All Mail starts unticked. Below the list, an optional field Only mails since (press Tab to edit it) takes a date as 2024-01-01 or 01.01.2024; empty means everything. Only mails that arrived on or after that date are copied (imapsync's own IMAP SEARCH SINCE, read-only on the old account). Older mails are left out on purpose: they are not errors and not in the report. The folder counts are totals, before the date filter.
  3. Copy: progress bar, counters, ETA, folder results.
  4. Done: result, counts, log file.
┌──────────────────────────────────────────────────────────────────────────────┐
│ dn-imapsync                                                                  │
│ 1 Source · 2 Destination · 3 Folders · 4 Copy · 5 Done                       │
│ Copy FROM (the old account)                                                  │
│                                                 Checks                       │
│   Email / username a@x.de                  ✓    ✓ Server name found          │
│   Password         ••                      ✓    ✓ Port open                  │
│   Server           127.0.0.1               ✓    ✓ Secure connection          │
│   Port             11431                   ✓    ✓ Login accepted             │
│   Security         ‹ SSL/TLS (993) ›       ✓    ✓ Folders found 3 folders    │
│ [ Test connection ]   [ Back ] [ Next ]                                      │
└──────────────────────────────────────────────────────────────────────────────┘

Keys: ↑ ↓ Tab Shift-Tab move, Enter next, F2 test, ← → Space change security, Esc back, Space tick a folder, a tick all, q quit (on the folder, copy and done screens), Ctrl-C quit anywhere. While copying, quitting asks Stop copying? [y/N]. c on the last screen copies again.

The source account is never changed: nothing is deleted or moved there. Running it again is safe. Messages already on the destination are skipped, so an interrupted copy continues where it stopped. Exit code: 0 success, imapsync's code on failure, 130 if stopped.

Extra imapsync flags go after --, for example ./dn-imapsync -- --maxsize 50000000. Flags that delete or expunge are refused.

Passwords

Passwords are kept in memory and written to two 0600 temp files for imapsync, which are deleted on every normal exit and on SIGTERM/SIGHUP. After kill -9 or a power cut they can stay in the system temp folder (macOS clears it on reboot).

Stopping and resuming

You can stop a copy at any time and run it again later. Messages are matched by their Message-Id, and the ones already on the destination are skipped, so a re-run continues where it left off. c (Continue) on the Done screen does the same.

Messages that were not copied

After every copy a plain-text report is written next to the log (~/Library/Logs/dn-imapsync/<time>_report.txt): one line per message that failed or was too big for the destination, with the folder, message number, size and the reason. No subjects, no bodies, no passwords. The Done screen shows the first three lines; press r to read it.

Logs

~/Library/Logs/dn-imapsync/ holds one log per run. Passwords are never written there.

Providers

  • Gmail: needs an app password: https://myaccount.google.com/apppasswords.
  • Outlook.com / Microsoft 365: may refuse password login. Try an app password; there is no OAuth2 support.
  • iCloud: needs an app-specific password.
  • GMX, web.de: switch on IMAP access in the mail settings first.

Troubleshooting

New mailbox looks empty? Check the folder list in your mail app, the copied folders appear by their original names, and INBOX is only copied when ticked.

Not included

OAuth2, two-way sync, deleting from the source, contacts and calendars, saved profiles. Anything else imapsync can do is reachable through --.

Tests

/usr/bin/python3 -m unittest