123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #! /bin/sh -e
- ## 20-cleanup.dpatch by Theodore Ts'o <tytso@mit.edu>
- ##
- ## DP: Make sure the database store and the imap database is closed
- ## DP: if isync is aborted.
- [ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
- patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
- if [ $# -ne 1 ]; then
- echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
- exit 1
- fi
- case "$1" in
- -patch) patch $patch_opts -p1 < $0;;
- -unpatch) patch $patch_opts -p1 -R < $0;;
- *)
- echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
- exit 1;;
- esac
- exit 0
- @DPATCH@
- Problem description:
- >> If isync dies in the middle of synchronization, or the network
- >> connection breaks while it is synchronizing a mailbox, new messages
- >> which are downloaded from the IMAP server do not have their UID saved
- >> to the maildir directory. This is REALLY, REALLY BAD, because it
- >> means that on the next isync, the downloaded messages are re-uploaded
- >> to the imap server, resulting in duplicate messages in the IMAP store.
- >>
- >> This takes means the network download takes longer, and if the network
- >> connection is unrealible, it means it's more likely the the IMAP
- >> connection will break, resulting in more duplicate messages being
- >> uploaded to the servers. (The first time, 14 messages were uploaded
- >> to the server. The second time I re-isynced, 65 messages were
- >> uploaded to the server, resulting in some 79 duplicate messages that I
- >> had to manually weed out. Grr, grr, grr, grr.)
- Problem solution:
- Actually, I managed to figure out the solution a while ago, and got
- hung up trying to figure out the right way to submit the patches back
- to upstream (there's no mailing list that I can find; so do you just
- communicate directly with the developers). Anyway, I got busy and I
- never had a chance to send the patches a while ago.
- This patch is not the best, but it does seem to work. Perhaps a
- better approach would be to use the more advanced API's available with
- berkdb, so you can actually force a sync to the db/dbm files after
- the mail message has been downloaded. Fundamentally, that's the
- problem. The id has been added to the db file, but the changes don't
- get forced out to disk, so in the case of an abnormal termination of
- the program, the id's never get written to disk.
- The patch enclosed below solves the problem by establishing a signal
- handler, which cleans up in the case of the user typing ^C (after the
- network connection has gone away, say because your GSM phone's GPRS
- connection has gotten flakey, for example). However, it doesn't solve
- the problem in case of an abrupt system crash. In order to address
- that problem, the overall program interfaces would have to be changed
- to use the newer berkdb interfaces directly, but that would mean
- dropping compatibility with the ancient dbm interface. Personally, I
- don't think that to be any great loss, but the changes would be much
- more invasive, and would require agreement with the upstream
- maintainer that this is the right way to go.
- Also, for bonus points, perhaps there should be an inactivity timer so
- that isync can automatically figure out when the network connection
- has gone away, and can do a clean shutdown and exit automatically,
- instead of requiring the user to type ^C.
- - Ted
- Patched files: src/main.c
- ===================================================================
- RCS file: isync-0.9.2/src/RCS/main.c,v
- retrieving revision 1.3
- diff -u -r1.3 isync-0.9.2/src/main.c
- --- isync-0.9.2/src/main.c 2004/01/10 01:13:38 1.3
- +++ isync-0.9.2/src/main.c 2004/01/10 01:14:34
- @@ -35,6 +35,7 @@
- #include <string.h>
- #include <ctype.h>
- #include <dirent.h>
- +#include <signal.h>
-
- int Quiet;
-
- @@ -92,6 +93,22 @@
- unsigned int Tag = 0;
- char Hostname[256];
- int Verbose = 0;
- +mailbox_t *CleanupMail = 0;
- +imap_t *CleanupImap = 0;
- +int CleanupValid = 0;
- +
- +static void signal_exit(int sig)
- +{
- + info("Abort received\n");
- + if (CleanupValid) {
- + info("Aborting, cleaning up\n");
- + if (CleanupMail)
- + maildir_close (CleanupMail);
- + if (CleanupImap)
- + imap_close (CleanupImap);
- + }
- + exit (1);
- +}
-
- static void
- version (void)
- @@ -319,6 +336,10 @@
- usage (1);
- }
-
- + signal(SIGTERM, signal_exit);
- + signal(SIGHUP, signal_exit);
- + signal(SIGINT, signal_exit);
- +
- gethostname (Hostname, sizeof (Hostname));
-
- load_config (config, &o2o);
- @@ -410,6 +431,9 @@
- ret = 1;
- break;
- }
- + CleanupValid = 1;
- + CleanupMail = mail;
- + CleanupImap = imap;
-
- info ("Synchronizing\n");
- i = (delete || box->delete) ? SYNC_DELETE : 0;
- @@ -460,6 +484,8 @@
-
- } while (0);
-
- + CleanupValid = 0;
- +
- /* we never sync the same mailbox twice, so close it now */
- if (mail)
- maildir_close (mail);
|