From 399651d088c477435e1bf507c6f482f0b44504c2 Mon Sep 17 00:00:00 2001 From: Nick Bebout Date: Mon, 24 Oct 2022 21:20:30 -0500 Subject: [PATCH] 2.229 --- ChangeLog | 129 +- FAQ.d/FAQ.Archiving.txt | 4 +- FAQ.d/FAQ.Authentication_failure.txt | 24 +- FAQ.d/FAQ.Big_Mailbox.txt | 2 +- FAQ.d/FAQ.Capacity_Planning.txt | 56 +- FAQ.d/FAQ.Contacts_Calendars.txt | 24 +- FAQ.d/FAQ.Dovecot.txt | 16 +- FAQ.d/FAQ.Emptying.txt | 25 +- FAQ.d/FAQ.Flags.txt | 20 +- FAQ.d/FAQ.Folders_Sizes.txt | 11 +- FAQ.d/FAQ.General.txt | 16 +- FAQ.d/FAQ.Gmail.txt | 85 +- FAQ.d/FAQ.ISP.txt | 58 +- FAQ.d/FAQ.Massive.txt | 106 +- FAQ.d/FAQ.Office365.txt | 16 +- FAQ.d/FAQ.OnlineUI.txt | 55 +- FAQ.d/FAQ.Release_Checklist.txt | 24 +- FAQ.d/FAQ.Two_Ways_Sync.txt | 67 +- FAQ.d/FAQ.User_Concurrent_Access.txt | 21 +- FAQ.d/FAQ.Yahoo.txt | 15 +- FAQ.d/FAQ.iCloud.txt | 24 + INSTALL.d/Dockerfile | 3 +- INSTALL.d/INSTALL.AWS_EC2.txt | 6 +- INSTALL.d/INSTALL.ArchLinux.txt | 5 +- INSTALL.d/INSTALL.Centos.txt | 10 +- INSTALL.d/INSTALL.Darwin.txt | 3 +- INSTALL.d/INSTALL.Debian.txt | 3 +- INSTALL.d/INSTALL.Docker_build.txt | 3 +- INSTALL.d/INSTALL.FreeBSD.txt | 9 +- INSTALL.d/INSTALL.OnlineUI.txt | 73 +- INSTALL.d/INSTALL.Ubuntu.txt | 10 +- INSTALL.d/INSTALL.webserver.txt | 18 + INSTALL.d/prerequisites_imapsync | 3 +- Makefile | 238 ++- README | 17 +- S/imapservers.shtml | 14 +- S/news.shtml | 35 +- S/paypal_return.shtml | 4 +- TODO | 28 +- VERSION | 2 +- X/cgi_memo | 864 +++++++- X/imapsync_form.js | 6 +- X/imapsync_form_extra.html | 12 +- X/imapsync_form_extra_free.html | 10 +- X/imapsync_online_status_24h_1200x70.png | Bin 17612 -> 0 bytes X/imapsync_online_status_2months_1200x70.png | Bin 19768 -> 0 bytes X/imapsync_online_status_7d_1200x70.png | Bin 19746 -> 0 bytes X/index.html | 2 +- ...psync_form_new.js => proximapsync_form.js} | 206 +- X/proximapsync_form_extra.html | 476 +++++ X/proximapsync_form_extra_free.html | 536 +++++ X/stat_patterns.txt | 3 +- X/u.html | 2 +- aa | 1542 +++++++++++++++ imapsync | 1752 ++++++++++++----- index.shtml | 249 ++- oauth2/README_OAUTH2.txt | 5 +- tests.sh | 62 +- 58 files changed, 5882 insertions(+), 1127 deletions(-) create mode 100644 FAQ.d/FAQ.iCloud.txt create mode 100644 INSTALL.d/INSTALL.webserver.txt delete mode 100644 X/imapsync_online_status_24h_1200x70.png delete mode 100644 X/imapsync_online_status_2months_1200x70.png delete mode 100644 X/imapsync_online_status_7d_1200x70.png rename X/{imapsync_form_new.js => proximapsync_form.js} (70%) create mode 100644 X/proximapsync_form_extra.html create mode 100644 X/proximapsync_form_extra_free.html create mode 100644 aa mode change 100755 => 100644 oauth2/README_OAUTH2.txt diff --git a/ChangeLog b/ChangeLog index 591d185..d1115f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,17 +1,138 @@ RCS file: RCS/imapsync,v Working file: imapsync -head: 2.200 +head: 2.229 branch: locks: strict - gilles: 2.200 + gilles: 2.229 access list: symbolic names: keyword substitution: kv -total revisions: 1100; selected revisions: 1100 +total revisions: 1129; selected revisions: 1129 description: ---------------------------- -revision 2.200 locked by: gilles; +revision 2.229 locked by: gilles; +date: 2022/09/14 18:08:24; author: gilles; state: Exp; lines: +16 -16 +Make pass "make linuxtests win32tests win64tests mactests" +---------------------------- +revision 2.228 +date: 2022/09/13 12:14:02; author: gilles; state: Exp; lines: +10 -9 +Doc. --oauthaccesstoken1 needs --password1 presence. This is a bug. +---------------------------- +revision 2.227 +date: 2022/07/28 15:59:38; author: gilles; state: Exp; lines: +347 -112 +Bugfix. Fixed memory measurement on MacOS and Win32 Win64 +---------------------------- +revision 2.226 +date: 2022/07/15 12:02:47; author: gilles; state: Exp; lines: +30 -26 +1966 unit tests +---------------------------- +revision 2.225 +date: 2022/07/14 16:56:11; author: gilles; state: Exp; lines: +14 -11 +*** empty log message *** +---------------------------- +revision 2.224 +date: 2022/07/13 17:33:42; author: gilles; state: Exp; lines: +8 -8 +typo connexions connections +---------------------------- +revision 2.223 +date: 2022/07/03 10:39:30; author: gilles; state: Exp; lines: +48 -11 +Default is now like --noemailreport1 --noemailreport2, no final email report. Popular demand. +Added a stat value: memory footprint times time spent during the sync. Unity MiB * hour. Line "Memory consumption at the end". +---------------------------- +revision 2.222 +date: 2022/06/29 12:13:58; author: gilles; state: Exp; lines: +9 -10 +Remove --memorystress from CGI options. +---------------------------- +revision 2.221 +date: 2022/06/28 23:12:01; author: gilles; state: Exp; lines: +72 -63 +CGI context. Refuse to serve when the cpu load is greater than 1 per cpu. A load of 3.9 with 4 cores is ok. +---------------------------- +revision 2.220 +date: 2022/06/28 19:01:18; author: gilles; state: Exp; lines: +8 -8 +CGI context. Refuse to server when memory left is less than 1 GB. +---------------------------- +revision 2.219 +date: 2022/06/25 21:33:30; author: gilles; state: Exp; lines: +24 -19 +heavy load by cpu limit from 6 to 3. Because 6 is too big on ks6 +---------------------------- +revision 2.218 +date: 2022/06/25 06:38:24; author: gilles; state: Exp; lines: +12 -9 +Typo. memory_consumption_all_pids_percent with only 2 decimals. +---------------------------- +revision 2.217 +date: 2022/06/25 06:16:42; author: gilles; state: Exp; lines: +148 -52 +CGI context. Bring back to exit on heavy load by cpu. limit is a load of 6 per core, roughly the number of processes running constantly per core. +---------------------------- +revision 2.216 +date: 2022/06/22 18:49:55; author: gilles; state: Exp; lines: +9 -9 +typo seconde second +---------------------------- +revision 2.215 +date: 2022/06/22 01:44:01; author: gilles; state: Exp; lines: +34 -21 +Added --exitonload option. Only available in CGI context for now. +---------------------------- +revision 2.214 +date: 2022/06/08 21:28:34; author: gilles; state: Exp; lines: +11 -11 +load_percent_threshold is now room for two average imapsync processes. +---------------------------- +revision 2.213 +date: 2022/05/20 11:57:22; author: gilles; state: Exp; lines: +48 -33 +Filtering buggy flags is now case insensitive. \Junk or \JUNK or \jUnK etc. +Refactoring. Added sub tests_filterbuggyflags() +---------------------------- +revision 2.212 +date: 2022/05/19 11:18:09; author: gilles; state: Exp; lines: +67 -16 +Bugfix. Do not crash when Proc::ProcessTable field pctmem does not exist. +---------------------------- +revision 2.211 +date: 2022/05/19 08:37:14; author: gilles; state: Exp; lines: +10 -10 +Last commit 2.210 did not pass the unit tests. Fixed. +---------------------------- +revision 2.210 +date: 2022/05/19 08:09:57; author: gilles; state: Exp; lines: +10 -10 +Added filtering \JUNK flag in cgi context or with --filterbuggyflags +---------------------------- +revision 2.209 +date: 2022/05/15 11:03:02; author: gilles; state: Exp; lines: +37 -9 +Enhancement. heavy_load_percent_threshold now based on memory_footprint_average_bytes 300 MB +---------------------------- +revision 2.208 +date: 2022/05/13 20:14:25; author: gilles; state: Exp; lines: +8 -8 +90% +---------------------------- +revision 2.207 +date: 2022/05/12 16:31:10; author: gilles; state: Exp; lines: +21 -21 +memory limit to quit from 100% to 50%. Quick fix. +---------------------------- +revision 2.206 +date: 2022/05/12 11:07:07; author: gilles; state: Exp; lines: +139 -54 +Added dependency. Perl module Proc::ProcessTable. Not mandatory anyway. For now. +CGI context. Exit when 100% of RAM memory is used by processes. Exit with status value 69 and message "EX_UNAVAILABLE: service unavailable". +Added the % of RAM used by all processes in the memory infi line. +---------------------------- +revision 2.205 +date: 2022/05/09 21:29:07; author: gilles; state: Exp; lines: +264 -247 +perlcritic. Change all "= shift ;" to " = shift @ARG ;" +---------------------------- +revision 2.204 +date: 2022/05/03 22:28:53; author: gilles; state: Exp; lines: +34 -9 +Do not report final emails when --dry or --justfolders +---------------------------- +revision 2.203 +date: 2022/04/26 22:57:46; author: gilles; state: Exp; lines: +42 -17 +Bugfix. Allow quota like: QUOTA "user-defined quota (konsoleH)" (STORAGE 988 48829 MESSAGE 20 20) +Enhancement. Added --memorystress to check memory crunching in normal run. +---------------------------- +revision 2.202 +date: 2022/04/18 23:40:20; author: gilles; state: Exp; lines: +89 -20 +CGI context. Do not append the log file name to ../list_all_logs_auto.txt when there is no parameters. +---------------------------- +revision 2.201 +date: 2022/04/09 08:45:27; author: gilles; state: Exp; lines: +12 -12 +Moved all getppid to mygetppid (it adds a comment on Windows, where ppid is too complicated to get. +---------------------------- +revision 2.200 date: 2022/04/04 16:05:55; author: gilles; state: Exp; lines: +14 -10 typo. "check the certificate server" => "check the server certificate." ---------------------------- diff --git a/FAQ.d/FAQ.Archiving.txt b/FAQ.d/FAQ.Archiving.txt index d4ce383..3317ec0 100644 --- a/FAQ.d/FAQ.Archiving.txt +++ b/FAQ.d/FAQ.Archiving.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Archiving.txt,v 1.26 2022/01/11 12:55:53 gilles Exp gilles $ +$Id: FAQ.Archiving.txt,v 1.27 2022/05/19 08:56:06 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -110,7 +110,7 @@ Q. How to move emails from one IMAP folder to another, either on the R1. Solution: - imapsync ... --minage 365 --folder Inbox --f1f2 INBOX=Archive --delete1 --noexpungeaftereach + imapsync ... --minage 365 --folder INBOX --f1f2 INBOX=Archive --delete1 --noexpungeaftereach Use the option --noexpungeaftereach if speed is a concern. Use the option --delete1 if you want to move messages, instead of just copy/sync them. diff --git a/FAQ.d/FAQ.Authentication_failure.txt b/FAQ.d/FAQ.Authentication_failure.txt index ec41351..262fe6d 100644 --- a/FAQ.d/FAQ.Authentication_failure.txt +++ b/FAQ.d/FAQ.Authentication_failure.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Authentication_failure.txt,v 1.15 2022/03/03 11:43:55 gilles Exp gilles $ +$Id: FAQ.Authentication_failure.txt,v 1.16 2022/08/17 09:18:17 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -25,17 +25,17 @@ Q. Imapsync fails with the following error, what can I do? Host1 failure: Error login on [imap.example.com] with user [foo] auth [LOGIN]: 2 NO [AUTHENTICATIONFAILED] Authentication failed -R. One over four imapsync syncs ends up quickly with the error message +R. One over four imapsync synchronizations end up quickly with the error message "Authentication failed" or "NO LOGIN failed" or a similar message. Authentication failure is the primary failure with imapsync and since nothing tangible can be done without authentication, this stage must succeed to go further. -Here are some advices to get you pass this difficult stage of authentication: +Here is some advice to get you to pass this difficult stage of authentication: - * Triple check each credential parameter. It's not always a password problem, + * Triple-check each credential parameter. It's not always a password problem, it can be the wrong host or the wrong user. - There are three parameters at each side: + There are three parameters on each side: * triple check --host1 * triple check --user1 * triple check --password1 @@ -43,7 +43,7 @@ Here are some advices to get you pass this difficult stage of authentication: * triple check --user2 * triple check --password2 - * If you can authenticate successfully with an other imap client software + * If you can authenticate successfully with another imap client software like Thunderbird or Outlook or Sparrow then it is a very good sign to authenticate successfully with imapsync. Examine the parameters of this other imap client and copy them as is for imapsync. @@ -52,7 +52,7 @@ Here are some advices to get you pass this difficult stage of authentication: At the beginning of the output, imapsync dumps all its command line parameters; it's the line after "Command line used:". With --showpasswords, imapsync prints the passwords received - instead of the string MASKED. It helps for debugging quoting issues. + instead of the string MASKED. It helps with debugging quoting issues. Option --showpasswords shows passwords again when the IMAP dialog is dumped by --debugimap option. Search for a line like "Sending: 2 LOGIN test1 secret1" (secret1 is the password here). @@ -64,18 +64,18 @@ Here are some advices to get you pass this difficult stage of authentication: https://imapsync.lamiral.info/FAQ.d/FAQ.Passwords_on_Mac.txt The quickest trick may be to change the password temporally - with easy characters like the classical alphabet, a long - string still ensure strong security. + with easy characters like the classical alphabet, one long + string still ensures strong security. * Sometimes some servers announce they support LOGIN but it - actually fails because the authentication mechanism + fails because the authentication mechanism working is something else like CRAM-MD5 or PLAIN. So: * Try --authmech1 CRAM-MD5 (or --authmech2 CRAM-MD5) * Try --authmech1 PLAIN (or --authmech2 PLAIN) * Manually test a login via ssl. - Use either ncat or telnet-ssl or openssl commands like in the + Use either ncat or telnet-ssl or openssl commands, like in the following examples with imap.gmail.com server: ncat --ssl -C imap.gmail.com 993 @@ -85,7 +85,7 @@ Here are some advices to get you pass this difficult stage of authentication: Replace imap.gmail.com by your imap server. The three commands do the same work here. -Tipical dialog for an imap LOGIN command: +Typical dialog for an imap LOGIN command: * OK Gimap ready for requests from 78.196.254.58 q1mb175739668wix a LOGIN "gilles.lamiral@gmail.com" "secret" diff --git a/FAQ.d/FAQ.Big_Mailbox.txt b/FAQ.d/FAQ.Big_Mailbox.txt index f2177a9..5a7a6c1 100644 --- a/FAQ.d/FAQ.Big_Mailbox.txt +++ b/FAQ.d/FAQ.Big_Mailbox.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Big_Mailbox.txt,v 1.7 2021/02/01 21:47:41 gilles Exp gilles $ +$Id: FAQ.Big_Mailbox.txt,v 1.8 2022/04/23 13:45:48 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ diff --git a/FAQ.d/FAQ.Capacity_Planning.txt b/FAQ.d/FAQ.Capacity_Planning.txt index 54a8ad2..abc3d00 100644 --- a/FAQ.d/FAQ.Capacity_Planning.txt +++ b/FAQ.d/FAQ.Capacity_Planning.txt @@ -1,4 +1,4 @@ -$Id: FAQ.Capacity_Planning.txt,v 1.3 2022/03/22 11:12:25 gilles Exp gilles $ +$Id: FAQ.Capacity_Planning.txt,v 1.6 2022/04/23 13:45:59 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -19,18 +19,49 @@ My current question is: Shall I use * N/2 4GB hosts * N/4 8GB hosts -Let's do some maths +Let's do some observations and maths + +The observations are done on the standalone imapsync online which +characteristics are: + +CPU: Intel i5-2300 with 4 cores + +RAM: 16 GB + +NET: 100 Mbps symetrical, 12.5 MBytes/s symetrical, + so 25 MBytes/s max for a global imapsync rate. + +Disks: I don't know. + +System: FreeBSD 11.4 + +===== CPU ===== The CPU can be an issue. On average, an imapsync run takes 5% of the overall cpu time for a Intel i5-2300 with 4 cores. It implies 20 imapsync runs is ok on the current online host before the cpus become the bottleneck. As a rule of thumb, imapsync takes 20% of a cpu core. +In the Intel i5-2300 4 cores, so far, the maximum number of imapsync +processes has been 68, which is 3 times what the system should +support in a standard imapsync workload. For this workload, the +imapsync performamces were not good, the server could not handle the load +and was even out of order for a while. For 40 imapsync processes, the +the performances are ok. + +===== RAM ===== + The RAM can be an issue. On average, an imapsync run takes 250 MB. So 4 imapsync processes per GB is the limit before swapping to disk, which is a known phenomenum telling when memory becomes the bottleneck. 16 GB allows 64 imapsync processes. +On the 16GB, so far, the maximum memory usage taken by imapsync processes was +13 GB. For that value, the one minute load was 10 or more, the number of +imapsync processes was around 40, the total bandwidth was around 19 MiB/s. + +===== LINK ===== + The Bandwidth I/O can be an issue. The "Average bandwidth rate" value given by imapsync at the end of a transfer, and also the bandwidth rate given during the sync on the ETA line, is the total size of all @@ -43,13 +74,30 @@ On average, an imapsync runs at 3 Mbps both ways, rx and tx, so 6 Mbps in total. So a 100 Mbps symetric link allows 33 imapsync processes before the link becomes the bottleneck. -The best minutes observed so far are a global 187 Mpbs rate (23 MiB/s) +The best minutes observed so far are a global 187 Mpbs rate (~23 MiB/s) on a 100 Mbps symetrical link done by 28 imapsync processes in parallel, 6.7 Mbps per process at that minute. But the best minutes observed for a -single imapsync process is at 103 Mbps, the rx/tx link limit. +single imapsync process is at 103 Mbps (~13 MiB/s), the rx/tx link limit. +===== DISKS ===== The harddisk I/O can be an issue. I don't measure it yet because imapsync doesn't perform heavy I/0 where it runs. Well, I don't know, no measure is no knowledge, just guesses. + +===== Repartition ====== + + +Let's consider we have a bunch of different hosts able to run imapsync +processes. How should we distribute imapsync jobs among them? + +A simple rule is "do not add more load to a host when one of the ressources +has reached its maximal. The ressources are memory, bandwidth, cpu, disk. +I ignore the disk part for now. + +maximum number of imapsync processes for a host += min( 4 * RAM_in_GB, 10 * nb_cores, bandwidth_in_mbps / 3 ) + + + diff --git a/FAQ.d/FAQ.Contacts_Calendars.txt b/FAQ.d/FAQ.Contacts_Calendars.txt index 84e94c3..18424b3 100644 --- a/FAQ.d/FAQ.Contacts_Calendars.txt +++ b/FAQ.d/FAQ.Contacts_Calendars.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Contacts_Calendars.txt,v 1.16 2022/04/05 13:48:52 gilles Exp gilles $ +$Id: FAQ.Contacts_Calendars.txt,v 1.17 2022/05/31 22:21:55 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -21,10 +21,10 @@ Now the questions again with their answers. Q. Can I copy or sync Contacts, Calendars, Tasks or Chat messages with imapsync? R. No, Imapsync can't migrate Contacts, Calendars, Tasks nor Chat messages. - It's because most IMAP servers don't get contacts and calendars + It's because most IMAP servers don't get Contacts and Calendar events via IMAP. In other words, messages synced by imapsync from Contacts/Calendars/Tasks/Chat folders are not used by email servers to set - or get the contacts, calendars, tasks or chat messages. + or get the contacts, calendars, tasks, or chat messages. No way via IMAP, no way via imapsync. So it's a good idea to avoid syncing contacts and calendars when @@ -55,20 +55,20 @@ b) From Gmail to Gmail, export and import calendars in ical format, c) For Outlook, use caldavsynchronizer. Homepage: http://caldavsynchronizer.org/ Outlook CalDav Synchronizer is a free Outlook Plugin, which synchronizes - events, tasks and contacts between Outlook and Google, SOGo, Nextcloud or + events, tasks, and contacts between Outlook and Google, SOGo, Nextcloud or any other CalDAV or CardDAV server. - Supported Outlook versions are Office 365, 2019, 2016, 2013, 2010 and 2007. + Supported Outlook versions are Office 365, 2019, 2016, 2013, 2010, and 2007. Free and Open Source software tool. -d) Etc. Search the web. There's also specific tools and paid services. +d) Etc. Search the web. There are also specific tools and paid services. There's no silver bullet to migrate Calendars and Contacts, if you find one, tell me! - Also consider asking experts at Sumatra company + Also, consider asking experts at the Sumatra company https://twitter.com/sumatra_dev http://sumatra.com/ -e) I plan to make tools for that but so far nothing has began +e) I plan to make tools for that but so far nothing has begun more than this discussion: http://linux-france.tk/prj/imapsync_list/msg01797.html http://linux-france.tk/prj/imapsync_list/msg01811.html @@ -77,10 +77,10 @@ http://linux-france.tk/prj/imapsync_list/msg01811.html Q. How can I avoid copying Calendar or Contacts folders? R. You can avoid synchronizing Calendar or Contacts folders with - the --exclude option. First you have to search what is their - exact name. The folders listing printed by imapsync at the + the --exclude option. First, you have to search what is their + exact name. The listing of folders printed by imapsync at the beginning of a run will surely help to find their names. - Assuming their names are "Calendars" and "Contacts" use then: + Assuming their names are "Calendars" and "Contacts", use: imapsync ... --exclude "Calendar" --exclude "Contacts" @@ -89,7 +89,7 @@ R. You can avoid synchronizing Calendar or Contacts folders with like "MyCalendarZ" or "TheContactsImDoneWith". Also, case matters: "calendar" does not match "Calendar". - To stritly avoid only "Calendar" or "Contacts" use + To strictly avoid only "Calendar" or "Contacts" use the following On windows: diff --git a/FAQ.d/FAQ.Dovecot.txt b/FAQ.d/FAQ.Dovecot.txt index 74b02b5..fb2d2ea 100644 --- a/FAQ.d/FAQ.Dovecot.txt +++ b/FAQ.d/FAQ.Dovecot.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Dovecot.txt,v 1.13 2021/12/03 12:51:23 gilles Exp gilles $ +$Id: FAQ.Dovecot.txt,v 1.14 2022/06/16 09:06:34 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -15,6 +15,10 @@ Questions answered in this FAQ are: Q. Is there imapsync specific options to deal with Dovecot? +Q. The login fails with the error: + Err 1/1: Host2 failure: Error login on [...] with user [...] auth [LOGIN]: timeout waiting 120s for data from server (5x) + What can it be? + Q. Subfolders are not created by imapsync and the error is "Mailbox doesn't allow inferior mailboxes" @@ -34,7 +38,15 @@ Now the questions again with their answers. Q. Is there imapsync specific options to deal with Dovecot? R. Dovecot is ok with imapsync, nothing special is needed, just the - basic option, the credentials, are needed. + basic options, ie, the credentials, are needed. + +======================================================================= +Q. The login fails with the error: + Err 1/1: Host2 failure: Error login on [...] with user [...] auth [LOGIN]: timeout waiting 120s for data from server (5x) + What can it be? + +R. It can be special characters in the password. Change it with only + normal characters, characters from a-z A-Z 0-9 ======================================================================= Q. How to migrate to Dovecot with an admin/MasterUser account? diff --git a/FAQ.d/FAQ.Emptying.txt b/FAQ.d/FAQ.Emptying.txt index 014ef12..e57234e 100644 --- a/FAQ.d/FAQ.Emptying.txt +++ b/FAQ.d/FAQ.Emptying.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Emptying.txt,v 1.12 2021/09/09 11:53:53 gilles Exp gilles $ +$Id: FAQ.Emptying.txt,v 1.14 2022/06/08 11:08:39 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -7,7 +7,7 @@ https://imapsync.lamiral.info/FAQ.d/ https://imapsync.lamiral.info/FAQ.d/FAQ.Emptying.txt ======================================================================= - Imapsync tip to empty an account. + Imapsync tips about deletions. ======================================================================= Questions answered in this FAQ are: @@ -24,6 +24,8 @@ Q. How to delete emails older than 90 days with imapsync? Q. How to delete emails matching a certain criterium with imapsync? +Q. Is there a way to delete the destination folders when the source + folders are no longer there? Now the questions again with their answers. @@ -128,5 +130,24 @@ Example: --host2 test.lamiral.info --user2 foo --password2 secret \ --delete1 --noexpungeaftereach --search "SENTBEFORE 31-Dec-2010" +====================================================================== +Q. Is there a way to delete the destination folders when the source + folders are no longer there? + +R. Yes, use --delete2folders + + --delete2folders : Delete folders in host2 that are not in host1. + For safety, first try it like this, it is safe: + --delete2folders --dry --justfolders --nofoldersizes + and see what folders will be deleted. + + --delete2foldersonly reg : Delete only folders matching the regex reg. + Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/" + This option activates --delete2folders + + --delete2foldersbutnot reg : Do not delete folders matching the regex rex. + Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/" + This option activates --delete2folders + ======================================================================= ======================================================================= \ No newline at end of file diff --git a/FAQ.d/FAQ.Flags.txt b/FAQ.d/FAQ.Flags.txt index 0f39077..6c483d0 100644 --- a/FAQ.d/FAQ.Flags.txt +++ b/FAQ.d/FAQ.Flags.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Flags.txt,v 1.26 2021/04/25 20:47:05 gilles Exp gilles $ +$Id: FAQ.Flags.txt,v 1.28 2022/06/22 17:07:35 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -22,6 +22,9 @@ Q. Exchange sends an email to any sender whose email is deleted without reading. It's called "unread notifications". How to set the \Seen flag on host1 (source system) before syncing? +Q. Every single mail synced to exchange online owns the + category $MDNSent after migration. How can I avoid this? + Q. Does imapsync retain the \Answered and $Forwarded flags? Q. How to fix this error: BAD Invalid system flag \FORWARDED @@ -174,6 +177,18 @@ https://translate.google.com/translate?sl=auto&tl=en&u=https%3A%2F%2Fwww.ci-solu German original: https://www.ci-solution.com/blog/artikel/ungelesen-geloescht-verhindern.html (Link from Oliver B.) + +====================================================================== +Q. Every single mail synced to exchange online owns the + category $MDNSent after migration. How can I avoid this? + +R. To remove the flag $MDNSent from all messages, use: + + imapsync ... --regexflag "s/\$MDNSent//g" + +See also the document +https://imapsync.lamiral.info/FAQ.d/FAQ.Flags.txt + ======================================================================= Q. Does imapsync retain the \Answered and $Forwarded flags? @@ -305,7 +320,8 @@ You can try --nofilterflags straightaway without the "other thunderbird" proposal. There is also the possibility to map flags across servers -with --regexflags +with the option --regexflag. See some --regexflag examples +above. ======================================================================= diff --git a/FAQ.d/FAQ.Folders_Sizes.txt b/FAQ.d/FAQ.Folders_Sizes.txt index 14081c9..5128310 100644 --- a/FAQ.d/FAQ.Folders_Sizes.txt +++ b/FAQ.d/FAQ.Folders_Sizes.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Folders_Sizes.txt,v 1.5 2021/07/04 23:02:32 gilles Exp gilles $ +$Id: FAQ.Folders_Sizes.txt,v 1.7 2022/04/23 13:45:15 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -61,11 +61,16 @@ R. There are several reasons to explain the different counts between found at the end on the line "Messages found duplicate on host1". To sync duplicates, use the option --syncduplicates -5) There are duplicate messages on host2 so host2 is +5) There are cross-duplicate messages on host1, same messages in different + folders, and you use --gmail1 or --skipcrossduplicates, which avoid + copying cross-duplicate messages in more than one folder on host2. + Use --noskipcrossduplicates if you want imapsync to sync cross-duplicates. + +6) There are duplicate messages on host2 so host2 is bigger than host1. Solution: use --delete2duplicates to delete the host2 duplicates. -6) Cosmic rays... +7) Cosmic rays... The important part to take into account for a good and well done sync is the last lines of imapsync. A good sync is when you encounter the diff --git a/FAQ.d/FAQ.General.txt b/FAQ.d/FAQ.General.txt index df5b1b5..115f686 100644 --- a/FAQ.d/FAQ.General.txt +++ b/FAQ.d/FAQ.General.txt @@ -1,5 +1,5 @@ #!/bin/cat -# $Id: FAQ.General.txt,v 1.245 2022/04/05 13:55:47 gilles Exp gilles $ +# $Id: FAQ.General.txt,v 1.246 2022/06/08 10:57:52 gilles Exp gilles $ ======================================================================= General FAQ for imapsync @@ -570,20 +570,6 @@ In imapsync, you can achieve this by using the following options: --proxyauth1 \ --passfile admin.txt -====================================================================== -Q. Is there a way to delete the destination folder when the source - folder is no longer there? - -R. Yes, use --delete2folders - ---delete2folders : Delete folders in host2 that are not in host1 server. - For safety, first try it like this (it is safe): - --delete2folders --dry --justfolders --nofoldersizes ---delete2foldersonly : Deleted only folders matching regex. - Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/" ---delete2foldersbutnot : Do not delete folders matching regex. - Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/" - ======================================================================= Q. I would love to have a function to inject lines in the header. Things like "X-migrated-from-foo: 20100617" diff --git a/FAQ.d/FAQ.Gmail.txt b/FAQ.d/FAQ.Gmail.txt index 387eaa0..f5b905f 100644 --- a/FAQ.d/FAQ.Gmail.txt +++ b/FAQ.d/FAQ.Gmail.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Gmail.txt,v 1.87 2022/02/10 12:42:52 gilles Exp gilles $ +$Id: FAQ.Gmail.txt,v 1.92 2022/06/28 11:03:40 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -56,7 +56,9 @@ Q. What are the Gmail imap names of the folders Q. Can I transfer Gmail "Chat" messages with imapsync? -Q. Can I safely use --useuid for Gmail transfers? +Q. Can I safely use --useuid or --usecache for Gmail transfers? + +Q. Can I use --syncduplicates Gmail transfers? Q. Gmail does not really delete messages in folder [Gmail]/All Mail What happens? What can I do? @@ -95,77 +97,22 @@ it has to be allowed in the Gmail configuration part: -> Click on the button "Save changes" at the bottom of the page. That's not finished, there is also the authentication issue to consider. -There are three different ways to authenticate to Gmail with Imapsync, +There are two different ways to authenticate to Gmail with Imapsync, either: -1) "Access for less secure apps" -2) "2-step verification" -3) XOauth2 ready for groups on any OS or +1) "App password with 2-step verification" + +or + +2) XOauth2 ready for groups on any OS or for individual Gmail authentication on Linux. -For the last one, XOauth2, see the document +For the second one, XOauth2, see the document https://imapsync.lamiral.info/FAQ.d/FAQ.XOAUTH2.txt -1) "Access for less secure apps", the first way to authenticate - to Gmail with Imapsync. This is the easiest way because - you just have to turn one button on. - -Go to https://myaccount.google.com/ -Click on the Security tab on the left menu or go directly to -https://myaccount.google.com/security?gar=1 - - -> Verify 2-step verification is OFF - https://myaccount.google.com/security?hl=en&pli=1&nlr=1#signin - -Near the end of the page, - -> Turn ON "Access for less secure apps" - https://www.google.com/settings/security/lesssecureapps - https://support.google.com/accounts/answer/6010255?hl=en - -Here is what Google add on this "Access for less secure apps": -"Some apps and devices use less secure sign-in technology, which makes your -account vulnerable. You can turn off access for these apps, which we recommend, -or turn it on if you want to use them despite the risks. -Google will automatically turn this setting OFF if it’s not being used." - -So after a while, this button will be turned off again. -I suggest to turn it off once the job with imapsync is finished. - -If you forgot to also enable imap you end up with login failure like this one: -"Host failure: Error login on [imap.gmail.com] with user [xxxx@gmail.com] auth [LOGIN]: -NO [ALERT] Your account is not enabled for IMAP use. Please visit your Gmail -settings page and enable your account for IMAP access. (Failure)" - -After using imapsync on a Gmail account, sometimes you may encounter an email -with the title "Critical security alert for your linked Google Account" -and the body -"Sign-in attempt was blocked for your linked Google Account -xxxx@gmail.com -Someone just used your password to try to sign in to your account from -a non-Google app. Google blocked them, but you should check what happened. -Review your account activity to make sure that no one else has access." -Click on the button "Check Activity" and let Gmail know you were the author -of the sign in. - - -Sometimes, with Gsuite, the login for the users are ok with imapsync -for a while then they become forbidden with -"failure: Error login on [imap.gmail.com] with user [xxx] auth [LOGIN]: -2 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)" - -In that case, use: -https://admin.google.com/AdminHome?hl=fr#ServiceSettings/notab=1&service=securitysetting&subtab=lesssecureappsaccess -to allow "Access for less secure apps to all users" -(Thanks to Sébastien R. for this input) -Remark: even if the user has enabled less secure apps at Super Admin - and reseller level, it still needs amended at - https://myaccount.google.com/security - (Thanks Tony@gle for this last tip!) - - -2) "2-step verification" the second way to authenticate - to Gmail with Imapsync. +1) "App password with 2-step verification" is the first way to + authenticate to Gmail with Imapsync. Go to https://myaccount.google.com/security @@ -795,6 +742,12 @@ message, and Gmail will always accept and throw away the new copy. It ends up with no duplicates on Gmail but a waste of bandwidth and time, which is the opposite goal of --usecache implied by --useuid. +======================================================================= +Q. Can I use --syncduplicates Gmail transfers? + +R. Yes, but Gmail will accept the new duplicate message and +throw away the new copy. It ends up with no duplicates on Gmail but +a waste of bandwidth and time. ======================================================================= Q. Gmail does not really delete messages in folder [Gmail]/All Mail diff --git a/FAQ.d/FAQ.ISP.txt b/FAQ.d/FAQ.ISP.txt index 1154751..ef21983 100644 --- a/FAQ.d/FAQ.ISP.txt +++ b/FAQ.d/FAQ.ISP.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.ISP.txt,v 1.13 2021/12/06 20:02:39 gilles Exp gilles $ +$Id: FAQ.ISP.txt,v 1.14 2022/05/22 08:04:05 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -9,7 +9,8 @@ https://imapsync.lamiral.info/FAQ.d/FAQ.ISP.txt Imapsync tips for ISP. Specific issues and solutions. ======================================================================= -* IMAPSync - usage scenario with ISP - by Flavio Zarur Lucarelli (https://www.lucanet.com.br) +* IMAPSync - usage scenario with ISP - by Flavio Zarur Lucarelli + (https://www.lucanet.com.br) I thought I had to write a quick step by step on my attempts to learn the imapsync features that matter the most, so it works as we expected @@ -20,9 +21,10 @@ Lamiral for all his help and hard work. First of all, remember to use --dry to test things first always and check the log file to see what would actually happen. -This type of copy keeps destination exactly like source (except, it doesn't -copy duplicates), so use it ONLY before changing your MX to the new server, -as it will delete whatever is in destination which isn't in source. +This type of copy keeps destination exactly like source (except, it +doesn't copy duplicates), so use it ONLY before changing your MX to +the new server, as it will delete whatever is in destination which +isn't in source. imapsync --host1 imap.myisp.com --user1 user@domain.com --password1 pwd \ --host2 imap.myisp.com --user2 user@domain.com --password2 pwd \ @@ -119,8 +121,9 @@ If your last full sync was 2 days ago, then use --maxage 2 Goal is to get all the new emails (2 last days) from source. Another alternative for syncing after the MX change, which Lamiral -suggests, involves deleting emails from source from the last day. -I prefer the method explained above. Anyway, here is this other cenario... +suggests, involves deleting emails from source from the last day. I +prefer the method explained above. Anyway, here is this other +scenario... Something like this: @@ -186,17 +189,50 @@ Option --automap is also good to do most of the translate job. 3) Folders to exclude, to speed up syncs, etc. ---exclude "^Backups" --exclude "(?i)spam" --exclude "(?i)junk" --exclude "(?i)trash" --exclude "(?i)lixeira" --exclude "(?i)Deleted Items" + imapsync ... --exclude "^Backups" --exclude "(?i)spam" --exclude "(?i)junk" --exclude "(?i)trash" --exclude "(?i)lixeira" --exclude "(?i)Deleted Items" 4) Delete older than 1 year from an account. Use the account itself as source and destination and use: ---minage 365 --delete1 + imapsync ... --minage 365 --delete1 -5) Check size of folders in an account. Use Imapsync with same account as source and destination, with this parameter: +5) Check size of folders in an account. Use Imapsync with same account + as source and destination, with this parameter: + + imapsync ... --justfoldersizes + + +6) If you have problems copying messages that have labels which are + not supported, there are a few ways out. + +We use Dovecot and it doesn't support a series of labels, except the +standard ones. By default, imapsync won't copy messages that have +labels not supported by the recipient server. For that reason, I now +always use --filterbuggyflags and tell customers that not all labels +are copied. + +There are other alternatives, such as replacing problematic flags with +other names or copying just standard flags, detailing which ones to +copy, however, --filterbuggyflags was the easiest solution, which +worked fine for us. + +7) Definitely worth reading about dupes, here +https://imapsync.lamiral.info/FAQ.d/FAQ.Duplicates.txt, if you have +problems. Always try to check, even if by sampling, if dupes +occur. In a big migration, when you do several passes, try to check a +few accounts. + +The one issue we had with many duplicated emals in the destinatio, was +solved with the first solution in the above FAQ, using this syntax, +when copying from source to the destination, hence effectively +removing the dupes. + + imapsync ... --useheader "Message-Id" --delete2duplicates + +Note that --delete2duplicates is on when --delete2 is used, unless +--syncduplicates is used or --nodelete2duplicates is used. ---justfoldersizes ======================================================================= ======================================================================= diff --git a/FAQ.d/FAQ.Massive.txt b/FAQ.d/FAQ.Massive.txt index 095af1c..50d0d16 100644 --- a/FAQ.d/FAQ.Massive.txt +++ b/FAQ.d/FAQ.Massive.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Massive.txt,v 1.32 2021/11/01 11:30:48 gilles Exp gilles $ +$Id: FAQ.Massive.txt,v 1.34 2022/07/14 16:00:23 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -14,7 +14,7 @@ Questions answered here are: Q. How long will take the whole migration? -Q. I need to migrate hundred accounts, how can I do? +Q. I need to migrate hundreds of accounts, how can I do that? Q. I have to migrate 500k users using 400 TB of disk space. How do I proceed? How about speed? @@ -23,7 +23,7 @@ Q. How to determine where is the bottleneck in an imapsync process? Q. Can I run several instances of imapsync in parallel on a Windows host? -Q. I run multiple imapsync applications at the same time then get a +Q. I run multiple imapsync applications at the same time and then get a warning "imapsync.pid already exists, overwriting it". Is this a potential problem when trying to sync multiple IMAP account in parallel? @@ -31,17 +31,18 @@ Q. I run multiple imapsync applications at the same time then get a ======================================================================= Q. How long will take the whole migration? -R1. First you have to consider several periods. There is the global - period, from when the migration process is decided to the final end +R1. First, you have to consider several periods. There is the global + period, from when the migration process is decided to the end, where all mailboxes are migrated. This global period can be divided into three smaller periods. - The first period is the analyse period: you play with the tools + The first period is the analysis period: you play with the tools available, you estimate the volume to be transferred, the number of accounts, you measure how long it takes for one account under your context. - The second period is the presync period. The users are still using + The second period is what I call the presyncing period. + The users are still using the old accounts but nothing prevents you from starting to sync the old accounts, as they are, to the new accounts. With tons of gigabytes to transfer, this period may be the longest one. @@ -49,15 +50,15 @@ R1. First you have to consider several periods. There is the global until the round is finished. The last period is the final sync period where only the last - changes of the mailboxes need to be synced in order to switch + mailboxes' changes need to be synced before switching the users to their new mailboxes. -R2. To estimate the presync period, consider the mean imapsync transfer +R2. To estimate the presyncing period, consider the mean imapsync transfer rate to be around 340 Kbytes/s, ie, 2.8 Mbps, no matter the local link bandwidth. - It's a mean, measured upon various different syncs, coming from + It's a mean, measured upon various syncs, coming from the online service /X where the network card flow rate is 200 Mbps - (Rx 100 Mps, Tx 100 Mps) and the provider bandwidth is also 200 Mbps. + (Rx 100 Mbps, Tx 100 Mbps) and the provider bandwidth is also 200 Mbps. The maximum global rate seen is 22 MiB/s (176 Mbps). At 340 Kbytes/s, @@ -65,15 +66,15 @@ R2. To estimate the presync period, consider the mean imapsync transfer At 10 transfers at a time, 1 TB will take 3.5 days. At 100 transfers at a time, 1 TB will take 8 hours. Double the time because the best scenario never happens. - Triple the time because, well, real world is like that. + Triple the time because, well, the real world is like that. -R3. An other way to better evaluate the end of the presync period can +R3. Another way to better evaluate the end of the presyncing period can be based on your actual data. Just apply a simple rule of three on the mailboxes already migrated to estimate the global end. If it took X hours to finish Y% of the mailboxes, then it will take 100*X/Y hours to finish 100% of the mailboxes. - Following the same idea but using matematical garbage, + Following the same idea but using mathematical garbage, the ETA can be estimated like this: t_0 = time of global start (the start of the first presync) t_now = time of now. @@ -90,11 +91,11 @@ R4. To estimate the last period, the final sync, just rerun a complete the same amount of time. ======================================================================= -Q. I need to migrate hundred accounts, how can I do? +Q. I need to migrate hundreds of accounts, how can I do that? R. If you have many mailboxes to migrate, think about a little script program. Write a file called file.txt (for example) -containing hosts, users and passwords on both sides. +containing hosts, users, and passwords on both sides. The separator used in this example is ";" The file.txt file contains for example: @@ -105,8 +106,8 @@ host003_1;user003_1;password003_1;host003_2;user003_2;password003_2; host004_1;user004_1;password004_1;host004_2;user004_2;password004_2; etc. -Most of the times, the first column (host001_1, host002_1 ...) will -contains the same value, the value of --host1 parameter. Same +Most of the time, the first column (host001_1, host002_1 ...) will +contain the same value, the value of --host1 parameter. Same thing for the third column (host001_2, host002_2). On Unix the shell script can be: @@ -147,7 +148,7 @@ becomes host001_1;user001_1;password001_1;host001_2;user001_2;password001_2; --automap --addheader host002_1;user002_1;password002_1;host002_2;user002_2;password002_2; --automap --addheader -With this solution, options can be added, changed or removed per account. +With this solution, options can be added, changed, or removed per account. Technically those options will go in %%M in the loop body Here is a complete Windows example ready to use: @@ -169,11 +170,11 @@ Q. I have to migrate 500k users using 400 TB of disk space. R. A good solution to this issue is two words: parallelism and measurements. -Since all mailboxes are functionnaly independent, they can be processed +Since all mailboxes are functionally independent, they can be processed independently, here comes the parallelism, ie, lunching several imapsync processes in parallel. -Meanwhile, mailboxes usually belong to the same server and the syncs +Meanwhile, mailboxes usually belong to the same server, and the syncs share the same imapsync host via the same bandwidth, here come some limitations and bottlenecks. @@ -184,7 +185,7 @@ Here comes some measurements. Since adding this way is not so easy, just look at the overall network rate of the imapsync host. - On Linux and FreeBSD, nload is a good candidate to measure this overall + On Linux and FreeBSD, the command "nload" is a good candidate to measure this overall network rate. For example, to measure the rate every 6 seconds (-t 6000), on eth0 or em0 interface, with values in Kbytes (-u K), use: @@ -195,24 +196,26 @@ Here comes some measurements. dstat -n -N eth0 6 # Linux only (in 2018) - Another excellent tool to measure the network trafic is iftop. - The following command will monitor imap and imaps connexions - on interfce eth0, only them, and sum them up: + Another excellent tool to measure the network traffic is iftop. + The following command will monitor imap and imaps connections + on interface eth0, only them, and sum them up: iftop -i eth0 -f 'port imap or port imaps' -B # Linux iftop -i em0 -f 'port imap or port imaps' -B # FreeBSD During iftop, press the h to see the display commands available, every single feature is useful! Press h again and try each one. - My preferred display combination is by typing + My preferred display combination is by typing the keys t p > - meaning: one line per connection, show port numbers, sort by destination. + t means "one line per connection" + p means "show port numbers" + > means "sort by destination" On Windows 8.1 Windows 10 Windows 2012 R2 Windows 2016, get the overall network rate with the classical task manager (Ctrl-Shift-Esc), there is a Performance tab - in it where resides a Network grap monitor. + in it, where resides a Network monitor. On Windows 7, get the overall network rate with the classical task manager (Ctrl-Shift-Esc), there is a Network tab in it. @@ -224,7 +227,7 @@ Here comes some measurements. transfer rate increase. 3) When the total transfer rate starts to diminish, stop new launches. - Note N as the number of parallel runs you got until then. + Note N as the number of runs in parallel you got until then. 4) Only keep N-2 parallel runs for the future. @@ -234,15 +237,15 @@ Q. How to determine where is the bottleneck in an imapsync process? R1. Divide and conquer. -In order to detect whether host1/link1 is the bottleneck or +To detect whether host1/link1 is the bottleneck or host2/link2, we have several tests to explore: -1) run a sync from host1 to host1, with a host1 test account as destination. -This way, only host1+link1 are tested, host2 is not directly concerned. +1) run a sync from host1 to host1, with a host1 test account as the destination. +This way, only host1 and link1 are tested, host2 is not directly concerned. If performances increase a lot then host2/link2 is the bottleneck. -2) run a sync from host2 to host2, with a host2 test account as destination. -This way, only host2+link2 are tested, host1 is not concerned. +2) run a sync from host2 to host2, with a host2 test account as the destination. +This way, only host2 and link2 are tested, host1 is not concerned. If performances increase a lot then host1/link1 is the bottleneck. If performances increase on both tests 1) and 2), I have no clue to explain that. @@ -250,39 +253,39 @@ Same thing if they both decrease! R2. Isolating and overcoming bottlenecks -On any process involving several mechanisms, among all elements taking -part on the process, there is always a bottleneck. No one knows in +In any process involving several mechanisms, among all elements taking +part in the process, there is always a bottleneck. No one knows in advance what is the first bottleneck. The first bottleneck has to be determined, by measurements, not by guesses. Once this first bottleneck is known and overcome then the next bottleneck has to be determined and overcome too, if needed. Repeat the process of looking for the next bottleneck and its elimination until you estimate the transfer rates, money costs, time spent on this, and final dates -are good enough to proceed the whole huge migration. +are good enough to proceed with the whole huge migration. Possible bottlenecks: - Throttles. IMAP servers have artificial limits. - For example Gmail, Office365, Exchange have throttle limits. + For example, Gmail, Office365, and Exchange have throttle limits. - Bandwidth. - Usually available bandwidth is NOT a bottleneck. - Meanwhile, it can be a bottleneck on small Internet connexions. + Usually, the available bandwidth is not a bottleneck. + Meanwhile, it can be a bottleneck on small Internet connections. Imapsync downloads messages from host1 and upload messages to host2, - consider this in case the connexion are asymmetric. + consider this in case the connection is asymmetric. -- I/O on disks. - I/O are a classical bottleneck, almost always forgotten. +- I/O, aka "Input/Output" on the disks of the imap servers. + The I/O on disks are a classical bottleneck, almost always forgotten. Unlike CPU and RAM, Input/Output performances don't improve very much as time goes on so it's often a bottleneck. To measure and overcome an I/O disk bottleneck, you need - usually a direct access to host1 and host2. + usually direct access to host1 and host2. An I/O bottleneck where imapsync runs is possible if --usecache or --useuid is used or with very big messages. -- RAM memory. +- RAM. On all sides, monitor that your systems don't swap its running processes on disk, because swapping running processes on disks decreases performance by a factor of 20, at least. @@ -291,9 +294,8 @@ Possible bottlenecks: - CPU. 100% CPU during a whole transfer means the system is busy. - Usually CPU is not a problem with imapsync but it can be a problem - with one of the imap servers. - Most often CPU is not the real bottleneck, I/O are. + CPU can be a problem with imapsync but it can also be a problem + with one or both of the imap servers. Other possible bottlenecks: - Number of hosts available to run imapsync processes. @@ -312,10 +314,10 @@ Q. Can I run several instances of imapsync in parallel on a Windows host? R. Yes! -Q. Any performance issue? +Q. Any performance issues? You have to try and check the transfer rates, sum them up to -have a uniq numeric criteria. +have a unique numeric criterion. There is always a limit, depending on remote imap servers and the one running imapsync. CPU, memory, Inputs/Outputs are the classical bottlenecks, @@ -336,7 +338,7 @@ REM After that, just double-click on each batch file to launch each process ======================================================================= -Q. I run multiple imapsync applications at the same time then get a +Q. I run multiple imapsync applications at the same time and then get a warning "imapsync.pid already exists, overwriting it". Is this a potential problem when trying to sync multiple IMAP account in parallel? @@ -346,7 +348,7 @@ by yourself. This file can help you to manage multiple runs by sending signals to the processes (sigterm or sigkill) using their PID. -Each run can have its own pid file with --pidfile option. +Each run can have its pid file with --pidfile option. The file imapsync.pid contains the PID of the current imapsync process. This file is removed at the end of a normal run. You can safely ignore the warning if you don't use imapsync.pid file diff --git a/FAQ.d/FAQ.Office365.txt b/FAQ.d/FAQ.Office365.txt index fcd6d37..6e3b9ee 100644 --- a/FAQ.d/FAQ.Office365.txt +++ b/FAQ.d/FAQ.Office365.txt @@ -1,5 +1,5 @@ -$Id: FAQ.Office365.txt,v 1.37 2022/04/06 09:58:39 gilles Exp gilles $ +$Id: FAQ.Office365.txt,v 1.38 2022/06/22 17:07:35 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -36,6 +36,9 @@ Q. Office365 fails with "User is authenticated but not connected". Q. I see "NO Maximum size of appendable message has been exceeded" What can I do with that? +Q. Every single mail synced to exchange online owns the + category $MDNSent after migration. How can I avoid this? + Q. The imap connection to Office365 is not working very efficiently, is there a solution to fix that? @@ -334,6 +337,17 @@ values on the migration accounts in the source and target tenants. Thanks to Sean McDougall, Ian Thomas & Matt Wilks from Toronto for this FAQ item. +====================================================================== +Q. Every single mail synced to exchange online owns the + category $MDNSent after migration. How can I avoid this? + +R. To remove the flag $MDNSent from all messages, use: + + imapsync ... --regexflag "s/\$MDNSent//g" + +See also the document +https://imapsync.lamiral.info/FAQ.d/FAQ.Flags.txt + ====================================================================== Q. The imap connection to Office365 is not working very efficiently, is there a solution to fix that? diff --git a/FAQ.d/FAQ.OnlineUI.txt b/FAQ.d/FAQ.OnlineUI.txt index d643d4d..26ed41a 100644 --- a/FAQ.d/FAQ.OnlineUI.txt +++ b/FAQ.d/FAQ.OnlineUI.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.OnlineUI.txt,v 1.32 2022/03/23 11:00:27 gilles Exp gilles $ +$Id: FAQ.OnlineUI.txt,v 1.36 2022/09/14 11:18:05 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -35,23 +35,26 @@ Q. The sync stalls at the beginning, just after a line like: "Host1: xxx says it has CAPABILITY for AUTHENTICATE LOGIN" What is the problem? +Q. The synchronization fails with the error message like: + Err 1/1: Host1 failure: Error login on [10.1.161.155] with user [webmaster@truc.com] auth [LOGIN]: 2 NO [ALERT] LOGIN DENIED -- COUNTRY IS BLACKLISTED + Now the questions again with their answers. ===================================================================== Q. Can I launch several imap synchronizations on the visual user interface /X? -R. Yes. Open several tabs/windows on your browser and fill each one +A. Yes. Open several tabs/windows on your browser and fill each one with different credentials. ===================================================================== Q. How secure is the online visual user interface /X? -R0. Well, I don't know if asking the provider whether his online +A0. Well, I don't know if asking the provider whether his online service is secure or not would be of any interest. Let's do it anyway, you'll be the judge. -R1. Some figures +A1. Some figures Date of this report: 24 December 2021. Happy Christmas! @@ -64,7 +67,7 @@ On average, /X has 51 users per day, each user lunches on average The total volume /X transferred so far is around 240 TiB coming from nearly 520 000 imap account migrations and 810 million email messages. -R2. Pros & Cons +A2. Pros & Cons The online imapsync service /X runs on HTTPS only, with a letsencrypt certificate, an up to date certificate overall rated "A+" at @@ -148,7 +151,7 @@ Q. I want to switch from the visual interface /X to the https://imapsync.lamiral.info/#DOC_BASIC What should I know? -R. Let's do some ascii art. +A. Let's do some ascii art. The visual interface looks roughly like this, for the textfields input part: +------------------------------------------+------------------------------------------+ @@ -203,7 +206,7 @@ https://imapsync.lamiral.info/examples/imapsync_example.sh Q. Shall I have issues with the browser timing out? What happens if the browser connection is closed for whatever reason? -R. A browser connection closed closes also the imapsync process, +A. A browser connection closed closes also the imapsync process, ie, the sync is ended right away. Further comments on this behavior. @@ -240,7 +243,7 @@ the logfile running the sync like a "tail -f" command (isn't that magic?). Q. Shall I have issues when the webserver times out? What happens if the web server closes the connection for whatever reason? -R. If the webserver closes the connection then usually it also +A. If the webserver closes the connection then usually it also kills the imapsync process and the imap connections as well. The current webserver timeout at @@ -252,12 +255,46 @@ Q. The sync stalls at the beginning, just after a line like: "Host1: xxx says it has CAPABILITY for AUTHENTICATE LOGIN" What is the problem? -R. I've seen this issue on /X with the imap server +A. I've seen this issue on /X with the imap server CommuniGate Pro IMAP Server 6.0.11 The issue looks related to special characters in the password. Solution for now: change the password, keep only standard (ASCII) alphanumeric characters ABC-YZ abc-yz 012-89. +===================================================================== +Q. The synchronization fails with the error message like: + Err 1/1: Host1 failure: Error login on [10.1.161.155] with user [webmaster@truc.com] auth [LOGIN]: 2 NO [ALERT] LOGIN DENIED -- COUNTRY IS BLACKLISTED + +A. The message "[ALERT] LOGIN DENIED -- COUNTRY IS BLACKLISTED" comes directly + from the IMAP server at 10.1.161.155 + +It looks like that the 10.1.161.155 imap server filters incoming +connexions based on their IPS. In that case, here are the current +IPs of the imapsync online service (September 2022): + +ks5.lamiral.info has address 91.121.221.224 +ks5ipv6.lamiral.info has IPv6 address 2001:41d0:2:84e0::1 +ks6.lamiral.info has address 5.39.87.81 +ks6ipv6.lamiral.info has IPv6 address 2001:41d0:8:9951::1 +ks7.lamiral.info has address 5.135.177.225 +ks7ipv6.lamiral.info has IPv6 address 2001:41d0:8:b8e1::1 +i050.lamiral.info has address 213.32.72.139 +i050ipv6.lamiral.info has IPv6 address 2001:41d0:302:1000::155d +vp3.lamiral.info has address 51.178.81.27 +vp3ipv6.lamiral.info has IPv6 address 2001:41d0:404:200::4d81 +vp4.lamiral.info has address 51.38.34.201 +vp4ipv6.lamiral.info has IPv6 address 2001:41d0:305:2100::4c46 + +The imapsync online service may contact your imap server with one +or more of those IP addresses. + +CPhulk of Cpannel has a buildin country block that can cause this behavior. +Later on you may encountered issues with maximum sessions per ip. +You can change that within cPannel. + +https://support.cpanel.net/hc/en-us/articles/4406663082519-What-is-cPHulk- +https://docs.cpanel.net/whm/security-center/cphulk-brute-force-protection/ + ===================================================================== ===================================================================== diff --git a/FAQ.d/FAQ.Release_Checklist.txt b/FAQ.d/FAQ.Release_Checklist.txt index 4a55af5..211a143 100644 --- a/FAQ.d/FAQ.Release_Checklist.txt +++ b/FAQ.d/FAQ.Release_Checklist.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.Release_Checklist.txt,v 1.22 2022/01/14 12:46:38 gilles Exp gilles $ +$Id: FAQ.Release_Checklist.txt,v 1.27 2022/09/16 05:35:27 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -17,14 +17,28 @@ Checklist before release a new release: - Make "imapsync --tests" pass on Windows 32 bits - Make "imapsync --tests" pass on Windows 64 bits +make linuxtests +make win32tests +make win64tests +make mactests + +or + +make -j linuxtests win32tests win64tests mactests + - Make "imapsync --testslive" pass on Linux - Make "imapsync --testslive" pass on Mac -- Make "imapsync --testslive" pass on Windows 32 bits -- Make "imapsync --testslive" pass on Windows 64 bits + + +make linuxtestslive mactestslive mactestslive6 + - Add a new section in S/news.shtml reading "rlog imapsync" - In case of a new dependency, add it to all the INSTALL/* files. - Generate the README + +make doc + - Run a spell checker on the README - Read the README again slowly. Fix all issues, all. - Read the OPTIONS section of README and read it very slowly @@ -38,8 +52,8 @@ Checklist before release a new release: - Review the newsletter by running: m4 -P W/ml_announce.in.txt -- Update W/rsync_exclude_dist.txt -- Update .gitignore +- Update the file W/rsync_exclude_dist.txt +- Update the file .gitignore - Review the TODO file and mark done what is done. - Review the general FAQ.d/FAQ.General.txt diff --git a/FAQ.d/FAQ.Two_Ways_Sync.txt b/FAQ.d/FAQ.Two_Ways_Sync.txt index 2650088..bc83151 100644 --- a/FAQ.d/FAQ.Two_Ways_Sync.txt +++ b/FAQ.d/FAQ.Two_Ways_Sync.txt @@ -1,4 +1,4 @@ -$Id: FAQ.Two_Ways_Sync.txt,v 1.6 2022/02/22 15:16:16 gilles Exp gilles $ +$Id: FAQ.Two_Ways_Sync.txt,v 1.8 2022/07/25 14:03:49 gilles Exp gilles $ This documentation is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -21,14 +21,15 @@ stateless. Each time imapsync runs, it considers messages and folders as if it were the first time it encounters them. Imapsync looks at messages, flags, and folders as they are now, not considering what they were -before. Imapsync has no memory outside the current running sync. +before the current. Imapsync has no memory outside the current running +sync. So now, why a stateless behavior cannot handle well a two ways sync between an account A and an account B? The problem arises with deletions, messages deletions, folders -deletions, or movings, messages movings across folders, folders -movings, and also folders renamings. Deletions and moves are ambiguous +deletions, or with moves, messages moves across folders, folders +moves, and also folders renamings. Deletions and moves are ambiguous changes when combined with creations on the opposite side. For example, if a message is deleted from A by a user, then imapsync @@ -38,18 +39,64 @@ that has to be copied from B. But if you know the answer yourself, that missing messages on one side A are deleted messages that have to be deleted on the other side then -run a sync with the --delete2 option from A to B. +run a sync with the --delete2 option from A to B. This assumes there +is no new messages on B because --delete2 will delete them. -If you know that the missing messages on A are missing messages from B -that has to be copied to A then run a sync from B to A. +If you know that the missing messages on A are messages from B +that has to be copied to A, then run a sync from B to A. If you know it's a mixed scenario, that there are some deletions/moves on A, and there are some deletions/moves on B, but not the same, then you are in trouble and it ends up with a not very good "two ways" sync. In that case, two runs of imapsync, one from A to B, one from B -to A, put the two accounts in a synchronized state. But deletions on -either side get cancelled and folder renamings on either side bring -messages duplicates. +to A, put the two accounts in a synchronized state. The deletions of +messages on either side get cancelled, deleted messages come back. A +folder renaming on either side brings back the old folder. It's not a +good two ways synchronization. + + +My suggestion is: + +a) Use a single active imap account that fits all your needs, + available from anywhere, at any time. Access it from both your + laptop and your iphone. + +b) Feed this active account with foreign and passive accounts with any + tool that can handle the transfer, imapsync being one of them. + +c) Have a slave imap backup account of the active one, available also + from anywhere, at any time. Use it only as a failsafe account, when + the active one is broken or to bring back misguidely deleted + messages to the active account. Use any tool that can handle the + synchronization, imapsync being a good one of them. + + +======================================================================= +Q. What can I do instead of having two ways synchronizations? + +R. My suggestion is: + +a) Use only one single active imap account that fits all your needs, + available from anywhere, at any time. Access it from all your + devices, laptops, phones, tablets. + +b) Feed this active account with foreign and passive accounts with any + tool that can handle the transfer, imapsync being one of them. + +c) Have a slave imap backup account of the active one, available also + from anywhere, at any time. Use it only as a failsafe account, when + the active one is broken or to bring back misguidely deleted + messages to the active account. Use any tool that can handle the + synchronization, imapsync being a good one of them. + + +======================================================================= +Q. What tools can I use to handle two ways synchronizations? + +R. There are offlineimap and mbsync/isync tools: + +offlineimap is located at http://www.offlineimap.org/ +mbsync/isync is located at https://isync.sourceforge.io/ ======================================================================= diff --git a/FAQ.d/FAQ.User_Concurrent_Access.txt b/FAQ.d/FAQ.User_Concurrent_Access.txt index 18e504c..00f7ee0 100644 --- a/FAQ.d/FAQ.User_Concurrent_Access.txt +++ b/FAQ.d/FAQ.User_Concurrent_Access.txt @@ -1,5 +1,5 @@ #!/bin/cat -$Id: FAQ.User_Concurrent_Access.txt,v 1.5 2018/05/24 11:34:30 gilles Exp gilles $ +$Id: FAQ.User_Concurrent_Access.txt,v 1.6 2022/05/05 13:18:29 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -35,6 +35,23 @@ Details: so --delete2 is needed to sync the deletion. * message flag change => will need a resync +Let's more precise about timing. +Imapsync works per folder, one folder at a time. + +If imapsync has already synced a folder during a run, +what happens to this folder now won't be synced by the current run. + +If imapsync has not already synced a folder during a run, +what happens to this folder now will be synced by the current run. + +If imapsync is syncing a folder during a run, +what happens to this folder now depends on when things happen. +Imapsync starts by listing messages and getting meta data about them, +Message-Id, Date, Size. +A message deleted just after the listing, won't be synced. +A new message arriving just after the listing, won't be synced. + + * Writing at destination/host2: * adding folder => no problem, unless --delete2folders is used * deleting folder => will reappear by a new sync @@ -42,5 +59,7 @@ Details: * deleting message => might reappear by a new sync. * message flag change => will be reseted by a new sync. + + ======================================================================= ======================================================================= \ No newline at end of file diff --git a/FAQ.d/FAQ.Yahoo.txt b/FAQ.d/FAQ.Yahoo.txt index 24c3e1f..3d0ddf7 100644 --- a/FAQ.d/FAQ.Yahoo.txt +++ b/FAQ.d/FAQ.Yahoo.txt @@ -1,5 +1,5 @@ -$Id: FAQ.Yahoo.txt,v 1.13 2021/12/03 12:38:58 gilles Exp gilles $ +$Id: FAQ.Yahoo.txt,v 1.15 2022/05/05 14:17:22 gilles Exp gilles $ This document is also available online at https://imapsync.lamiral.info/FAQ.d/ @@ -64,7 +64,18 @@ Q. Synchronizing from XXX to Yahoo R. Example: +On Linux: ./imapsync \ + --host1 XXX \ + --user1 Billy@other.com \ + --password1 billysecreta \ + --host2 imap.mail.yahoo.com \ + --user2 Billy@yahoo.com \ + --password2 billysecretb \ + --regexmess 's{(? @@ -191,7 +196,7 @@ stuff with the following commands: a2enmod cgi a2enconf serve-cgi-bin - /etc/init.d/apache2 reload + /etc/init.d/apache2 restart If the cgi mode and the cgi-bin configuration are not activated then you may encounter a 404 error when, later, you will run the command @@ -216,6 +221,9 @@ it will work under Apache with this command: su -s /bin/sh -c 'SERVER_SOFTWARE=foo /usr/lib/cgi-bin/imapsync' www-data +You should end with something like: +Exiting with return value 0 (EX_OK: successful termination) + Test that imapsync is considered a cgi with: wget -nv -S -O- http://localhost/cgi-bin/imapsync?testslive=1 @@ -223,8 +231,9 @@ Test that imapsync is considered a cgi with: The last command should print something like: Status: 200 OK to sync IMAP boxes. Load on bar is ... ... +Exiting with return value 0 (EX_OK: successful termination) -If you get a 404 here then review the cgi installation and +If you get a 404 or a 5xx here then review the cgi installation and configuration part. @@ -264,6 +273,12 @@ Check or the safer https://yourhost/X/imapsync_form_extra.html +Let's encrypt your site because crendentials should never travel in +clear form. Go to https://certbot.eff.org/instructions + +See the Troubleshooting section to fix the systemd Apache +PrivateTmp=true issue. + That's all for installing a /X service on a Debian family system. ============================================================================= @@ -352,15 +367,19 @@ while maintaining SELinux in enforcing mode. Quick solution: - sestatus - setenforce 0 - sestatus + getsebool httpd_can_network_connect # should show --> off + setsebool -P httpd_can_network_connect=1 + getsebool httpd_can_network_connect # should show --> on + wget -nv -S -O- http://localhost/cgi-bin/imapsync?testslive=1 # no more "Permission denied" + +The -P option installs the rule permanently, even after a reboot To go back to the previous state: - setenforce 1 - sestatus - + getsebool httpd_can_network_connect # should show --> on + setsebool -P httpd_can_network_connect=0 + getsebool httpd_can_network_connect # should show --> off + Nota bene ========= @@ -387,16 +406,18 @@ https://humdi.net/vnstat/ Vnstat is already available as a package in most Linux distros. The images are generated by the following commands, every minute: -vnstati -s -o /var/www/vnstat/vnstat_s.png -vnstati -h -o /var/www/vnstat/vnstat_h.png -vnstati -hg -o /var/www/vnstat/vnstat_hg.png -vnstati -hs -o /var/www/vnstat/vnstat_hs.png -vnstati -d -o /var/www/vnstat/vnstat_d.png -vnstati -m -o /var/www/vnstat/vnstat_m.png -vnstati -y -o /var/www/vnstat/vnstat_y.png -vnstati -t -o /var/www/vnstat/vnstat_t.png -vnstati -vs -o /var/www/vnstat/vnstat_vs.png -vnstati -5 -o /var/www/vnstat/vnstat_5.png +vnstati -s -o /var/www/html/vnstat/vnstat_s.png +vnstati -h -o /var/www/html/vnstat/vnstat_h.png +vnstati -hg -o /var/www/html/vnstat/vnstat_hg.png +vnstati -hs -o /var/www/html/vnstat/vnstat_hs.png +vnstati -d -o /var/www/html/vnstat/vnstat_d.png +vnstati -m -o /var/www/html/vnstat/vnstat_m.png +vnstati -y -o /var/www/html/vnstat/vnstat_y.png +vnstati -t -o /var/www/html/vnstat/vnstat_t.png +vnstati -vs -o /var/www/html/vnstat/vnstat_vs.png +vnstati -5 -o /var/www/html/vnstat/vnstat_5.png + + ======================================================================= @@ -441,14 +462,22 @@ be canceled the next time the apache package is updated. Debian: systemctl edit apache2 + cat /etc/systemd/system/apache2.service.d/override.conf +[Service] +PrivateTmp=false + systemctl daemon-reload systemctl restart apache2 systemctl status apache2 Centos: systemctl edit httpd + cat /etc/systemd/system/httpd.service.d/override.conf +[Service] +PrivateTmp=false + systemctl daemon-reload systemctl restart httpd systemctl status httpd diff --git a/INSTALL.d/INSTALL.Ubuntu.txt b/INSTALL.d/INSTALL.Ubuntu.txt index a9df12d..1c1ca43 100644 --- a/INSTALL.d/INSTALL.Ubuntu.txt +++ b/INSTALL.d/INSTALL.Ubuntu.txt @@ -1,5 +1,5 @@ #!/bin/cat -# $Id: INSTALL.Ubuntu.txt,v 1.18 2021/07/30 15:06:43 gilles Exp gilles $ +# $Id: INSTALL.Ubuntu.txt,v 1.21 2022/06/03 16:58:47 gilles Exp gilles $ This documentation is also located online at https://imapsync.lamiral.info/INSTALL.d/ @@ -17,6 +17,7 @@ This command installs standard Ubuntu packages: sudo apt-get install \ libauthen-ntlm-perl \ libclass-load-perl \ +libcrypt-openssl-rsa-perl \ libcrypt-ssleay-perl \ libdata-uniqid-perl \ libdigest-hmac-perl \ @@ -28,11 +29,13 @@ libio-compress-perl \ libio-socket-inet6-perl \ libio-socket-ssl-perl \ libio-tee-perl \ +libjson-webtoken-perl \ libmail-imapclient-perl \ libmodule-scandeps-perl \ libnet-dbus-perl \ libnet-ssleay-perl \ libpar-packer-perl \ +libproc-processtable-perl \ libreadonly-perl \ libregexp-common-perl \ libsys-meminfo-perl \ @@ -58,11 +61,6 @@ the following command installs it "manually": sudo cpanm Mail::IMAPClient -In case you need to use XOAUTH2 authentication you have to install -the module JSON::WebToken with the command: - - sudo cpanm JSON::WebToken - After installing the dependencies, imapsync should be working. You don't have to be root to test and use imapsync. diff --git a/INSTALL.d/INSTALL.webserver.txt b/INSTALL.d/INSTALL.webserver.txt new file mode 100644 index 0000000..f02d4db --- /dev/null +++ b/INSTALL.d/INSTALL.webserver.txt @@ -0,0 +1,18 @@ +#!/bin/cat +# $Id: INSTALL.webserver.txt,v 1.6 2022/06/15 12:09:39 gilles Exp gilles $ + +This documentation is also located online at +https://imapsync.lamiral.info/INSTALL.d/ +https://imapsync.lamiral.info/INSTALL.d/INSTALL.webserver.txt + + +The script named webserver in the top directory is a small web server +dedicated to offer the visual interface. It is experimental and it is +for now a plain text HTTP server (ie, not https). + + +Dependencies to run webserver on Debian/Ubuntu distributions: + + sudo apt install libnet-server-perl + + diff --git a/INSTALL.d/prerequisites_imapsync b/INSTALL.d/prerequisites_imapsync index bbac1f4..34be2dd 100755 --- a/INSTALL.d/prerequisites_imapsync +++ b/INSTALL.d/prerequisites_imapsync @@ -1,6 +1,6 @@ #!/bin/sh -# $Id: prerequisites_imapsync,v 1.35 2019/11/27 15:58:46 gilles Exp gilles $ +# $Id: prerequisites_imapsync,v 1.36 2022/05/17 13:46:16 gilles Exp gilles $ MODULES_MANDATORY=' App::cpanminus @@ -39,6 +39,7 @@ Package::Stash::XS PAR::Packer Parse::RecDescent Pod::Usage +Proc::ProcessTable Readonly Regexp::Common Sys::MemInfo diff --git a/Makefile b/Makefile index d1e9edf..36a3919 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -# $Id: Makefile,v 1.345 2022/04/06 10:00:39 gilles Exp gilles $ +# $Id: Makefile,v 1.349 2022/09/15 08:43:25 gilles Exp gilles $ .PHONY: help usage all doc @@ -109,8 +109,6 @@ VERSION: imapsync touch -r ./imapsync ./VERSION - - doc/GOOD_PRACTICES.html: doc/GOOD_PRACTICES.t2t txt2tags -i doc/GOOD_PRACTICES.t2t -t html --toc -o doc/GOOD_PRACTICES.html ./W/tools/validate_html4 doc/GOOD_PRACTICES.html @@ -172,18 +170,32 @@ install: testp W/imapsync.1 install W/imapsync.1 $(DESTDIR)$(PREFIX)/share/man/man1/imapsync.1 chmod 644 $(DESTDIR)$(PREFIX)/share/man/man1/imapsync.1 - - - ############### # Local goals ############### -.PHONY: prereq test tests unitests testp testf test3xx perlcritic allcritic crit compok dev cover tidy nytprof functree +.PHONY: dailybuild dailytests prereq test tests unitests testp testf test3xx perlcritic allcritic crit compok dev cover tidy nytprof functree dev: test functree crit cover nytprof bin +dailytests: linuxtests win32tests win64tests mactests + +dailybuild: linuxbuild win32build win64build macbuild + +linuxtests: + ./imapsync --tests + +linuxtestsdebug: + ./imapsync --testsdebug + +testsdebug: linuxtestsdebug win64testsdebug win32testsdebug mactestsdebug + +testslive: mactestslive + + + + docker: @echo "make docker_copy_to_vp3 # copy imapsync Dockerfile memo_docker to vp3" @echo "make docker_build # build the imapsync docker image" @@ -258,7 +270,7 @@ perlcritic: W/perlcritic_3.txt W/perlcritic_2.txt allcritic: W/perlcritic_4.txt W/perlcritic_3.txt W/perlcritic_2.txt W/perlcritic_1.txt W/perlcritic_1.txt: imapsync W/.compok - perlcritic --statistics-only -1 imapsync > W/perlcritic_1.txt.tmp || : + perlcritic --statistics -1 imapsync > W/perlcritic_1.txt.tmp || : mv W/perlcritic_1.txt.tmp W/perlcritic_1.txt echo | ci -l W/perlcritic_1.txt @@ -331,6 +343,7 @@ win32testsdebug: ./W/check_winerr test_testsdebug.bat + .PHONY: W/*.bat examples/* @@ -451,35 +464,48 @@ imapsync_32bit.exe: imapsync chmod a+r+x imapsync_32bit.exe (date "+%s"| tr "\n" " "; echo -n "END 32bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME +win64tests: win64tests_p26 - -win64tests: +win64tests_p24: unix2dos W/test_tests.bat scp imapsync W/test_tests.bat pc_HP_DV7_p24:'Desktop/imapsync_build' ssh 'pc HP DV7'@p24 'Desktop/imapsync_build/test_tests.bat' ./W/check_win64err test_tests.bat -win64testsdebug: +win64testsdebug_p24: unix2dos W/test_testsdebug.bat scp imapsync W/test_testsdebug.bat pc_HP_DV7_p24:'Desktop/imapsync_build' ssh 'pc HP DV7'@p24 'Desktop/imapsync_build/test_testsdebug.bat' ./W/check_win64err test_testsdebug.bat - +win64testsdebug: win64testsdebug_p26 win64testsdebug_p26: unix2dos W/test_testsdebug.bat - scp imapsync W/test_testsdebug.bat gille@p26:'Desktop\imapsync_build' - ssh gille@p26 'Desktop\imapsync_build\test_testsdebug.bat' + scp imapsync W/test_testsdebug.bat gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\test_testsdebug.bat' ./W/check_p26err test_testsdebug.bat + win64tests_p26: unix2dos W/test_tests.bat - scp imapsync W/test_tests.bat gille@p26:'Desktop\imapsync_build' - ssh gille@p26 'Desktop\imapsync_build\test_tests.bat' + scp imapsync W/test_tests.bat gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\test_tests.bat' ./W/check_p26err test_tests.bat +win64_test_exe_always_fail_p26: + unix2dos W/test_exe_always_fail.bat + scp W/test_exe_always_fail.bat gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\test_exe_always_fail.bat' + ./W/check_p26err test_exe_always_fail.bat + +win64_test_always_fail_p26: + unix2dos W/test_exe_always_fail.bat + scp imapsync W/test_always_fail.bat gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\test_always_fail.bat' + ./W/check_p26err test_always_fail.bat + zzz: unix2dos W/build_exe.bat W/install_module_one.bat scp imapsync W/build_exe.bat W/install_module_one.bat W/test_exe_testsdebug.bat pc_HP_DV7_p24:'Desktop/imapsync_build' @@ -543,19 +569,46 @@ win64prepa: winprepalocal ssh 'pc HP DV7'@p24 'Desktop/imapsync_build/build_exe.bat' ./W/check_win64err build_exe.bat -win64build: winprepalocal +win64build_p24: winprepalocal scp imapsync W/build_exe.bat W/install_modules.bat pc_HP_DV7_p24:'Desktop/imapsync_build' ssh 'pc HP DV7'@p24 'Desktop/imapsync_build/build_exe.bat' ./W/check_win64err build_exe.bat imapsync.exe: imapsync_64bit.exe_p26 - cp -a imapsync_64bit.exe imapsync.exe + cp -a imapsync_64bit.exe_p26 imapsync.exe + +win64build: imapsync_64bit.exe_p26 +win64build_p26: winprepalocal + scp imapsync W/build_exe.bat W/install_modules.bat gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\build_exe.bat' + ./W/check_win64err build_exe.bat + .PHONY: imapsync_64bit.exe_p24 imapsync_64bit.exe_p26 +64exe: imapsync_64bit.exe_p26 + +imapsync_64bit.exe_p26: imapsync + (date "+%s"| tr "\n" " "; echo -n "BEGIN 64bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME + unix2dos W/build_exe.bat W/test_exe.bat W/install_modules.bat W/install_module_one.bat + ssh gille@p26 'perl -V' + ssh gille@p26 'if not exist OneDrive\Bureau\imapsync_build mkdir OneDrive\Bureau\imapsync_build' + scp imapsync W/build_exe.bat W/install_modules.bat W/install_module_one.bat \ + W/test_exe_tests.bat W/test_exe_testsdebug.bat W/test_exe.bat \ + gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\build_exe.bat' + ./W/check_p26err build_exe.bat + scp ../../var/pass/secret.tata ../../var/pass/secret.titi gille@p26:'OneDrive\Bureau\imapsync_build' + ssh gille@p26 'OneDrive\Bureau\imapsync_build\test_exe.bat' + ./W/check_p26err test_exe.bat + rm -f imapsync_64bit.exe + scp -T gille@p26:'OneDrive\Bureau\imapsync_build\imapsync_64bit.exe' . + chmod a+r+x imapsync_64bit.exe + (date "+%s"| tr "\n" " "; echo -n "END 64bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME + imapsync_64bit.exe_p24: imapsync (date "+%s"| tr "\n" " "; echo -n "BEGIN 64bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME @@ -573,26 +626,8 @@ imapsync_64bit.exe_p24: imapsync chmod a+r+x imapsync_64bit.exe (date "+%s"| tr "\n" " "; echo -n "END 64bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME -imapsync_64bit.exe: imapsync - (date "+%s"| tr "\n" " "; echo -n "BEGIN 64bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME - unix2dos W/build_exe.bat W/test_exe.bat W/install_modules.bat W/install_module_one.bat - ssh gille@p26 'perl -V' - ssh gille@p26 'if not exist Desktop\imapsync_build mkdir Desktop\imapsync_build' - scp imapsync W/build_exe.bat W/install_modules.bat W/install_module_one.bat \ - W/test_exe_tests.bat W/test_exe_testsdebug.bat W/test_exe.bat \ - gille@p26:'Desktop\imapsync_build' - ssh gille@p26 'Desktop\imapsync_build\build_exe.bat' - ./W/check_p26err build_exe.bat - scp ../../var/pass/secret.tata ../../var/pass/secret.titi gille@p26:'Desktop\imapsync_build' - ssh gille@p26 'Desktop\imapsync_build\test_exe.bat' - ./W/check_p26err test_exe.bat - rm -f imapsync_64bit.exe - scp -T gille@p26:'Desktop\imapsync_build\imapsync_64bit.exe' . - chmod a+r+x imapsync_64bit.exe - (date "+%s"| tr "\n" " "; echo -n "END 64bit " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME - -zip: dosify_bat +zip: dosify_bat cidone rm -rfv ../prepa_zip/imapsync_$(VERSION)/ mkdir -p ../prepa_zip/imapsync_$(VERSION)/FAQ.d/ ../prepa_zip/imapsync_$(VERSION)/Cook/ cp -av examples/imapsync_example.bat examples/sync_loop_windows.bat examples/file.txt ../prepa_zip/imapsync_$(VERSION)/ @@ -614,9 +649,9 @@ zip: dosify_bat mac: imapsync_bin_Darwin macstadiumcopy: - rsync -v imapsync W/build_mac.sh INSTALL.d/prerequisites_imapsync webserver administrator@macstadium.lamiral.info: - rsync -v examples/file.txt examples/sync_loop_darwin.sh administrator@macstadium.lamiral.info:examples/ - rsync -v X/ administrator@macstadium.lamiral.info:X/ + rsync -pv imapsync W/build_mac.sh INSTALL.d/prerequisites_imapsync webserver administrator@macstadium.lamiral.info: + rsync -pv examples/file.txt examples/sync_loop_darwin.sh administrator@macstadium.lamiral.info:examples/ + rsync -pv X/ administrator@macstadium.lamiral.info:X/ maccopy: rsync -v -p -e 'ssh -4 -p 995' imapsync W/build_mac.sh INSTALL.d/prerequisites_imapsync webserver \ @@ -648,6 +683,16 @@ mactestslive6: rsync -p -e 'ssh -4 -p 995' imapsync gilleslamira@gate.polarhome.com: ssh -4 -p 995 gilleslamira@gate.polarhome.com '. .bash_profile; perl imapsync --testslive6' +macstests: + rsync -pv imapsync administrator@macstadium.lamiral.info: + ssh administrator@macstadium.lamiral.info '. .bash_profile; perl imapsync --tests' + +macstestsdebug: + rsync -pv imapsync administrator@macstadium.lamiral.info: + ssh administrator@macstadium.lamiral.info '. .bash_profile; perl imapsync --testsdebug' + + + .PHONY: bin win lin win32 win64 bin: mac win @@ -660,6 +705,10 @@ win32: imapsync_32bit.exe win64: imapsync_64bit.exe +win32build: imapsync_32bit.exe + +linuxbuild: lin + $(BIN_NAME): imapsync rcsdiff imapsync @@ -893,15 +942,19 @@ upload_latest: unitests ci_imapsync bin -.PHONY: upload_cgi upload_cgi_ks5 upload_cgi_memo upload_cgi_vp3 upload_cgi_vp4 upload_cgi_ks6 +.PHONY: upload_cgi upload_cgi_ks5 upload_cgi_memo upload_cgi_vp3 upload_cgi_vp4 upload_cgi_ks6 upload_tmphash_all -upload_cgi: upload_cgi_ks5 upload_cgi_vp3 upload_cgi_vp4 upload_cgi_ks6 -upload_cgi_ks5: ci_imapsync unitests ks5tests - rsync -P imapsync root@ks5.lamiral.info:/home/www/apache24/cgi-bin/imapsync_new - curl -v --data 'testslive=1' https://imapsync.lamiral.info/cgi-bin/imapsync_new | grep 'Exiting with return value 0' - rsync -P imapsync root@ks5.lamiral.info:/home/www/apache24/cgi-bin/imapsync - curl -v --data 'testslive=1' https://imapsync.lamiral.info/cgi-bin/imapsync | grep 'Exiting with return value 0' +upload_proximapsync: + rcsdiff W/learn/proximapsync + W/learn/proximapsync --tests + W/learn/proximapsync --testslive | grep 'Exiting with return value 0' + rsync -P W/learn/proximapsync root@ks5.lamiral.info:/home/www/apache24/cgi-bin/proximapsync_new + ssh root@ks5.lamiral.info '/home/www/apache24/cgi-bin/proximapsync_new --tests' + ssh root@ks5.lamiral.info '/home/www/apache24/cgi-bin/proximapsync_new --testslive' | grep 'Exiting with return value 0' + curl -v --data 'testslive=1' https://imapsync.lamiral.info/cgi-bin/proximapsync_new 2>/dev/null | grep 'Exiting with return value 0' + rsync -P W/learn/proximapsync root@ks5.lamiral.info:/home/www/apache24/cgi-bin/proximapsync + curl -v --data 'testslive=1' https://imapsync.lamiral.info/cgi-bin/proximapsync 2>/dev/null | grep 'Exiting with return value 0' upload_cgi_memo: dos2unix X/stat_patterns.txt X/server_survey_patterns.txt @@ -909,31 +962,73 @@ upload_cgi_memo: rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@ks5:/var/tmp/imapsync_cgi/ upload_cgi_memo_all: - rsync -av X/cgi_memo root@ks5:/var/tmp/imapsync_cgi/ - rsync -av X/cgi_memo root@ks6:/var/tmp/imapsync_cgi/ - rsync -av X/cgi_memo root@vp3:/var/tmp/imapsync_cgi/ - rsync -av X/cgi_memo root@vp4:/var/tmp/imapsync_cgi/ + rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@ks5:/var/tmp/imapsync_cgi/ + rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@ks6:/var/tmp/imapsync_cgi/ + rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@ks7:/var/tmp/imapsync_cgi/ + rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@vp3:/var/tmp/imapsync_cgi/ + rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@vp4:/var/tmp/imapsync_cgi/ + ! ping -c1 -W1 cl1 || rsync -av X/cgi_memo X/stat_patterns.txt X/server_survey_patterns.txt root@cl1:/var/tmp/imapsync_cgi/ + +upload_tmphash_all: + scp /var/tmp/imapsync_hash root@ks5:/var/tmp/imapsync_hash && ssh root@ks5 chgrp www /var/tmp/imapsync_hash + scp /var/tmp/imapsync_hash root@ks6:/var/tmp/imapsync_hash && ssh root@ks6 chgrp www-data /var/tmp/imapsync_hash + scp /var/tmp/imapsync_hash root@vp3:/var/tmp/imapsync_hash && ssh root@vp3 chgrp www-data /var/tmp/imapsync_hash + scp /var/tmp/imapsync_hash root@vp4:/var/tmp/imapsync_hash && ssh root@vp4 chgrp apache /var/tmp/imapsync_hash + scp /var/tmp/imapsync_hash root@i050:/var/tmp/imapsync_hash && ssh root@i050 chgrp www-data /var/tmp/imapsync_hash + +test_cgi_all: + curl -v --data 'testslive=1;exitonload=0' https://imapsync.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' # ks5 + curl -v --data 'testslive=1;exitonload=0' https://i006.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://i007.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://i013.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://i014.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + +upload_cgi: upload_cgi_ks5 upload_cgi_vp3 upload_cgi_vp4 upload_cgi_ks6 upload_cgi_ks7 + +# FreeBSD +upload_cgi_ks5: ci_imapsync unitests ks5tests + rsync -P imapsync root@ks5.lamiral.info:/home/www/apache24/cgi-bin/imapsync_new + curl -v --data 'testslive=1;exitonload=0' https://imapsync.lamiral.info/cgi-bin/imapsync_new 2>/dev/null | grep 'Exiting with return value 0' + rsync -P imapsync root@ks5.lamiral.info:/home/www/apache24/cgi-bin/imapsync + curl -v --data 'testslive=1;exitonload=0' https://imapsync.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + # Debian upload_cgi_vp3: ci_imapsync vp3tests rsync -P imapsync root@vp3.lamiral.info:/usr/lib/cgi-bin/imapsync_new - curl -v --data 'testslive=1' https://vp3.lamiral.info/cgi-bin/imapsync_new | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://vp3.lamiral.info/cgi-bin/imapsync_new 2>/dev/null | grep 'Exiting with return value 0' rsync -P imapsync root@vp3.lamiral.info:/usr/lib/cgi-bin/imapsync - curl -v --data 'testslive=1' https://vp3.lamiral.info/cgi-bin/imapsync | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://vp3.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' # Centos upload_cgi_vp4: ci_imapsync vp4tests rsync -P imapsync root@vp4.lamiral.info:/var/www/cgi-bin/imapsync_new - curl -v --data 'testslive=1' https://vp4.lamiral.info/cgi-bin/imapsync_new | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://vp4.lamiral.info/cgi-bin/imapsync_new 2>/dev/null | grep 'Exiting with return value 0' rsync -P imapsync root@vp4.lamiral.info:/var/www/cgi-bin/imapsync - curl -v --data 'testslive=1' https://vp4.lamiral.info/cgi-bin/imapsync | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://vp4.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' # Debian upload_cgi_ks6: ci_imapsync ks6tests rsync -P imapsync root@ks6.lamiral.info:/usr/lib/cgi-bin/imapsync_new - curl -v --data 'testslive=1' https://ks6.lamiral.info/cgi-bin/imapsync_new | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://ks6.lamiral.info/cgi-bin/imapsync_new 2>/dev/null | grep 'Exiting with return value 0' rsync -P imapsync root@ks6.lamiral.info:/usr/lib/cgi-bin/imapsync - curl -v --data 'testslive=1' https://ks6.lamiral.info/cgi-bin/imapsync | grep 'Exiting with return value 0' + curl -v --data 'testslive=1;exitonload=0' https://ks6.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + +# Promox/Debian +upload_cgi_ks7: ci_imapsync ks7tests + rsync -P imapsync root@ks7.lamiral.info:/usr/lib/cgi-bin/imapsync_new + curl -v --data 'testslive=1;exitonload=0' https://ks7.lamiral.info/cgi-bin/imapsync_new 2>/dev/null | grep 'Exiting with return value 0' + rsync -P imapsync root@ks7.lamiral.info:/usr/lib/cgi-bin/imapsync + curl -v --data 'testslive=1;exitonload=0' https://ks7.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + +# Debian +upload_cgi_cl1: ci_imapsync cl1tests + rsync -P imapsync root@cl1.lamiral.info:/usr/lib/cgi-bin/imapsync_new + curl -v --data 'testslive=1;exitonload=0' https://cl1.lamiral.info/cgi-bin/imapsync_new 2>/dev/null | grep 'Exiting with return value 0' + rsync -P imapsync root@cl1.lamiral.info:/usr/lib/cgi-bin/imapsync + curl -v --data 'testslive=1;exitonload=0' https://cl1.lamiral.info/cgi-bin/imapsync 2>/dev/null | grep 'Exiting with return value 0' + + .PHONY: vp3tests vp4tests ks6tests @@ -952,10 +1047,29 @@ ks6tests: ssh root@ks6.lamiral.info ./imapsync --tests ssh root@ks6.lamiral.info ./imapsync --testslive6 +ks7tests: + rsync -P imapsync root@ks7.lamiral.info:imapsync + ssh root@ks7.lamiral.info ./imapsync --tests + ssh root@ks7.lamiral.info ./imapsync --testslive6 + +cl1tests: + rsync -P imapsync root@cl1.lamiral.info:imapsync + ssh root@cl1.lamiral.info ./imapsync --tests + ssh root@cl1.lamiral.info ./imapsync --testslive6 + + +upload_imapsync_all: + scp imapsync INSTALL.d/prerequisites_imapsync W/learn/processtable root@i005.lamiral.info: + scp imapsync INSTALL.d/prerequisites_imapsync W/learn/processtable root@i006.lamiral.info: + scp imapsync INSTALL.d/prerequisites_imapsync W/learn/processtable root@i013.lamiral.info: + scp imapsync INSTALL.d/prerequisites_imapsync W/learn/processtable root@i014.lamiral.info: + + upload_X: - ./W/tools/validate_xml_html5 X/index.html X/imapsync_form.html X/imapsync_form_extra.html X/imapsync_form_extra_free.html X/imapsync_form_wrapper.html - rcsdiff X/imapsync_form.html X/imapsync_form_extra.html X/imapsync_form_extra_free.html X/imapsync_form_wrapper.html X/imapsync_form.css X/noscript.css - rcsdiff X/imapsync_form.js X/imapsync_form_wrapper.js + ./W/tools/validate_xml_html5 X/imapsync_form.html X/imapsync_form_extra.html X/imapsync_form_extra_free.html X/imapsync_form_wrapper.html X/proximapsync_form_extra_free.html + rcsdiff X/imapsync_form.html X/imapsync_form_extra.html X/imapsync_form_extra_free.html X/imapsync_form_wrapper.html X/proximapsync_form_extra_free.html + rcsdiff X/imapsync_form.css X/noscript.css + rcsdiff X/imapsync_form.js X/imapsync_form_wrapper.js X/proximapsync_form.js rcsdiff INSTALL.d/INSTALL.OnlineUI.txt rsync -a ./INSTALL.d/INSTALL.OnlineUI.txt ../imapsync_website/INSTALL.d/INSTALL.OnlineUI.txt rsync -av --delete X/ ../imapsync_website/X/ @@ -977,6 +1091,10 @@ upload_FAQ: rsync -avH --delete ./doc/ ../imapsync_website/doc/ rsync -aHvz --delete ../imapsync_website/ root@ks5.lamiral.info:/usr/local/www/apache24/data/imapsync/ +upload_oauth2: + rm -f oauth2/D_oauth2_* + rsync -aHv --delete ./oauth2/ ../imapsync_website/oauth2/ + rsync -aHvz --delete ../imapsync_website/ root@ks5.lamiral.info:/usr/local/www/apache24/data/imapsync/ upload_ks_W_memo: rsync -av W/memo gilles@ks.lamiral.info:public_html/imapsync/W/memo diff --git a/README b/README index e463c5c..93e716b 100644 --- a/README +++ b/README @@ -6,7 +6,7 @@ NAME VERSION - This documentation refers to Imapsync $Revision: 2.200 $ + This documentation refers to Imapsync $Revision: 2.229 $ USAGE @@ -225,7 +225,7 @@ OPTIONS It will be combined with the --user1 value to form the string to pass with XOAUTH2 authentication. The password given by --password1 or --passfile1 - is ignored. + is ignored but needed on the command line. Instead of the access token itself, the value can be a file containing the access token on the first line. If the value is a file, imapsync reads its first line @@ -239,7 +239,8 @@ OPTIONS --oauthdirect1 str : The direct string to pass with XOAUTH2 authentication. The password given by --password1 or --passfile1 and - the user given by --user1 are ignored. + the user given by --user1 are ignored but they are + needed to be on the command line. Consider it a bug. --oauthdirect2 str : same thing as oauthdirect1 @@ -368,7 +369,7 @@ OPTIONS 2019_12_22_23_57_59_532 is nearly the date of the start YYYY_MM_DD_HH_MM_SS_mmm - year_month_day_hour_minute_seconde_millisecond + year_month_day_hour_minute_second_millisecond and user1 user2 are the --user1 --user2 values. @@ -617,7 +618,7 @@ OPTIONS Default is 120 and 0 means no timeout at all. Caveat, under CGI context, you may encounter a timeout - from the webserver, killing imapsync and the imap connexions. + from the webserver, killing imapsync and the imap connections. See the document INSTALL.OnlineUI.txt and search for "Timeout" for how to deal with this issue. @@ -653,6 +654,12 @@ OPTIONS it's an http request to http://imapsync.lamiral.info/prj/imapsync/VERSION + --emailreport1 : Put the email final report in host1 INBOX + --emailreport2 : Put the email final report in host2 INBOX + + --noemailreport1 : Do not put the email final report in host1 INBOX + --noemailreport2 : Do not put the email final report in host2 INBOX + --noid : Do not send/receive IMAP "ID" command to imap servers. --justconnect : Just connect to both servers and print useful diff --git a/S/imapservers.shtml b/S/imapservers.shtml index 2040ad4..6cf4bd6 100644 --- a/S/imapservers.shtml +++ b/S/imapservers.shtml @@ -4,7 +4,7 @@ -Imapsync list of the 86 imap server software applications supported +Imapsync list of the 88 imap server software applications supported @@ -27,12 +27,13 @@ -

Imapsync list of the 86 imap server software applications supported (and the broken ones) +

Imapsync list of the 88 imap server software applications supported (and the broken ones) (back to menu)

To know whether your IMAP server is a widespread choice, -take a look at http://openemailsurvey.org/
+take a look at http://openemailsurvey.org/ or +the Shodan imap query result.
The short answer is that if you're not using the famous Dovecot then you're in a niche!

@@ -128,6 +129,9 @@ imapsync --host1 imap.gmail.com
  • GMX IMAP4 StreamProxy. (http://www.gmx.com/)
  • Godaddy IMAP (since Godaddy runs Courier) (https://www.godaddy.com/)
  • Gromox/Grammm IMAP server (https://docs.grammm.com/)
  • + +
  • Grommunio (https://grommunio.com/)
  • +
  • Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ item about Groupwise (http://www.novell.com/products/groupwise/)
  • hMailServer 5.40-B1950 [host12], 5.3.3 [host2], 4.4.1 [host1], 5.3.2-B1769 [host2], 5.6 [host2] @@ -185,6 +189,8 @@ imapsync --host1 imap.gmail.com
  • SunONE Messaging server 5.2, 6.0 (SUN JES - Java Enterprise System) (http://www.oracle.com/)
  • Sun Java(tm) System Messaging Server 6.2-2.05, 6.2-7.05, 6.3 (http://www.oracle.com/)
  • Surgemail 3.6f5-5, 6.3d-72 [host2] (http://netwinsite.com/surgemail/)
  • + +
  • Tegu mail server (https://mbk-lab.ru/)
  • UW-imap servers (imap-2000b) rijkkramer IMAP4rev1 2000.287 (RedHat uses UW like 2003.338rh), v12.264 Solaris 5.7 (OSI Approved) (http://www.washington.edu/imap/)
  • @@ -246,7 +252,7 @@ alt="Viewable With Any Browser" /> This document last modified on -($Id: imapservers.shtml,v 1.56 2021/06/08 09:56:54 gilles Exp gilles $)
    +($Id: imapservers.shtml,v 1.59 2022/06/02 10:45:27 gilles Exp gilles $)
    Top of the page

    diff --git a/S/news.shtml b/S/news.shtml index e404725..43ed332 100644 --- a/S/news.shtml +++ b/S/news.shtml @@ -58,11 +58,11 @@ If you are very interrested in those projects, don't hesitate to solicit me! +
      +
    • 2.229
    • +
    • General:
    • + +
    • Dependencies added: Proc::ProcessTable
    • +
    • Dependencies removed: None
    • + +
    • Enhancement: Added a stat value: memory footprint times time spent during the sync. The unity is MiB * hour. The stat line is "Memory consumption at the end".
    • +
    • Enhancement: Filtering buggy flags is now case insensitive. \Junk or \JUNK or \jUnK etc. (sub tests_filterbuggyflags)
    • +
    • Enhancement: Added --memorystress to check memory crunching in normal run.
    • + +
    • Usability: Do not email final reports by default. Use --emailreport1 and --emailreport2 to add final emails reports in each INBOX.
    • + +
    • CGI context: +
        +
      • Refuse to serve when the cpu load is greater than 1 per cpu. A load of 3.9 with 4 cores is ok, 4.1 is not. (sub heavy_load_reached_by_cpu)
      • +
      • Refuse to serve when the RAM memory available for imapsync processes is less than 1 GB, presented by percentage on the first line like "64.80% used by processes". (sub heavy_load_percent_threshold)
      • +
      • When refuse to serve, exits with value 69 EX_UNAVAILABLE
      • +
      +
    • +
    • Testing: 1992 unit tests
    • +
    + +
    • 2.200
    • Dependencies removed: None
    • @@ -1039,7 +1068,7 @@ by ignoring PERMANENTFLAGS (Exchange tests) This document last modified on -($Id: news.shtml,v 1.84 2022/04/04 16:11:25 gilles Exp gilles $)
      +($Id: news.shtml,v 1.87 2022/09/15 08:42:40 gilles Exp gilles $)
      Top of the page

      diff --git a/S/paypal_return.shtml b/S/paypal_return.shtml index 2292a1c..daa135b 100644 --- a/S/paypal_return.shtml +++ b/S/paypal_return.shtml @@ -41,7 +41,7 @@ to view details of this transaction (if you have a Paypal account).

      Now you have access to the full unlimited imapsync -online service /X. +online service /X. This online imapsync service doesn't require any installation on your side, just use it as it is.

      Also, in case you want to run imapsync by yourself, you will find imapsync @@ -112,7 +112,7 @@ src="S/images/ab_jlh.png" This document last modified on -($Id: paypal_return.shtml,v 1.39 2020/10/13 16:25:09 gilles Exp gilles $) +($Id: paypal_return.shtml,v 1.40 2022/05/04 10:23:52 gilles Exp gilles $)

      + + + + + + + + + diff --git a/X/proximapsync_form_extra_free.html b/X/proximapsync_form_extra_free.html new file mode 100644 index 0000000..01fcd7f --- /dev/null +++ b/X/proximapsync_form_extra_free.html @@ -0,0 +1,536 @@ + + + + + + + + + + + Mailbox Imapsync Online + + + + + + + + + + + + + + + + + + + +
      + +
      
      +        
      +        
      +
      + +
      + +
      +
      + + Imapsync home + + Top + Pricing + + Bottom +
      +
      + +

      Mailbox Imapsync Online

      + +

      Copy/synchronize a Mailbox (below 3 GB) to another, + without duplicates!
      + Buying gives unlimited syncs of any size.

      + + + + + + +
      +

      Pay by usage type

      +
      + + + +
      + + + +
      + + +
      +

      + 30-day money back guarantee!
      + No question nor condition to get a refund, really, just request it and you'll sure get a refund! +

      + +

      + +If you're a European professional buyer, please enter your VAT number: + + +It's for the invoice and customs declaration.
      +It's ok if you don't have a VAT number.
      +

      +
      +
      + + + +
      +
      +
      +
      + IMAP source Mailbox + + (usually an email address) +
      + + +
      + + + +
      + + +
      + + (or its IP address) +
      + + + + +
      + +
      + +
      + +
      + +
      + + +
      +
      + +
      +
      +
      +
      +
      + +
      +
      +
      +
      + +
      + +
      + +
      + +
      + +
      + +
      + +
      + +
      + + +
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + + +
      + +
      +
      +
      + +
      + + +
      +
      + IMAP destination Mailbox + + (usually an email address) +
      + + +
      + + +
      + + +
      + + (or its IP address) +
      + + + + +
      + +
      + +
      + +
      + +
      + + +
      +
      + + + +
      +
      +
      +
      +
      + +
      + + + + + + + +
      + +
      + If you close this window (or tab) during the synchronization, + it will abort the synchronization, it's like hitting the red button "Abort!" below. +
      + + + + + +
      +
      + +
      +
      + +
      +
      +
      + +
      + +
      
      +
      +        
      +        Best bandwidth available hours are from 11h PM to 11h AM UTC on Mondays to Fridays, all hours on Saturdays and Sundays.
      +        
      +
      +        
      ETA: Estimation Time of Arrival
      + +
      +
      + Progress bar +
      +
      + Progress bar +
      +
      + +
      +

      Console of imapsync launch

      +
      +
      +
      +
      +            
      + +
      + +
      +

      Console of abort

      +
      +
      +
      +
      +            
      +
      +
      + +
      + +

      Log of imapsync run

      + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + +
      +
      +

      + Local bandwidth statistics
      + + + Local bandwidth statistics + +

      +
      + + +
      +
      +

      + Imapsync Online Status over the last 24h
      + Imapsync Online Status over the last 24h + +

      +
      + + +
      +
      +

      + +The service is down? For how long? How often? Take also a look at the +Imapsync Online Status +monitor page powered by the HetrixTools company. + +

      +
      + + +
      + +

      Feel free to contact + Gilles LAMIRAL +

      + + +
      +
      +
      + + Imapsync home page + + Top + + Bottom +
      + ($Id: proximapsync_form_extra_free.html,v 1.3 2022/05/07 13:53:00 gilles Exp gilles $)
      + Terms and conditions for anything: No limits to do anything with this work and this license!
      +
      +
      +
      + + + + + + + + + + + + diff --git a/X/stat_patterns.txt b/X/stat_patterns.txt index 51f3914..d783004 100644 --- a/X/stat_patterns.txt +++ b/X/stat_patterns.txt @@ -1,6 +1,5 @@ ^Here is imapsync -^Load end is -^Load is +^Load .*is ^Server is on heavy load ^Temp directory is ^Current directory is diff --git a/X/u.html b/X/u.html index 981d6bf..77c187a 120000 --- a/X/u.html +++ b/X/u.html @@ -1 +1 @@ -imapsync_form_extra.html \ No newline at end of file +proximapsync_form_extra.html \ No newline at end of file diff --git a/aa b/aa new file mode 100644 index 0000000..73e9cb2 --- /dev/null +++ b/aa @@ -0,0 +1,1542 @@ +HOST1=localhost +HOST2=localhost +perl_syntax passed +Here is imapsync 2.223 on host petite, a linux system with 0.1/2.0 free GiB of RAM, 107.34% used by processes. +with Perl 5.22.1 and Mail::IMAPClient 3.43 +Transfer started at jeudi 07 juillet 2022-07-07 09:53:06 +0200 CEST +PID is 31799 my PPID is 31540 +Log file is LOG_imapsync/2022_07_07_09_53_06_047_imapsync.gl@gmail.com_imapsync.gl@gmail.com.txt ( to change it, use --logfile path ; or use --nolog to turn off logging ) +Load is 0.16 0.29 0.33 3/628 on 2 cores +Current directory is /home/gilles/public_html/imapsync +Real user id is gilles (uid 1000) +Effective user id is gilles (euid 1000) +$RCSfile: imapsync,v $ $Revision: 2.223 $ $Date: 2022/07/03 10:39:30 $ +Command line used, run by /usr/bin/perl: +./imapsync --gmail1 --user1 imapsync.gl@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl_gmail --gmail2 --user2 imapsync.gl@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl_gmail --no-modulesversion --justfolderlists +Temp directory is /tmp ( to change it use --tmpdir dirpath ) +kill -QUIT 31799 # special behavior: call to sub catch_exit +kill -TERM 31799 # special behavior: call to sub catch_exit +kill -INT 31799 # special behavior: call to sub catch_reconnect +kill -HUP 31799 # special behavior: call to sub catch_print +kill -USR1 31799 # special behavior: call to sub toggle_sleep +File /tmp/imapsync.pid does not exist +PID file is /tmp/imapsync.pid ( to change it, use --pidfile filepath ; to avoid it use --pidfile "" ) +Writing my PID 31799 in /tmp/imapsync.pid +Writing also my logfile name in /tmp/imapsync.pid : LOG_imapsync/2022_07_07_09_53_06_047_imapsync.gl@gmail.com_imapsync.gl@gmail.com.txt +Info: will resync flags for already transferred messages. Use --noresyncflags to not resync flags. +SSL debug mode level is --debugssl 1 (can be set from 0 meaning no debug to 4 meaning max debug) +Host1: SSL default mode is like --sslargs1 "SSL_verify_mode=0", meaning for host1 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host1: Use --sslargs1 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host1 +Host2: SSL default mode is like --sslargs2 "SSL_verify_mode=0", meaning for host2 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host2: Use --sslargs2 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host2 +Info: turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1. +Host1: will try to use LOGIN authentication on host1 +Host2: will try to use LOGIN authentication on host2 +Host1: imap connection timeout is 120 seconds +Host2: imap connection timeout is 120 seconds +Host1: imap connection keepalive is on on host1. Use --nokeepalive1 to disable it. +Host2: imap connection keepalive is on on host2. Use --nokeepalive2 to disable it. +Host1: IMAP server [imap.gmail.com] port [993] user [imapsync.gl@gmail.com] +Host2: IMAP server [imap.gmail.com] port [993] user [imapsync.gl@gmail.com] +Host1: connecting and login on host1 [imap.gmail.com] port [993] with user [imapsync.gl@gmail.com] +Host1 IP address: 2a00:1450:400c:c07::6c Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host1 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 t12mb104916042wmq +Host1 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host1: success login on [imap.gmail.com] with user [imapsync.gl@gmail.com] auth [LOGIN] or [LOGIN] +Host2: connecting and login on host2 [imap.gmail.com] port [993] with user [imapsync.gl@gmail.com] +Host2 IP address: 2a00:1450:400c:c07::6d Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host2 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 f11mb222883796wri +Host2 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host2: success login on [imap.gmail.com] with user [imapsync.gl@gmail.com] auth [LOGIN] or [LOGIN] +Host1: state Authenticated +Host2: state Authenticated +Host1 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host2 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host1: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host1") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success +Host2: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host2") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success + +Host2: QUOTA capability found, presented in raw IMAP on next lines +Sending: 5 GETQUOTAROOT INBOX +Sent 22 bytes +Read: * QUOTAROOT "INBOX" "" + * QUOTA "" (STORAGE 23274 15728640) + 5 OK Success + +Host2: Quota current storage is 23832576 bytes. Limit is 16106127360 bytes. So 0.15 % full +Host2: found APPENDLIMIT=35651584 in CAPABILITY (use --appendlimit xxxx to override this automatic setting) +Host2: Setting maxsize to appendlimit 35651584 +Host1: Compression is off. Use --compress1 to allow compression on host1 +Host2: Compression is off. Use --compress2 to allow compression on host2 +Host1: found 144 folders. +Host2: found 144 folders. +Host1: guessing separator from folder listing: [/] +Host1: separator given by NAMESPACE: [/] +Host2: guessing separator from folder listing: [/] +Host2: separator given by NAMESPACE: [/] +Host1: guessing prefix from folder listing: [] +Host1: prefix given by NAMESPACE: [] +Host2: guessing prefix from folder listing: [] +Host2: prefix given by NAMESPACE: [] +Host1: separator and prefix: [/][] +Host2: separator and prefix: [/][] +Including all folders found by default. Use --subscribed or --folder or --folderrec or --include to select specific folders. Use --exclude to unselect specific folders. +Excluding folders matching pattern \[Gmail\]$ +[[Gmail]] + +Host1: Checking wanted folders exist. Use --nocheckfoldersexist to avoid this check (shared of public namespace targeted). +Host1: Checking wanted folders are selectable. Use --nocheckselectable to avoid this check. +Turned on automapping folders ( use --noautomap to turn off automapping ) +Host1: special [Gmail]/All Mail = \All +Host1: special [Gmail]/Bin = \Trash +Host1: special [Gmail]/Drafts = \Drafts +Host1: special [Gmail]/Sent Mail = \Sent +Host1: special [Gmail]/Spam = \Junk +Host1: special [Gmail]/Starred = \Flagged + +Host2: special [Gmail]/All Mail = \All +Host2: special [Gmail]/Bin = \Trash +Host2: special [Gmail]/Drafts = \Drafts +Host2: special [Gmail]/Sent Mail = \Sent +Host2: special [Gmail]/Spam = \Junk +Host2: special [Gmail]/Starred = \Flagged + + +++++ Listing folders +All foldernames are presented between brackets like [X] where X is the foldername. +When a foldername contains non-ASCII characters it is presented in the form +[X] = [Y] where +X is the imap foldername you have to use in command line options and +Y is the utf8 output just printed for convenience, to recognize it. + +Host1: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasNoChildren) "/" "\"qq\"" +* LIST (\HasNoChildren) "/" "\"uni\"" +* LIST (\HasNoChildren) "/" "A B" +* LIST (\HasNoChildren) "/" "A:B:C" +* LIST (\HasChildren) "/" "Aa" +* LIST (\HasChildren) "/" "Aa/B" +* LIST (\HasNoChildren) "/" "Aa/B/C" +* LIST (\HasChildren) "/" "BBB" +* LIST (\HasNoChildren) "/" "BBB/ blanc_begin" +* LIST (\HasNoChildren) "/" "BBB/\"qq\"" +* LIST (\HasNoChildren) "/" "BBB/\"uni\"" +* LIST (\HasNoChildren) "/" "BBB/A" +* LIST (\HasNoChildren) "/" "BBB/A B" +* LIST (\HasNoChildren) "/" "BBB/A:B:C" +* LIST (\HasNoChildren) "/" "BBB/Draft" +* LIST (\HasNoChildren) "/" "BBB/Drafts" +* LIST (\HasNoChildren) "/" "BBB/Giancarlo" +* LIST (\HasNoChildren) "/" "BBB/INBOX" +* LIST (\HasNoChildren) "/" "BBB/Junk" +* LIST (\HasNoChildren) "/" "BBB/Messages envoy&AOk-s" +* LIST (\HasNoChildren) "/" "BBB/Messagesenvoy&AOk-s" +* LIST (\HasNoChildren) "/" "BBB/NUL_char" +* LIST (\HasNoChildren) "/" "BBB/Note" +* LIST (\HasNoChildren) "/" "BBB/SMS" +* LIST (\HasNoChildren) "/" "BBB/Sent" +* LIST (\HasChildren) "/" "BBB/Trash" +* LIST (\HasNoChildren) "/" "BBB/Trash/Giancarlo" +* LIST (\HasNoChildren) "/" "BBB/[bracket]" +* LIST (\HasNoChildren) "/" "BBB/a@bc" +* LIST (\HasNoChildren) "/" "BBB/addheader" +* LIST (\HasNoChildren) "/" "BBB/backstar\\*" +* LIST (\HasNoChildren) "/" "BBB/bigmail2" +* LIST (\HasChildren) "/" "BBB/blanc" +* LIST (\HasChildren \Noselect) "/" "BBB/blanc " +* LIST (\HasNoChildren) "/" "BBB/blanc /blanc2" +* LIST (\HasNoChildren) "/" "BBB/blanc middle" +* LIST (\HasNoChildren) "/" "BBB/blanc/blanc2" +* LIST (\HasNoChildren) "/" "BBB/blanc_begin" +* LIST (\HasNoChildren) "/" "BBB/disarm" +* LIST (\HasNoChildren) "/" "BBB/duplicates" +* LIST (\HasNoChildren) "/" "BBB/errors" +* LIST (\HasNoChildren) "/" "BBB/f g\\h\"i'j" +* LIST (\HasNoChildren) "/" "BBB/f g\\h_i_j" +* LIST (\HasNoChildren) "/" "BBB/few_emails" +* LIST (\HasNoChildren) "/" "BBB/lalala" +* LIST (\HasNoChildren) "/" "BBB/longline" +* LIST (\HasNoChildren) "/" "BBB/new_folder" +* LIST (\HasNoChildren) "/" "BBB/oneemail" +* LIST (\HasNoChildren) "/" "BBB/oneemail2" +* LIST (\HasNoChildren) "/" "BBB/oneemail3" +* LIST (\HasNoChildren) "/" "BBB/partial" +* LIST (\HasNoChildren) "/" "BBB/ppp" +* LIST (\HasNoChildren) "/" "BBB/qqq" +* LIST (\HasNoChildren) "/" "BBB/regexmess" +* LIST (\HasNoChildren) "/" "BBB/scwchu" +* LIST (\HasNoChildren) "/" "BBB/size_null" +* LIST (\HasNoChildren) "/" "BBB/star*" +* LIST (\HasNoChildren) "/" "BBB/uni" +* LIST (\HasNoChildren) "/" "BBB/useuid" +* LIST (\HasChildren) "/" "BBB/yop" +* LIST (\HasNoChildren) "/" "BBB/yop/YAP" +* LIST (\HasChildren \Noselect) "/" "BBB/yop/yap" +* LIST (\HasNoChildren) "/" "BBB/yop/yap/yip" +* LIST (\HasChildren) "/" "BBB/yop/yup" +* LIST (\HasChildren) "/" "BBB/yop/yup/yip" +* LIST (\HasChildren) "/" "BBB/yop/yup/yip/yap" +* LIST (\HasNoChildren) "/" "BBB/yop/yup/yip/yap/yep" +* LIST (\HasChildren) "/" "BBB/yopX" +* LIST (\HasNoChildren) "/" "BBB/yopX/yap" +* LIST (\HasNoChildren) "/" "BBB/yopX/yup" +* LIST (\HasNoChildren) "/" "BBB/zz" +* LIST (\HasNoChildren) "/" "BBB/zz_1" +* LIST (\HasNoChildren) "/" "BBB/zz_2" +* LIST (\HasNoChildren) "/" "BBB/zz_3" +* LIST (\HasNoChildren) "/" "Chats" +* LIST (\HasNoChildren) "/" "Draft" +* LIST (\HasNoChildren) "/" "Drafts" +* LIST (\HasNoChildren) "/" "Dumb" +* LIST (\HasNoChildren) "/" "Giancarlo" +* LIST (\HasChildren \Noselect) "/" "Gmail" +* LIST (\HasNoChildren) "/" "Gmail/Messages envoyes" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasNoChildren) "/" "Important" +* LIST (\HasNoChildren) "/" "Junk" +* LIST (\HasNoChildren) "/" "Messages envoy&AOk-s" +* LIST (\HasNoChildren) "/" "Messages_envoy&AOk-s" +* LIST (\HasNoChildren) "/" "Messagesenvoy&AOk-s" +* LIST (\HasNoChildren) "/" "Note" +* LIST (\HasNoChildren) "/" "SMS" +* LIST (\HasNoChildren) "/" "Sent" +* LIST (\HasNoChildren) "/" "Test" +* LIST (\HasNoChildren) "/" "Trash" +* LIST (\HasNoChildren) "/" "Updates_L" +* LIST (\HasChildren) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Bin" +* LIST (\HasNoChildren) "/" "[Gmail]/Chats" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren) "/" "[Gmail]/Messages envoy&AOk-s" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren) "/" "[Gmail]/Trash" +* LIST (\HasNoChildren) "/" "[Gmail]/te*st" +* LIST (\HasNoChildren) "/" "a@bc" +* LIST (\HasNoChildren) "/" "addheader" +* LIST (\HasNoChildren) "/" "backstar\\*" +* LIST (\HasNoChildren) "/" "bigmail2" +* LIST (\HasChildren) "/" "blanc" +* LIST (\HasChildren \Noselect) "/" "blanc " +* LIST (\HasNoChildren) "/" "blanc /blanc2" +* LIST (\HasNoChildren) "/" "blanc middle" +* LIST (\HasNoChildren) "/" "blanc/blanc2" +* LIST (\HasNoChildren) "/" "blanc_begin" +* LIST (\HasChildren) "/" "blanc_end" +* LIST (\HasNoChildren) "/" "blanc_end/blanc2" +* LIST (\HasChildren) "/" "blanc_end2" +* LIST (\HasNoChildren) "/" "blanc_end2/blanc2" +* LIST (\HasNoChildren) "/" "duplicates" +* LIST (\HasNoChildren) "/" "f g\\h\"i'j" +* LIST (\HasNoChildren) "/" "f g\\h_i_j" +* LIST (\HasNoChildren) "/" "few_emails" +* LIST (\HasNoChildren) "/" "inbox_copy" +* LIST (\HasNoChildren) "/" "lalala" +* LIST (\HasNoChildren) "/" "new_folder" +* LIST (\HasNoChildren) "/" "oneemail" +* LIST (\HasNoChildren) "/" "oneemail2" +* LIST (\HasNoChildren) "/" "oneemail3" +* LIST (\HasNoChildren) "/" "ppp" +* LIST (\HasNoChildren) "/" "qqq" +* LIST (\HasNoChildren) "/" "regexmess" +* LIST (\HasNoChildren) "/" "scwchu" +* LIST (\HasNoChildren) "/" "size_null" +* LIST (\HasNoChildren) "/" "star*" +* LIST (\HasNoChildren) "/" "te*st" +* LIST (\HasNoChildren) "/" "uni" +* LIST (\HasNoChildren) "/" "useuid" +* LIST (\HasChildren) "/" "yop" +* LIST (\HasNoChildren) "/" "yop/yap" +* LIST (\HasChildren) "/" "yop/yup" +* LIST (\HasChildren) "/" "yop/yup/yip" +* LIST (\HasChildren) "/" "yop/yup/yip/yap" +* LIST (\HasNoChildren) "/" "yop/yup/yip/yap/yep" +* LIST (\HasChildren) "/" "yopX" +* LIST (\HasNoChildren) "/" "yopX/yap" +* LIST (\HasNoChildren) "/" "yopX/yup" +* LIST (\HasNoChildren) "/" "zz" +153 OK Success + +["qq"] +["uni"] +[A B] +[A:B:C] +[Aa] +[Aa/B] +[Aa/B/C] +[BBB] +[BBB/ blanc_begin] +[BBB/"qq"] +[BBB/"uni"] +[BBB/A] +[BBB/A B] +[BBB/A:B:C] +[BBB/Draft] +[BBB/Drafts] +[BBB/Giancarlo] +[BBB/INBOX] +[BBB/Junk] +[BBB/Messages envoy&AOk-s] = [BBB/Messages envoyés] +[BBB/Messagesenvoy&AOk-s] = [BBB/Messagesenvoyés] +[BBB/NUL_char] +[BBB/Note] +[BBB/SMS] +[BBB/Sent] +[BBB/Trash] +[BBB/Trash/Giancarlo] +[BBB/[bracket]] +[BBB/a@bc] +[BBB/addheader] +[BBB/backstar\*] +[BBB/bigmail2] +[BBB/blanc] +[BBB/blanc /blanc2] +[BBB/blanc middle] +[BBB/blanc/blanc2] +[BBB/blanc_begin] +[BBB/disarm] +[BBB/duplicates] +[BBB/errors] +[BBB/f g\h"i'j] +[BBB/f g\h_i_j] +[BBB/few_emails] +[BBB/lalala] +[BBB/longline] +[BBB/new_folder] +[BBB/oneemail] +[BBB/oneemail2] +[BBB/oneemail3] +[BBB/partial] +[BBB/ppp] +[BBB/qqq] +[BBB/regexmess] +[BBB/scwchu] +[BBB/size_null] +[BBB/star*] +[BBB/uni] +[BBB/useuid] +[BBB/yop] +[BBB/yop/YAP] +[BBB/yop/yap/yip] +[BBB/yop/yup] +[BBB/yop/yup/yip] +[BBB/yop/yup/yip/yap] +[BBB/yop/yup/yip/yap/yep] +[BBB/yopX] +[BBB/yopX/yap] +[BBB/yopX/yup] +[BBB/zz] +[BBB/zz_1] +[BBB/zz_2] +[BBB/zz_3] +[Chats] +[Draft] +[Drafts] +[Dumb] +[Giancarlo] +[Gmail/Messages envoyes] +[INBOX] +[Important] +[Junk] +[Messages envoy&AOk-s] = [Messages envoyés] +[Messages_envoy&AOk-s] = [Messages_envoyés] +[Messagesenvoy&AOk-s] = [Messagesenvoyés] +[Note] +[SMS] +[Sent] +[Test] +[Trash] +[Updates_L] +[[Gmail]] +[[Gmail]/All Mail] +[[Gmail]/Bin] +[[Gmail]/Chats] +[[Gmail]/Drafts] +[[Gmail]/Important] +[[Gmail]/Messages envoy&AOk-s] = [[Gmail]/Messages envoyés] +[[Gmail]/Sent Mail] +[[Gmail]/Spam] +[[Gmail]/Starred] +[[Gmail]/Trash] +[[Gmail]/te*st] +[a@bc] +[addheader] +[backstar\*] +[bigmail2] +[blanc] +[blanc /blanc2] +[blanc middle] +[blanc/blanc2] +[blanc_begin] +[blanc_end] +[blanc_end/blanc2] +[blanc_end2] +[blanc_end2/blanc2] +[duplicates] +[f g\h"i'j] +[f g\h_i_j] +[few_emails] +[inbox_copy] +[lalala] +[new_folder] +[oneemail] +[oneemail2] +[oneemail3] +[ppp] +[qqq] +[regexmess] +[scwchu] +[size_null] +[star*] +[te*st] +[uni] +[useuid] +[yop] +[yop/yap] +[yop/yup] +[yop/yup/yip] +[yop/yup/yip/yap] +[yop/yup/yip/yap/yep] +[yopX] +[yopX/yap] +[yopX/yup] +[zz] + +Host2: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasNoChildren) "/" "\"qq\"" +* LIST (\HasNoChildren) "/" "\"uni\"" +* LIST (\HasNoChildren) "/" "A B" +* LIST (\HasNoChildren) "/" "A:B:C" +* LIST (\HasChildren) "/" "Aa" +* LIST (\HasChildren) "/" "Aa/B" +* LIST (\HasNoChildren) "/" "Aa/B/C" +* LIST (\HasChildren) "/" "BBB" +* LIST (\HasNoChildren) "/" "BBB/ blanc_begin" +* LIST (\HasNoChildren) "/" "BBB/\"qq\"" +* LIST (\HasNoChildren) "/" "BBB/\"uni\"" +* LIST (\HasNoChildren) "/" "BBB/A" +* LIST (\HasNoChildren) "/" "BBB/A B" +* LIST (\HasNoChildren) "/" "BBB/A:B:C" +* LIST (\HasNoChildren) "/" "BBB/Draft" +* LIST (\HasNoChildren) "/" "BBB/Drafts" +* LIST (\HasNoChildren) "/" "BBB/Giancarlo" +* LIST (\HasNoChildren) "/" "BBB/INBOX" +* LIST (\HasNoChildren) "/" "BBB/Junk" +* LIST (\HasNoChildren) "/" "BBB/Messages envoy&AOk-s" +* LIST (\HasNoChildren) "/" "BBB/Messagesenvoy&AOk-s" +* LIST (\HasNoChildren) "/" "BBB/NUL_char" +* LIST (\HasNoChildren) "/" "BBB/Note" +* LIST (\HasNoChildren) "/" "BBB/SMS" +* LIST (\HasNoChildren) "/" "BBB/Sent" +* LIST (\HasChildren) "/" "BBB/Trash" +* LIST (\HasNoChildren) "/" "BBB/Trash/Giancarlo" +* LIST (\HasNoChildren) "/" "BBB/[bracket]" +* LIST (\HasNoChildren) "/" "BBB/a@bc" +* LIST (\HasNoChildren) "/" "BBB/addheader" +* LIST (\HasNoChildren) "/" "BBB/backstar\\*" +* LIST (\HasNoChildren) "/" "BBB/bigmail2" +* LIST (\HasChildren) "/" "BBB/blanc" +* LIST (\HasChildren \Noselect) "/" "BBB/blanc " +* LIST (\HasNoChildren) "/" "BBB/blanc /blanc2" +* LIST (\HasNoChildren) "/" "BBB/blanc middle" +* LIST (\HasNoChildren) "/" "BBB/blanc/blanc2" +* LIST (\HasNoChildren) "/" "BBB/blanc_begin" +* LIST (\HasNoChildren) "/" "BBB/disarm" +* LIST (\HasNoChildren) "/" "BBB/duplicates" +* LIST (\HasNoChildren) "/" "BBB/errors" +* LIST (\HasNoChildren) "/" "BBB/f g\\h\"i'j" +* LIST (\HasNoChildren) "/" "BBB/f g\\h_i_j" +* LIST (\HasNoChildren) "/" "BBB/few_emails" +* LIST (\HasNoChildren) "/" "BBB/lalala" +* LIST (\HasNoChildren) "/" "BBB/longline" +* LIST (\HasNoChildren) "/" "BBB/new_folder" +* LIST (\HasNoChildren) "/" "BBB/oneemail" +* LIST (\HasNoChildren) "/" "BBB/oneemail2" +* LIST (\HasNoChildren) "/" "BBB/oneemail3" +* LIST (\HasNoChildren) "/" "BBB/partial" +* LIST (\HasNoChildren) "/" "BBB/ppp" +* LIST (\HasNoChildren) "/" "BBB/qqq" +* LIST (\HasNoChildren) "/" "BBB/regexmess" +* LIST (\HasNoChildren) "/" "BBB/scwchu" +* LIST (\HasNoChildren) "/" "BBB/size_null" +* LIST (\HasNoChildren) "/" "BBB/star*" +* LIST (\HasNoChildren) "/" "BBB/uni" +* LIST (\HasNoChildren) "/" "BBB/useuid" +* LIST (\HasChildren) "/" "BBB/yop" +* LIST (\HasNoChildren) "/" "BBB/yop/YAP" +* LIST (\HasChildren \Noselect) "/" "BBB/yop/yap" +* LIST (\HasNoChildren) "/" "BBB/yop/yap/yip" +* LIST (\HasChildren) "/" "BBB/yop/yup" +* LIST (\HasChildren) "/" "BBB/yop/yup/yip" +* LIST (\HasChildren) "/" "BBB/yop/yup/yip/yap" +* LIST (\HasNoChildren) "/" "BBB/yop/yup/yip/yap/yep" +* LIST (\HasChildren) "/" "BBB/yopX" +* LIST (\HasNoChildren) "/" "BBB/yopX/yap" +* LIST (\HasNoChildren) "/" "BBB/yopX/yup" +* LIST (\HasNoChildren) "/" "BBB/zz" +* LIST (\HasNoChildren) "/" "BBB/zz_1" +* LIST (\HasNoChildren) "/" "BBB/zz_2" +* LIST (\HasNoChildren) "/" "BBB/zz_3" +* LIST (\HasNoChildren) "/" "Chats" +* LIST (\HasNoChildren) "/" "Draft" +* LIST (\HasNoChildren) "/" "Drafts" +* LIST (\HasNoChildren) "/" "Dumb" +* LIST (\HasNoChildren) "/" "Giancarlo" +* LIST (\HasChildren \Noselect) "/" "Gmail" +* LIST (\HasNoChildren) "/" "Gmail/Messages envoyes" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasNoChildren) "/" "Important" +* LIST (\HasNoChildren) "/" "Junk" +* LIST (\HasNoChildren) "/" "Messages envoy&AOk-s" +* LIST (\HasNoChildren) "/" "Messages_envoy&AOk-s" +* LIST (\HasNoChildren) "/" "Messagesenvoy&AOk-s" +* LIST (\HasNoChildren) "/" "Note" +* LIST (\HasNoChildren) "/" "SMS" +* LIST (\HasNoChildren) "/" "Sent" +* LIST (\HasNoChildren) "/" "Test" +* LIST (\HasNoChildren) "/" "Trash" +* LIST (\HasNoChildren) "/" "Updates_L" +* LIST (\HasChildren) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Bin" +* LIST (\HasNoChildren) "/" "[Gmail]/Chats" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren) "/" "[Gmail]/Messages envoy&AOk-s" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren) "/" "[Gmail]/Trash" +* LIST (\HasNoChildren) "/" "[Gmail]/te*st" +* LIST (\HasNoChildren) "/" "a@bc" +* LIST (\HasNoChildren) "/" "addheader" +* LIST (\HasNoChildren) "/" "backstar\\*" +* LIST (\HasNoChildren) "/" "bigmail2" +* LIST (\HasChildren) "/" "blanc" +* LIST (\HasChildren \Noselect) "/" "blanc " +* LIST (\HasNoChildren) "/" "blanc /blanc2" +* LIST (\HasNoChildren) "/" "blanc middle" +* LIST (\HasNoChildren) "/" "blanc/blanc2" +* LIST (\HasNoChildren) "/" "blanc_begin" +* LIST (\HasChildren) "/" "blanc_end" +* LIST (\HasNoChildren) "/" "blanc_end/blanc2" +* LIST (\HasChildren) "/" "blanc_end2" +* LIST (\HasNoChildren) "/" "blanc_end2/blanc2" +* LIST (\HasNoChildren) "/" "duplicates" +* LIST (\HasNoChildren) "/" "f g\\h\"i'j" +* LIST (\HasNoChildren) "/" "f g\\h_i_j" +* LIST (\HasNoChildren) "/" "few_emails" +* LIST (\HasNoChildren) "/" "inbox_copy" +* LIST (\HasNoChildren) "/" "lalala" +* LIST (\HasNoChildren) "/" "new_folder" +* LIST (\HasNoChildren) "/" "oneemail" +* LIST (\HasNoChildren) "/" "oneemail2" +* LIST (\HasNoChildren) "/" "oneemail3" +* LIST (\HasNoChildren) "/" "ppp" +* LIST (\HasNoChildren) "/" "qqq" +* LIST (\HasNoChildren) "/" "regexmess" +* LIST (\HasNoChildren) "/" "scwchu" +* LIST (\HasNoChildren) "/" "size_null" +* LIST (\HasNoChildren) "/" "star*" +* LIST (\HasNoChildren) "/" "te*st" +* LIST (\HasNoChildren) "/" "uni" +* LIST (\HasNoChildren) "/" "useuid" +* LIST (\HasChildren) "/" "yop" +* LIST (\HasNoChildren) "/" "yop/yap" +* LIST (\HasChildren) "/" "yop/yup" +* LIST (\HasChildren) "/" "yop/yup/yip" +* LIST (\HasChildren) "/" "yop/yup/yip/yap" +* LIST (\HasNoChildren) "/" "yop/yup/yip/yap/yep" +* LIST (\HasChildren) "/" "yopX" +* LIST (\HasNoChildren) "/" "yopX/yap" +* LIST (\HasNoChildren) "/" "yopX/yup" +* LIST (\HasNoChildren) "/" "zz" +11 OK Success + +["qq"] +["uni"] +[A B] +[A:B:C] +[Aa] +[Aa/B] +[Aa/B/C] +[BBB] +[BBB/ blanc_begin] +[BBB/"qq"] +[BBB/"uni"] +[BBB/A] +[BBB/A B] +[BBB/A:B:C] +[BBB/Draft] +[BBB/Drafts] +[BBB/Giancarlo] +[BBB/INBOX] +[BBB/Junk] +[BBB/Messages envoy&AOk-s] = [BBB/Messages envoyés] +[BBB/Messagesenvoy&AOk-s] = [BBB/Messagesenvoyés] +[BBB/NUL_char] +[BBB/Note] +[BBB/SMS] +[BBB/Sent] +[BBB/Trash] +[BBB/Trash/Giancarlo] +[BBB/[bracket]] +[BBB/a@bc] +[BBB/addheader] +[BBB/backstar\*] +[BBB/bigmail2] +[BBB/blanc] +[BBB/blanc /blanc2] +[BBB/blanc middle] +[BBB/blanc/blanc2] +[BBB/blanc_begin] +[BBB/disarm] +[BBB/duplicates] +[BBB/errors] +[BBB/f g\h"i'j] +[BBB/f g\h_i_j] +[BBB/few_emails] +[BBB/lalala] +[BBB/longline] +[BBB/new_folder] +[BBB/oneemail] +[BBB/oneemail2] +[BBB/oneemail3] +[BBB/partial] +[BBB/ppp] +[BBB/qqq] +[BBB/regexmess] +[BBB/scwchu] +[BBB/size_null] +[BBB/star*] +[BBB/uni] +[BBB/useuid] +[BBB/yop] +[BBB/yop/YAP] +[BBB/yop/yap/yip] +[BBB/yop/yup] +[BBB/yop/yup/yip] +[BBB/yop/yup/yip/yap] +[BBB/yop/yup/yip/yap/yep] +[BBB/yopX] +[BBB/yopX/yap] +[BBB/yopX/yup] +[BBB/zz] +[BBB/zz_1] +[BBB/zz_2] +[BBB/zz_3] +[Chats] +[Draft] +[Drafts] +[Dumb] +[Giancarlo] +[Gmail/Messages envoyes] +[INBOX] +[Important] +[Junk] +[Messages envoy&AOk-s] = [Messages envoyés] +[Messages_envoy&AOk-s] = [Messages_envoyés] +[Messagesenvoy&AOk-s] = [Messagesenvoyés] +[Note] +[SMS] +[Sent] +[Test] +[Trash] +[Updates_L] +[[Gmail]] +[[Gmail]/All Mail] +[[Gmail]/Bin] +[[Gmail]/Chats] +[[Gmail]/Drafts] +[[Gmail]/Important] +[[Gmail]/Messages envoy&AOk-s] = [[Gmail]/Messages envoyés] +[[Gmail]/Sent Mail] +[[Gmail]/Spam] +[[Gmail]/Starred] +[[Gmail]/Trash] +[[Gmail]/te*st] +[a@bc] +[addheader] +[backstar\*] +[bigmail2] +[blanc] +[blanc /blanc2] +[blanc middle] +[blanc/blanc2] +[blanc_begin] +[blanc_end] +[blanc_end/blanc2] +[blanc_end2] +[blanc_end2/blanc2] +[duplicates] +[f g\h"i'j] +[f g\h_i_j] +[few_emails] +[inbox_copy] +[lalala] +[new_folder] +[oneemail] +[oneemail2] +[oneemail3] +[ppp] +[qqq] +[regexmess] +[scwchu] +[size_null] +[star*] +[te*st] +[uni] +[useuid] +[yop] +[yop/yap] +[yop/yup] +[yop/yup/yip] +[yop/yup/yip/yap] +[yop/yup/yip/yap/yep] +[yopX] +[yopX/yap] +[yopX/yup] +[zz] + +Folders mapping from --automap feature (use --f1f2 to override any mapping): +[[Gmail]/Starred] -> [[Gmail]/Starred] +[[Gmail]/Bin] -> [[Gmail]/Bin] +[[Gmail]/Drafts] -> [[Gmail]/Drafts] +[Junk] -> [[Gmail]/Spam] +[[Gmail]/Sent Mail] -> [[Gmail]/Sent Mail] +[[Gmail]/All Mail] -> [[Gmail]/All Mail] +[Sent] -> [[Gmail]/Sent Mail] +[Trash] -> [[Gmail]/Bin] +[[Gmail]/Spam] -> [[Gmail]/Spam] +[Drafts] -> [[Gmail]/Drafts] + +Exiting because of --justfolderlists +Exiting with return value 0 (EX_OK: successful termination) 0/50 nb_errors/max_errors PID 31799 +Removing pidfile /tmp/imapsync.pid +Disconnecting from host1 imap.gmail.com user1 imapsync.gl@gmail.com +Disconnecting from host2 imap.gmail.com user2 imapsync.gl@gmail.com +Log file is LOG_imapsync/2022_07_07_09_53_06_047_imapsync.gl@gmail.com_imapsync.gl@gmail.com.txt ( to change it, use --logfile filepath ; or use --nolog to turn off logging ) +Here is imapsync 2.223 on host petite, a linux system with 0.1/2.0 free GiB of RAM, 108.00% used by processes. +with Perl 5.22.1 and Mail::IMAPClient 3.43 +Transfer started at jeudi 07 juillet 2022-07-07 09:53:35 +0200 CEST +PID is 31806 my PPID is 31540 +Log file is LOG_imapsync/2022_07_07_09_53_35_129_imapsync.gl0@gmail.com_imapsync.gl0@gmail.com.txt ( to change it, use --logfile path ; or use --nolog to turn off logging ) +Load is 0.18 0.28 0.32 3/630 on 2 cores +Current directory is /home/gilles/public_html/imapsync +Real user id is gilles (uid 1000) +Effective user id is gilles (euid 1000) +$RCSfile: imapsync,v $ $Revision: 2.223 $ $Date: 2022/07/03 10:39:30 $ +Command line used, run by /usr/bin/perl: +./imapsync --gmail1 --user1 imapsync.gl0@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl0_gmail --gmail2 --user2 imapsync.gl0@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl0_gmail --no-modulesversion --justfolderlists +Temp directory is /tmp ( to change it use --tmpdir dirpath ) +kill -QUIT 31806 # special behavior: call to sub catch_exit +kill -TERM 31806 # special behavior: call to sub catch_exit +kill -INT 31806 # special behavior: call to sub catch_reconnect +kill -HUP 31806 # special behavior: call to sub catch_print +kill -USR1 31806 # special behavior: call to sub toggle_sleep +File /tmp/imapsync.pid does not exist +PID file is /tmp/imapsync.pid ( to change it, use --pidfile filepath ; to avoid it use --pidfile "" ) +Writing my PID 31806 in /tmp/imapsync.pid +Writing also my logfile name in /tmp/imapsync.pid : LOG_imapsync/2022_07_07_09_53_35_129_imapsync.gl0@gmail.com_imapsync.gl0@gmail.com.txt +Info: will resync flags for already transferred messages. Use --noresyncflags to not resync flags. +SSL debug mode level is --debugssl 1 (can be set from 0 meaning no debug to 4 meaning max debug) +Host1: SSL default mode is like --sslargs1 "SSL_verify_mode=0", meaning for host1 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host1: Use --sslargs1 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host1 +Host2: SSL default mode is like --sslargs2 "SSL_verify_mode=0", meaning for host2 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host2: Use --sslargs2 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host2 +Info: turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1. +Host1: will try to use LOGIN authentication on host1 +Host2: will try to use LOGIN authentication on host2 +Host1: imap connection timeout is 120 seconds +Host2: imap connection timeout is 120 seconds +Host1: imap connection keepalive is on on host1. Use --nokeepalive1 to disable it. +Host2: imap connection keepalive is on on host2. Use --nokeepalive2 to disable it. +Host1: IMAP server [imap.gmail.com] port [993] user [imapsync.gl0@gmail.com] +Host2: IMAP server [imap.gmail.com] port [993] user [imapsync.gl0@gmail.com] +Host1: connecting and login on host1 [imap.gmail.com] port [993] with user [imapsync.gl0@gmail.com] +Host1 IP address: 2a00:1450:400c:c07::6c Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host1 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 u13mb163543970wrs +Host1 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host1: success login on [imap.gmail.com] with user [imapsync.gl0@gmail.com] auth [LOGIN] or [LOGIN] +Host2: connecting and login on host2 [imap.gmail.com] port [993] with user [imapsync.gl0@gmail.com] +Host2 IP address: 2a00:1450:400c:c07::6d Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host2 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 i2mb49702066wmh +Host2 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host2: success login on [imap.gmail.com] with user [imapsync.gl0@gmail.com] auth [LOGIN] or [LOGIN] +Host1: state Authenticated +Host2: state Authenticated +Host1 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host2 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host1: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host1") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success +Host2: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host2") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success + +Host2: QUOTA capability found, presented in raw IMAP on next lines +Sending: 5 GETQUOTAROOT INBOX +Sent 22 bytes +Read: * QUOTAROOT "INBOX" "" + * QUOTA "" (STORAGE 687 15728640) + 5 OK Success + +Host2: Quota current storage is 703488 bytes. Limit is 16106127360 bytes. So 0.00 % full +Host2: found APPENDLIMIT=35651584 in CAPABILITY (use --appendlimit xxxx to override this automatic setting) +Host2: Setting maxsize to appendlimit 35651584 +Host1: Compression is off. Use --compress1 to allow compression on host1 +Host2: Compression is off. Use --compress2 to allow compression on host2 +Host1: found 8 folders. +Host2: found 8 folders. +Host1: guessing separator from folder listing: [/] +Host1: separator given by NAMESPACE: [/] +Host2: guessing separator from folder listing: [/] +Host2: separator given by NAMESPACE: [/] +Host1: guessing prefix from folder listing: [] +Host1: prefix given by NAMESPACE: [] +Host2: guessing prefix from folder listing: [] +Host2: prefix given by NAMESPACE: [] +Host1: separator and prefix: [/][] +Host2: separator and prefix: [/][] +Including all folders found by default. Use --subscribed or --folder or --folderrec or --include to select specific folders. Use --exclude to unselect specific folders. +Excluding folders matching pattern \[Gmail\]$ + +Host1: Checking wanted folders exist. Use --nocheckfoldersexist to avoid this check (shared of public namespace targeted). +Host1: Checking wanted folders are selectable. Use --nocheckselectable to avoid this check. +Turned on automapping folders ( use --noautomap to turn off automapping ) +Host1: special [Gmail]/All Mail = \All +Host1: special [Gmail]/Drafts = \Drafts +Host1: special [Gmail]/Sent Mail = \Sent +Host1: special [Gmail]/Spam = \Junk +Host1: special [Gmail]/Starred = \Flagged +Host1: special [Gmail]/Trash = \Trash + +Host2: special [Gmail]/All Mail = \All +Host2: special [Gmail]/Drafts = \Drafts +Host2: special [Gmail]/Sent Mail = \Sent +Host2: special [Gmail]/Spam = \Junk +Host2: special [Gmail]/Starred = \Flagged +Host2: special [Gmail]/Trash = \Trash + + +++++ Listing folders +All foldernames are presented between brackets like [X] where X is the foldername. +When a foldername contains non-ASCII characters it is presented in the form +[X] = [Y] where +X is the imap foldername you have to use in command line options and +Y is the utf8 output just printed for convenience, to recognize it. + +Host1: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash" +18 OK Success + +[INBOX] +[[Gmail]/All Mail] +[[Gmail]/Drafts] +[[Gmail]/Important] +[[Gmail]/Sent Mail] +[[Gmail]/Spam] +[[Gmail]/Starred] +[[Gmail]/Trash] + +Host2: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash" +11 OK Success + +[INBOX] +[[Gmail]/All Mail] +[[Gmail]/Drafts] +[[Gmail]/Important] +[[Gmail]/Sent Mail] +[[Gmail]/Spam] +[[Gmail]/Starred] +[[Gmail]/Trash] + +Folders mapping from --automap feature (use --f1f2 to override any mapping): +[[Gmail]/Starred] -> [[Gmail]/Starred] +[[Gmail]/Trash] -> [[Gmail]/Trash] +[[Gmail]/Sent Mail] -> [[Gmail]/Sent Mail] +[[Gmail]/Drafts] -> [[Gmail]/Drafts] +[[Gmail]/Spam] -> [[Gmail]/Spam] +[[Gmail]/All Mail] -> [[Gmail]/All Mail] + +Exiting because of --justfolderlists +Exiting with return value 0 (EX_OK: successful termination) 0/50 nb_errors/max_errors PID 31806 +Removing pidfile /tmp/imapsync.pid +Disconnecting from host1 imap.gmail.com user1 imapsync.gl0@gmail.com +Disconnecting from host2 imap.gmail.com user2 imapsync.gl0@gmail.com +Log file is LOG_imapsync/2022_07_07_09_53_35_129_imapsync.gl0@gmail.com_imapsync.gl0@gmail.com.txt ( to change it, use --logfile filepath ; or use --nolog to turn off logging ) +Here is imapsync 2.223 on host petite, a linux system with 0.1/2.0 free GiB of RAM, 108.07% used by processes. +with Perl 5.22.1 and Mail::IMAPClient 3.43 +Transfer started at jeudi 07 juillet 2022-07-07 09:53:44 +0200 CEST +PID is 31811 my PPID is 31540 +Log file is LOG_imapsync/2022_07_07_09_53_44_949_imapsync.gl1@gmail.com_imapsync.gl1@gmail.com.txt ( to change it, use --logfile path ; or use --nolog to turn off logging ) +Load is 0.23 0.28 0.32 4/631 on 2 cores +Current directory is /home/gilles/public_html/imapsync +Real user id is gilles (uid 1000) +Effective user id is gilles (euid 1000) +$RCSfile: imapsync,v $ $Revision: 2.223 $ $Date: 2022/07/03 10:39:30 $ +Command line used, run by /usr/bin/perl: +./imapsync --gmail1 --user1 imapsync.gl1@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl1_gmail --gmail2 --user2 imapsync.gl1@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl1_gmail --no-modulesversion --justfolderlists +Temp directory is /tmp ( to change it use --tmpdir dirpath ) +kill -QUIT 31811 # special behavior: call to sub catch_exit +kill -TERM 31811 # special behavior: call to sub catch_exit +kill -INT 31811 # special behavior: call to sub catch_reconnect +kill -HUP 31811 # special behavior: call to sub catch_print +kill -USR1 31811 # special behavior: call to sub toggle_sleep +File /tmp/imapsync.pid does not exist +PID file is /tmp/imapsync.pid ( to change it, use --pidfile filepath ; to avoid it use --pidfile "" ) +Writing my PID 31811 in /tmp/imapsync.pid +Writing also my logfile name in /tmp/imapsync.pid : LOG_imapsync/2022_07_07_09_53_44_949_imapsync.gl1@gmail.com_imapsync.gl1@gmail.com.txt +Info: will resync flags for already transferred messages. Use --noresyncflags to not resync flags. +SSL debug mode level is --debugssl 1 (can be set from 0 meaning no debug to 4 meaning max debug) +Host1: SSL default mode is like --sslargs1 "SSL_verify_mode=0", meaning for host1 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host1: Use --sslargs1 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host1 +Host2: SSL default mode is like --sslargs2 "SSL_verify_mode=0", meaning for host2 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host2: Use --sslargs2 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host2 +Info: turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1. +Host1: will try to use LOGIN authentication on host1 +Host2: will try to use LOGIN authentication on host2 +Host1: imap connection timeout is 120 seconds +Host2: imap connection timeout is 120 seconds +Host1: imap connection keepalive is on on host1. Use --nokeepalive1 to disable it. +Host2: imap connection keepalive is on on host2. Use --nokeepalive2 to disable it. +Host1: IMAP server [imap.gmail.com] port [993] user [imapsync.gl1@gmail.com] +Host2: IMAP server [imap.gmail.com] port [993] user [imapsync.gl1@gmail.com] +Host1: connecting and login on host1 [imap.gmail.com] port [993] with user [imapsync.gl1@gmail.com] +Host1 IP address: 2a00:1450:400c:c04::6c Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host1 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 2mb79178924wmo +Host1 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host1: success login on [imap.gmail.com] with user [imapsync.gl1@gmail.com] auth [LOGIN] or [LOGIN] +Host2: connecting and login on host2 [imap.gmail.com] port [993] with user [imapsync.gl1@gmail.com] +Host2 IP address: 2a00:1450:400c:c04::6d Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host2 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 y2mb272977894wrd +Host2 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host2: success login on [imap.gmail.com] with user [imapsync.gl1@gmail.com] auth [LOGIN] or [LOGIN] +Host1: state Authenticated +Host2: state Authenticated +Host1 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host2 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host1: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host1") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success +Host2: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host2") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success + +Host2: QUOTA capability found, presented in raw IMAP on next lines +Sending: 5 GETQUOTAROOT INBOX +Sent 22 bytes +Read: * QUOTAROOT "INBOX" "" + * QUOTA "" (STORAGE 391 15728640) + 5 OK Success + +Host2: Quota current storage is 400384 bytes. Limit is 16106127360 bytes. So 0.00 % full +Host2: found APPENDLIMIT=35651584 in CAPABILITY (use --appendlimit xxxx to override this automatic setting) +Host2: Setting maxsize to appendlimit 35651584 +Host1: Compression is off. Use --compress1 to allow compression on host1 +Host2: Compression is off. Use --compress2 to allow compression on host2 +Host1: found 12 folders. +Host2: found 12 folders. +Host1: guessing separator from folder listing: [/] +Host1: separator given by NAMESPACE: [/] +Host2: guessing separator from folder listing: [/] +Host2: separator given by NAMESPACE: [/] +Host1: guessing prefix from folder listing: [] +Host1: prefix given by NAMESPACE: [] +Host2: guessing prefix from folder listing: [] +Host2: prefix given by NAMESPACE: [] +Host1: separator and prefix: [/][] +Host2: separator and prefix: [/][] +Including all folders found by default. Use --subscribed or --folder or --folderrec or --include to select specific folders. Use --exclude to unselect specific folders. +Excluding folders matching pattern \[Gmail\]$ + +Host1: Checking wanted folders exist. Use --nocheckfoldersexist to avoid this check (shared of public namespace targeted). +Host1: Checking wanted folders are selectable. Use --nocheckselectable to avoid this check. +Turned on automapping folders ( use --noautomap to turn off automapping ) +Host1: special [Gmail]/All Mail = \All +Host1: special [Gmail]/Starred = \Flagged + +Host2: special [Gmail]/All Mail = \All +Host2: special [Gmail]/Starred = \Flagged + + +++++ Listing folders +All foldernames are presented between brackets like [X] where X is the foldername. +When a foldername contains non-ASCII characters it is presented in the form +[X] = [Y] where +X is the imap foldername you have to use in command line options and +Y is the utf8 output just printed for convenience, to recognize it. + +Host1: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasNoChildren) "/" "Blabla" +* LIST (\HasNoChildren) "/" "Blan Blan" +* LIST (\HasNoChildren) "/" "Coucou" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasNoChildren) "/" "Test" +* LIST (\HasNoChildren) "/" "Work" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren) "/" "\\Important" +* LIST (\HasNoChildren) "/" "\\Inbox" +* LIST (\HasNoChildren) "/" "\\Starred" +22 OK Success + +[Blabla] +[Blan Blan] +[Coucou] +[INBOX] +[Test] +[Work] +[[Gmail]/All Mail] +[[Gmail]/Important] +[[Gmail]/Starred] +[\Important] +[\Inbox] +[\Starred] + +Host2: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasNoChildren) "/" "Blabla" +* LIST (\HasNoChildren) "/" "Blan Blan" +* LIST (\HasNoChildren) "/" "Coucou" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasNoChildren) "/" "Test" +* LIST (\HasNoChildren) "/" "Work" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren) "/" "\\Important" +* LIST (\HasNoChildren) "/" "\\Inbox" +* LIST (\HasNoChildren) "/" "\\Starred" +11 OK Success + +[Blabla] +[Blan Blan] +[Coucou] +[INBOX] +[Test] +[Work] +[[Gmail]/All Mail] +[[Gmail]/Important] +[[Gmail]/Starred] +[\Important] +[\Inbox] +[\Starred] + +Folders mapping from --automap feature (use --f1f2 to override any mapping): +[[Gmail]/Starred] -> [[Gmail]/Starred] +[[Gmail]/All Mail] -> [[Gmail]/All Mail] + +Exiting because of --justfolderlists +Exiting with return value 0 (EX_OK: successful termination) 0/50 nb_errors/max_errors PID 31811 +Removing pidfile /tmp/imapsync.pid +Disconnecting from host1 imap.gmail.com user1 imapsync.gl1@gmail.com +Disconnecting from host2 imap.gmail.com user2 imapsync.gl1@gmail.com +Log file is LOG_imapsync/2022_07_07_09_53_44_949_imapsync.gl1@gmail.com_imapsync.gl1@gmail.com.txt ( to change it, use --logfile filepath ; or use --nolog to turn off logging ) +Here is imapsync 2.223 on host petite, a linux system with 0.1/2.0 free GiB of RAM, 109.22% used by processes. +with Perl 5.22.1 and Mail::IMAPClient 3.43 +Transfer started at jeudi 07 juillet 2022-07-07 09:53:57 +0200 CEST +PID is 31816 my PPID is 31540 +Log file is LOG_imapsync/2022_07_07_09_53_57_868_imapsync.gl2@gmail.com_imapsync.gl2@gmail.com.txt ( to change it, use --logfile path ; or use --nolog to turn off logging ) +Load is 0.42 0.32 0.34 2/634 on 2 cores +Current directory is /home/gilles/public_html/imapsync +Real user id is gilles (uid 1000) +Effective user id is gilles (euid 1000) +$RCSfile: imapsync,v $ $Revision: 2.223 $ $Date: 2022/07/03 10:39:30 $ +Command line used, run by /usr/bin/perl: +./imapsync --gmail1 --user1 imapsync.gl2@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl2_gmail --gmail2 --user2 imapsync.gl2@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl2_gmail --no-modulesversion --justfolderlists +Temp directory is /tmp ( to change it use --tmpdir dirpath ) +kill -QUIT 31816 # special behavior: call to sub catch_exit +kill -TERM 31816 # special behavior: call to sub catch_exit +kill -INT 31816 # special behavior: call to sub catch_reconnect +kill -HUP 31816 # special behavior: call to sub catch_print +kill -USR1 31816 # special behavior: call to sub toggle_sleep +File /tmp/imapsync.pid does not exist +PID file is /tmp/imapsync.pid ( to change it, use --pidfile filepath ; to avoid it use --pidfile "" ) +Writing my PID 31816 in /tmp/imapsync.pid +Writing also my logfile name in /tmp/imapsync.pid : LOG_imapsync/2022_07_07_09_53_57_868_imapsync.gl2@gmail.com_imapsync.gl2@gmail.com.txt +Info: will resync flags for already transferred messages. Use --noresyncflags to not resync flags. +SSL debug mode level is --debugssl 1 (can be set from 0 meaning no debug to 4 meaning max debug) +Host1: SSL default mode is like --sslargs1 "SSL_verify_mode=0", meaning for host1 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host1: Use --sslargs1 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host1 +Host2: SSL default mode is like --sslargs2 "SSL_verify_mode=0", meaning for host2 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host2: Use --sslargs2 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host2 +Info: turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1. +Host1: will try to use LOGIN authentication on host1 +Host2: will try to use LOGIN authentication on host2 +Host1: imap connection timeout is 120 seconds +Host2: imap connection timeout is 120 seconds +Host1: imap connection keepalive is on on host1. Use --nokeepalive1 to disable it. +Host2: imap connection keepalive is on on host2. Use --nokeepalive2 to disable it. +Host1: IMAP server [imap.gmail.com] port [993] user [imapsync.gl2@gmail.com] +Host2: IMAP server [imap.gmail.com] port [993] user [imapsync.gl2@gmail.com] +Host1: connecting and login on host1 [imap.gmail.com] port [993] with user [imapsync.gl2@gmail.com] +Host1 IP address: 2a00:1450:400c:c04::6c Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host1 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 f9mb238805277wmg +Host1 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host1: success login on [imap.gmail.com] with user [imapsync.gl2@gmail.com] auth [LOGIN] or [LOGIN] +Host2: connecting and login on host2 [imap.gmail.com] port [993] with user [imapsync.gl2@gmail.com] +Host2 IP address: 2a00:1450:400c:c04::6d Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host2 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 bi26mb169281364wmb +Host2 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host2: success login on [imap.gmail.com] with user [imapsync.gl2@gmail.com] auth [LOGIN] or [LOGIN] +Host1: state Authenticated +Host2: state Authenticated +Host1 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host2 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host1: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host1") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success +Host2: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host2") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success + +Host2: QUOTA capability found, presented in raw IMAP on next lines +Sending: 5 GETQUOTAROOT INBOX +Sent 22 bytes +Read: * QUOTAROOT "INBOX" "" + * QUOTA "" (STORAGE 1177 15728640) + 5 OK Success + +Host2: Quota current storage is 1205248 bytes. Limit is 16106127360 bytes. So 0.01 % full +Host2: found APPENDLIMIT=35651584 in CAPABILITY (use --appendlimit xxxx to override this automatic setting) +Host2: Setting maxsize to appendlimit 35651584 +Host1: Compression is off. Use --compress1 to allow compression on host1 +Host2: Compression is off. Use --compress2 to allow compression on host2 +Host1: found 26 folders. +Host2: found 26 folders. +Host1: guessing separator from folder listing: [/] +Host1: separator given by NAMESPACE: [/] +Host2: guessing separator from folder listing: [/] +Host2: separator given by NAMESPACE: [/] +Host1: guessing prefix from folder listing: [] +Host1: prefix given by NAMESPACE: [] +Host2: guessing prefix from folder listing: [] +Host2: prefix given by NAMESPACE: [] +Host1: separator and prefix: [/][] +Host2: separator and prefix: [/][] +Including all folders found by default. Use --subscribed or --folder or --folderrec or --include to select specific folders. Use --exclude to unselect specific folders. +Excluding folders matching pattern \[Gmail\]$ + +Host1: Checking wanted folders exist. Use --nocheckfoldersexist to avoid this check (shared of public namespace targeted). +Host1: Checking wanted folders are selectable. Use --nocheckselectable to avoid this check. +Turned on automapping folders ( use --noautomap to turn off automapping ) +Host1: special [Gmail]/Brouillons = \Drafts +Host1: special [Gmail]/Corbeille = \Trash +Host1: special [Gmail]/Messages envoy&AOk-s = \Sent +Host1: special [Gmail]/Spam = \Junk +Host1: special [Gmail]/Suivis = \Flagged +Host1: special [Gmail]/Tous les messages = \All + +Host2: special [Gmail]/Brouillons = \Drafts +Host2: special [Gmail]/Corbeille = \Trash +Host2: special [Gmail]/Messages envoy&AOk-s = \Sent +Host2: special [Gmail]/Spam = \Junk +Host2: special [Gmail]/Suivis = \Flagged +Host2: special [Gmail]/Tous les messages = \All + + +++++ Listing folders +All foldernames are presented between brackets like [X] where X is the foldername. +When a foldername contains non-ASCII characters it is presented in the form +[X] = [Y] where +X is the imap foldername you have to use in command line options and +Y is the utf8 output just printed for convenience, to recognize it. + +Host1: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasChildren \Noselect) "/" "Archive" +* LIST (\HasChildren) "/" "Archive/Bob" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blabla" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blan Blan" +* LIST (\HasNoChildren) "/" "Archive/Bob/Coucou" +* LIST (\HasNoChildren) "/" "Archive/Bob/INBOX" +* LIST (\HasNoChildren) "/" "Archive/Bob/Test" +* LIST (\HasNoChildren) "/" "Archive/Bob/Work" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Important" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Inbox" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Starred" +* LIST (\HasNoChildren) "/" "Blabla" +* LIST (\HasNoChildren) "/" "Blan Blan" +* LIST (\HasNoChildren) "/" "Coucou" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasNoChildren) "/" "Test" +* LIST (\HasNoChildren) "/" "Work" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Brouillons" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Corbeille" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Messages envoy&AOk-s" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Suivis" +* LIST (\All \HasNoChildren) "/" "[Gmail]/Tous les messages" +* LIST (\HasNoChildren) "/" "\\Important" +* LIST (\HasNoChildren) "/" "\\Inbox" +* LIST (\HasNoChildren) "/" "\\Starred" +36 OK Success + +[Archive/Bob] +[Archive/Bob/Blabla] +[Archive/Bob/Blan Blan] +[Archive/Bob/Coucou] +[Archive/Bob/INBOX] +[Archive/Bob/Test] +[Archive/Bob/Work] +[Archive/Bob/\Important] +[Archive/Bob/\Inbox] +[Archive/Bob/\Starred] +[Blabla] +[Blan Blan] +[Coucou] +[INBOX] +[Test] +[Work] +[[Gmail]/Brouillons] +[[Gmail]/Corbeille] +[[Gmail]/Important] +[[Gmail]/Messages envoy&AOk-s] = [[Gmail]/Messages envoyés] +[[Gmail]/Spam] +[[Gmail]/Suivis] +[[Gmail]/Tous les messages] +[\Important] +[\Inbox] +[\Starred] + +Host2: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasChildren \Noselect) "/" "Archive" +* LIST (\HasChildren) "/" "Archive/Bob" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blabla" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blan Blan" +* LIST (\HasNoChildren) "/" "Archive/Bob/Coucou" +* LIST (\HasNoChildren) "/" "Archive/Bob/INBOX" +* LIST (\HasNoChildren) "/" "Archive/Bob/Test" +* LIST (\HasNoChildren) "/" "Archive/Bob/Work" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Important" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Inbox" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Starred" +* LIST (\HasNoChildren) "/" "Blabla" +* LIST (\HasNoChildren) "/" "Blan Blan" +* LIST (\HasNoChildren) "/" "Coucou" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasNoChildren) "/" "Test" +* LIST (\HasNoChildren) "/" "Work" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Brouillons" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Corbeille" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Messages envoy&AOk-s" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Suivis" +* LIST (\All \HasNoChildren) "/" "[Gmail]/Tous les messages" +* LIST (\HasNoChildren) "/" "\\Important" +* LIST (\HasNoChildren) "/" "\\Inbox" +* LIST (\HasNoChildren) "/" "\\Starred" +11 OK Success + +[Archive/Bob] +[Archive/Bob/Blabla] +[Archive/Bob/Blan Blan] +[Archive/Bob/Coucou] +[Archive/Bob/INBOX] +[Archive/Bob/Test] +[Archive/Bob/Work] +[Archive/Bob/\Important] +[Archive/Bob/\Inbox] +[Archive/Bob/\Starred] +[Blabla] +[Blan Blan] +[Coucou] +[INBOX] +[Test] +[Work] +[[Gmail]/Brouillons] +[[Gmail]/Corbeille] +[[Gmail]/Important] +[[Gmail]/Messages envoy&AOk-s] = [[Gmail]/Messages envoyés] +[[Gmail]/Spam] +[[Gmail]/Suivis] +[[Gmail]/Tous les messages] +[\Important] +[\Inbox] +[\Starred] + +Folders mapping from --automap feature (use --f1f2 to override any mapping): +[[Gmail]/Spam] -> [[Gmail]/Spam] +[[Gmail]/Tous les messages] -> [[Gmail]/Tous les messages] +[[Gmail]/Corbeille] -> [[Gmail]/Corbeille] +[[Gmail]/Suivis] -> [[Gmail]/Suivis] +[[Gmail]/Messages envoy&AOk-s] = [[Gmail]/Messages envoyés] -> [[Gmail]/Messages envoy&AOk-s] = [[Gmail]/Messages envoyés] +[[Gmail]/Brouillons] -> [[Gmail]/Brouillons] + +Exiting because of --justfolderlists +Exiting with return value 0 (EX_OK: successful termination) 0/50 nb_errors/max_errors PID 31816 +Removing pidfile /tmp/imapsync.pid +Disconnecting from host1 imap.gmail.com user1 imapsync.gl2@gmail.com +Disconnecting from host2 imap.gmail.com user2 imapsync.gl2@gmail.com +Log file is LOG_imapsync/2022_07_07_09_53_57_868_imapsync.gl2@gmail.com_imapsync.gl2@gmail.com.txt ( to change it, use --logfile filepath ; or use --nolog to turn off logging ) +Here is imapsync 2.223 on host petite, a linux system with 0.1/2.0 free GiB of RAM, 109.03% used by processes. +with Perl 5.22.1 and Mail::IMAPClient 3.43 +Transfer started at jeudi 07 juillet 2022-07-07 09:54:09 +0200 CEST +PID is 32065 my PPID is 31540 +Log file is LOG_imapsync/2022_07_07_09_54_09_123_imapsync.gl3@gmail.com_imapsync.gl3@gmail.com.txt ( to change it, use --logfile path ; or use --nolog to turn off logging ) +Load is 0.54 0.36 0.35 3/635 on 2 cores +Current directory is /home/gilles/public_html/imapsync +Real user id is gilles (uid 1000) +Effective user id is gilles (euid 1000) +$RCSfile: imapsync,v $ $Revision: 2.223 $ $Date: 2022/07/03 10:39:30 $ +Command line used, run by /usr/bin/perl: +./imapsync --gmail1 --user1 imapsync.gl3@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl3_gmail --gmail2 --user2 imapsync.gl3@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl3_gmail --no-modulesversion --justfolderlists +Temp directory is /tmp ( to change it use --tmpdir dirpath ) +kill -QUIT 32065 # special behavior: call to sub catch_exit +kill -TERM 32065 # special behavior: call to sub catch_exit +kill -INT 32065 # special behavior: call to sub catch_reconnect +kill -HUP 32065 # special behavior: call to sub catch_print +kill -USR1 32065 # special behavior: call to sub toggle_sleep +File /tmp/imapsync.pid does not exist +PID file is /tmp/imapsync.pid ( to change it, use --pidfile filepath ; to avoid it use --pidfile "" ) +Writing my PID 32065 in /tmp/imapsync.pid +Writing also my logfile name in /tmp/imapsync.pid : LOG_imapsync/2022_07_07_09_54_09_123_imapsync.gl3@gmail.com_imapsync.gl3@gmail.com.txt +Info: will resync flags for already transferred messages. Use --noresyncflags to not resync flags. +SSL debug mode level is --debugssl 1 (can be set from 0 meaning no debug to 4 meaning max debug) +Host1: SSL default mode is like --sslargs1 "SSL_verify_mode=0", meaning for host1 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host1: Use --sslargs1 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host1 +Host2: SSL default mode is like --sslargs2 "SSL_verify_mode=0", meaning for host2 SSL_VERIFY_NONE, ie, do not check the server certificate. +Host2: Use --sslargs2 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host2 +Info: turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1. +Host1: will try to use LOGIN authentication on host1 +Host2: will try to use LOGIN authentication on host2 +Host1: imap connection timeout is 120 seconds +Host2: imap connection timeout is 120 seconds +Host1: imap connection keepalive is on on host1. Use --nokeepalive1 to disable it. +Host2: imap connection keepalive is on on host2. Use --nokeepalive2 to disable it. +Host1: IMAP server [imap.gmail.com] port [993] user [imapsync.gl3@gmail.com] +Host2: IMAP server [imap.gmail.com] port [993] user [imapsync.gl3@gmail.com] +Host1: connecting and login on host1 [imap.gmail.com] port [993] with user [imapsync.gl3@gmail.com] +Host1 IP address: 2a00:1450:400c:c04::6c Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host1 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 o9mb168635237wmr +Host1 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host1: success login on [imap.gmail.com] with user [imapsync.gl3@gmail.com] auth [LOGIN] or [LOGIN] +Host2: connecting and login on host2 [imap.gmail.com] port [993] with user [imapsync.gl3@gmail.com] +Host2 IP address: 2a00:1450:400c:c04::6d Local IP address: 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 +Host2 banner: * OK Gimap ready for requests from 2a01:e34:ecde:70d0:223:54ff:fec2:36d7 l4mb132600559wml +Host2 capability before authentication: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH AUTH +Host2: success login on [imap.gmail.com] with user [imapsync.gl3@gmail.com] auth [LOGIN] or [LOGIN] +Host1: state Authenticated +Host2: state Authenticated +Host1 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host2 capability once authenticated: IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMIT=35651584 COMPRESS UTF8 APPENDLIMIT +Host1: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host1") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success +Host2: found ID capability. Sending/receiving ID, presented in raw IMAP for now. +In order to avoid sending/receiving ID, use option --noid +Sending: 4 ID ("name" "imapsync" "version" "2.223" "os" "linux" "vendor" "Gilles LAMIRAL" "support-url" "https://imapsync.lamiral.info/" "date" "03-Jul-2022 10:39:30 +0000" "side" "host2") +Sent 181 bytes +Read: * ID ("name" "GImap" "vendor" "Google, Inc." "support-url" "https://support.google.com/mail" "version" "gmail_imap_220624.08_p0" "remote-host" "2a01:e34:ecde:70d0:223:54ff:fec2:36d7") + 4 OK Success + +Host2: QUOTA capability found, presented in raw IMAP on next lines +Sending: 5 GETQUOTAROOT INBOX +Sent 22 bytes +Read: * QUOTAROOT "INBOX" "" + * QUOTA "" (STORAGE 443 15728640) + 5 OK Success + +Host2: Quota current storage is 453632 bytes. Limit is 16106127360 bytes. So 0.00 % full +Host2: found APPENDLIMIT=35651584 in CAPABILITY (use --appendlimit xxxx to override this automatic setting) +Host2: Setting maxsize to appendlimit 35651584 +Host1: Compression is off. Use --compress1 to allow compression on host1 +Host2: Compression is off. Use --compress2 to allow compression on host2 +Host1: found 19 folders. +Host2: found 19 folders. +Host1: guessing separator from folder listing: [/] +Host1: separator given by NAMESPACE: [/] +Host2: guessing separator from folder listing: [/] +Host2: separator given by NAMESPACE: [/] +Host1: guessing prefix from folder listing: [] +Host1: prefix given by NAMESPACE: [] +Host2: guessing prefix from folder listing: [] +Host2: prefix given by NAMESPACE: [] +Host1: separator and prefix: [/][] +Host2: separator and prefix: [/][] +Including all folders found by default. Use --subscribed or --folder or --folderrec or --include to select specific folders. Use --exclude to unselect specific folders. +Excluding folders matching pattern \[Gmail\]$ + +Host1: Checking wanted folders exist. Use --nocheckfoldersexist to avoid this check (shared of public namespace targeted). +Host1: Checking wanted folders are selectable. Use --nocheckselectable to avoid this check. +Turned on automapping folders ( use --noautomap to turn off automapping ) +Host1: special [Gmail]/All Mail = \All +Host1: special [Gmail]/Drafts = \Drafts +Host1: special [Gmail]/Sent Mail = \Sent +Host1: special [Gmail]/Spam = \Junk +Host1: special [Gmail]/Starred = \Flagged +Host1: special [Gmail]/Trash = \Trash + +Host2: special [Gmail]/All Mail = \All +Host2: special [Gmail]/Drafts = \Drafts +Host2: special [Gmail]/Sent Mail = \Sent +Host2: special [Gmail]/Spam = \Junk +Host2: special [Gmail]/Starred = \Flagged +Host2: special [Gmail]/Trash = \Trash + + +++++ Listing folders +All foldernames are presented between brackets like [X] where X is the foldername. +When a foldername contains non-ASCII characters it is presented in the form +[X] = [Y] where +X is the imap foldername you have to use in command line options and +Y is the utf8 output just printed for convenience, to recognize it. + +Host1: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasChildren) "/" "Archive" +* LIST (\HasChildren) "/" "Archive/Bob" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blabla" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blan Blan" +* LIST (\HasNoChildren) "/" "Archive/Bob/Coucou" +* LIST (\HasNoChildren) "/" "Archive/Bob/INBOX" +* LIST (\HasNoChildren) "/" "Archive/Bob/Test" +* LIST (\HasNoChildren) "/" "Archive/Bob/Work" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Important" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Inbox" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Starred" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash" +29 OK Success + +[Archive] +[Archive/Bob] +[Archive/Bob/Blabla] +[Archive/Bob/Blan Blan] +[Archive/Bob/Coucou] +[Archive/Bob/INBOX] +[Archive/Bob/Test] +[Archive/Bob/Work] +[Archive/Bob/\Important] +[Archive/Bob/\Inbox] +[Archive/Bob/\Starred] +[INBOX] +[[Gmail]/All Mail] +[[Gmail]/Drafts] +[[Gmail]/Important] +[[Gmail]/Sent Mail] +[[Gmail]/Spam] +[[Gmail]/Starred] +[[Gmail]/Trash] + +Host2: folders list (first the raw imap format then the [X] = [Y]): +* LIST (\HasChildren) "/" "Archive" +* LIST (\HasChildren) "/" "Archive/Bob" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blabla" +* LIST (\HasNoChildren) "/" "Archive/Bob/Blan Blan" +* LIST (\HasNoChildren) "/" "Archive/Bob/Coucou" +* LIST (\HasNoChildren) "/" "Archive/Bob/INBOX" +* LIST (\HasNoChildren) "/" "Archive/Bob/Test" +* LIST (\HasNoChildren) "/" "Archive/Bob/Work" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Important" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Inbox" +* LIST (\HasNoChildren) "/" "Archive/Bob/\\Starred" +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash" +11 OK Success + +[Archive] +[Archive/Bob] +[Archive/Bob/Blabla] +[Archive/Bob/Blan Blan] +[Archive/Bob/Coucou] +[Archive/Bob/INBOX] +[Archive/Bob/Test] +[Archive/Bob/Work] +[Archive/Bob/\Important] +[Archive/Bob/\Inbox] +[Archive/Bob/\Starred] +[INBOX] +[[Gmail]/All Mail] +[[Gmail]/Drafts] +[[Gmail]/Important] +[[Gmail]/Sent Mail] +[[Gmail]/Spam] +[[Gmail]/Starred] +[[Gmail]/Trash] + +Folders mapping from --automap feature (use --f1f2 to override any mapping): +[[Gmail]/Trash] -> [[Gmail]/Trash] +[Archive] -> [Archive] +[[Gmail]/Spam] -> [[Gmail]/Spam] +[[Gmail]/Sent Mail] -> [[Gmail]/Sent Mail] +[[Gmail]/All Mail] -> [[Gmail]/All Mail] +[[Gmail]/Drafts] -> [[Gmail]/Drafts] +[[Gmail]/Starred] -> [[Gmail]/Starred] + +Exiting because of --justfolderlists +Exiting with return value 0 (EX_OK: successful termination) 0/50 nb_errors/max_errors PID 32065 +Removing pidfile /tmp/imapsync.pid +Disconnecting from host1 imap.gmail.com user1 imapsync.gl3@gmail.com +Disconnecting from host2 imap.gmail.com user2 imapsync.gl3@gmail.com +Log file is LOG_imapsync/2022_07_07_09_54_09_123_imapsync.gl3@gmail.com_imapsync.gl3@gmail.com.txt ( to change it, use --logfile filepath ; or use --nolog to turn off logging ) +gmail_glX_all_justfolderlist passed diff --git a/imapsync b/imapsync index 5a646d7..826467c 100755 --- a/imapsync +++ b/imapsync @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# $Id: imapsync,v 2.200 2022/04/04 16:05:55 gilles Exp gilles $ +# $Id: imapsync,v 2.229 2022/09/14 18:08:24 gilles Exp gilles $ # structure # pod documentation # use pragmas @@ -25,7 +25,7 @@ and without duplicates. =head1 VERSION -This documentation refers to Imapsync $Revision: 2.200 $ +This documentation refers to Imapsync $Revision: 2.229 $ =head1 USAGE @@ -253,7 +253,7 @@ Same thing for user2 password. It will be combined with the --user1 value to form the string to pass with XOAUTH2 authentication. The password given by --password1 or --passfile1 - is ignored. + is ignored but needed on the command line. Instead of the access token itself, the value can be a file containing the access token on the first line. If the value is a file, imapsync reads its first line @@ -267,7 +267,8 @@ Same thing for user2 password. --oauthdirect1 str : The direct string to pass with XOAUTH2 authentication. The password given by --password1 or --passfile1 and - the user given by --user1 are ignored. + the user given by --user1 are ignored but they are + needed to be on the command line. Consider it a bug. --oauthdirect2 str : same thing as oauthdirect1 @@ -401,7 +402,7 @@ where: 2019_12_22_23_57_59_532 is nearly the date of the start YYYY_MM_DD_HH_MM_SS_mmm - year_month_day_hour_minute_seconde_millisecond + year_month_day_hour_minute_second_millisecond and user1 user2 are the --user1 --user2 values. @@ -658,7 +659,7 @@ https://imapsync.lamiral.info/FAQ.d/FAQ.Gmail.txt Default is 120 and 0 means no timeout at all. Caveat, under CGI context, you may encounter a timeout - from the webserver, killing imapsync and the imap connexions. + from the webserver, killing imapsync and the imap connections. See the document INSTALL.OnlineUI.txt and search for "Timeout" for how to deal with this issue. @@ -694,6 +695,12 @@ https://imapsync.lamiral.info/FAQ.d/FAQ.Gmail.txt it's an http request to http://imapsync.lamiral.info/prj/imapsync/VERSION + --emailreport1 : Put the email final report in host1 INBOX + --emailreport2 : Put the email final report in host2 INBOX + + --noemailreport1 : Do not put the email final report in host1 INBOX + --noemailreport2 : Do not put the email final report in host2 INBOX + --noid : Do not send/receive IMAP "ID" command to imap servers. --justconnect : Just connect to both servers and print useful @@ -1357,7 +1364,7 @@ my( $SSL_VERIFY_POLICY, ) ; -single_sync( $sync, $acc1, $acc2 ); +exit( single_sync( $sync, $acc1, $acc2 ) ) ; @@ -1386,24 +1393,13 @@ $acc2->{ N } = '2' ; $sync->{timestart} = time ; # Is a float because of use Time::HiRres -$sync->{rcs} = q{$Id: imapsync,v 2.200 2022/04/04 16:05:55 gilles Exp gilles $} ; - -$sync->{ memory_consumption_at_start } = memory_consumption( ) || 0 ; +$sync->{rcs} = q{$Id: imapsync,v 2.229 2022/09/14 18:08:24 gilles Exp gilles $} ; +$sync->{ memory_consumption_at_start } = memory_consumption_of_myself( ) || 0 ; my @loadavg = loadavg( ) ; -$sync->{ cpu_number } = cpu_number( ) ; -$sync->{ loaddelay } = load_and_delay( $sync->{ cpu_number }, @loadavg ) ; -$sync->{ loaddelay } = 0 ; - -$sync->{ loadavg } = join( q{ }, $loadavg[ 0 ] ) - . " on $sync->{cpu_number} cores and " - . ram_memory_info( ) ; - - - $sync->{ total_bytes_transferred } = 0 ; $sync->{ total_bytes_skipped } = 0 ; $sync->{ nb_msg_transferred } = 0 ; @@ -1448,14 +1444,20 @@ $sync->{ biggest_message_transferred } = 0; Dec => '11', ); - - # Just create a CGI object if under cgi context only. # Needed for the get_options() call cgibegin( $sync ) ; # In cgi context, printing must start by the header so we delay other prints by using output() storage my $options_good = get_options( $sync, @ARGV ) ; + +$sync->{ cpu_number } = cpu_number( ) ; +$sync->{ heavy_load_reached } = heavy_load_reached( $sync ) ; + +$sync->{ loadavg } = join( q{ }, $loadavg[ 0 ] ) + . " on $sync->{cpu_number} cores and " + . ram_memory_info( $sync ) ; + # Is it the first myprint? cgibuildheader( $sync ) ; docker_context( $sync ) ; @@ -1472,8 +1474,8 @@ if ( ! defined $options_good ) { exit $EX_USAGE ; } # the second line (ending with "1 ;") can then stay active or be commented, # the result will be the same: no releasecheck by default (because 0 is then the defined value). -$sync->{releasecheck} = defined $sync->{releasecheck} ? $sync->{releasecheck} : 0 ; -#$sync->{releasecheck} = defined $sync->{releasecheck} ? $sync->{releasecheck} : 1 ; +#$sync->{releasecheck} = defined $sync->{releasecheck} ? $sync->{releasecheck} : 0 ; +$sync->{releasecheck} = defined $sync->{releasecheck} ? $sync->{releasecheck} : 1 ; # just the version if ( $sync->{ version } ) { @@ -1534,12 +1536,14 @@ if ( $sync->{ abortbyfile } ) { $sync->{ abort } = 1 ; } install_signals( $sync ) ; +$sync->{ loglogfilename } = '../list_all_logs_auto.txt' ; $sync->{ log } = defined $sync->{ log } ? $sync->{ log } : 1 ; + $sync->{ errorsdump } = defined $sync->{ errorsdump } ? $sync->{ errorsdump } : 1 ; $sync->{ errorsmax } = defined $sync->{ errorsmax } ? $sync->{ errorsmax } : $ERRORS_MAX ; -$sync->{ emailreport1 } = defined $sync->{ emailreport1 } ? $sync->{ emailreport1 } : 1 ; -$sync->{ emailreport2 } = defined $sync->{ emailreport2 } ? $sync->{ emailreport2 } : 1 ; +$sync->{ emailreport1 } = defined $sync->{ emailreport1 } ? $sync->{ emailreport1 } : 0 ; +$sync->{ emailreport2 } = defined $sync->{ emailreport2 } ? $sync->{ emailreport2 } : 0 ; # log and output @@ -1582,7 +1586,7 @@ myprint( "Transfer started at $sync->{ timestart_str }\n" ) ; myprint( "PID is $PROCESS_ID my PPID is ", mygetppid( ), "\n" ) ; announcelogfile( $sync ) ; myprint( "Load is " . ( join( q{ }, loadavg( ) ) || 'unknown' ), " on $sync->{cpu_number} cores\n" ) ; -#myprintf( "Memory consumption so far: %.1f MiB\n", memory_consumption( ) / $KIBI / $KIBI ) ; +#myprintf( "Memory consumption so far: %.1f MiB\n", memory_consumption_of_myself( ) / $KIBI / $KIBI ) ; myprint( 'Current directory is ' . getcwd( ) . "\n" ) ; myprint( 'Real user id is ' . getpwuid_any_os( $REAL_USER_ID ) . " (uid $REAL_USER_ID)\n" ) ; myprint( 'Effective user id is ' . getpwuid_any_os( $EFFECTIVE_USER_ID ). " (euid $EFFECTIVE_USER_ID)\n" ) ; @@ -1662,16 +1666,19 @@ if ( $sync->{ abort } ) exit $EX_OK ; } +if ( $sync->{ memorystress } ) { tests_memory_stress() ; } + + # simulong is just a loop printing some lines for xx seconds with option "--simulong xx". simulong( $sync ) ; -# New place for cgiload 2019_03_03 +# New place for cgi_exit_on_heavy_load 2019_03_03 # because I want to log it # Can break here if load is too heavy -# Have in mind the CGI header has already a 503 Service Unavailable -cgiload( $sync ) ; +# Have in mind the CGI header has already a 503 Service Unavailable printed. +cgi_exit_on_heavy_load( $sync ) ; $fixcolonbug = defined $fixcolonbug ? $fixcolonbug : 1 ; @@ -3030,8 +3037,7 @@ if ( $sync->{ testslive } or $sync->{ testslive6 } ) tests_live_result( $sync->{ nb_errors } ) ; } -$sync->{ emailreport2 } and email_report_append( $sync->{ acc2 }, email_report( $sync, email_report_body_extra2( ) ) ) ; -$sync->{ emailreport1 } and email_report_append( $sync->{ acc1 }, email_report( $sync, email_report_body_extra1( ) ) ) ; +final_emails_reports( $sync ) ; #$sync->{imap1}->State( 0 ); # Unconnected if ( ! lost_connection( $sync, $sync->{imap1}, "for host1 [$sync->{host1}]" ) ) { $sync->{imap1}->logout( ) ; } @@ -3464,7 +3470,7 @@ sub tests_killpid_by_brother sub killpid { - my $pidtokill = shift ; + my $pidtokill = shift @ARG ; if ( ! $pidtokill ) { myprint( "No process to kill.\n" ) ; @@ -3601,7 +3607,7 @@ sub tests_under_docker_context sub under_docker_context { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! defined $mysync ) { return ; } @@ -3625,7 +3631,7 @@ sub under_docker_context sub docker_context { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! under_docker_context( $mysync ) ) { @@ -3659,7 +3665,7 @@ sub docker_context sub cgibegin { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! under_cgi_context( $mysync ) ) { return ; } require CGI ; CGI->import( qw( -no_debug -utf8 ) ) ; @@ -3701,7 +3707,7 @@ sub tests_under_cgi_context sub under_cgi_context { - my $mysync = shift ; + my $mysync = shift @ARG ; # Under cgi context if ( $ENV{SERVER_SOFTWARE} ) { return 1 ; @@ -3712,7 +3718,7 @@ sub under_cgi_context sub cgibuildheader { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! under_cgi_context( $mysync ) ) { return ; } my $imapsync_runs = $mysync->{cgi}->cookie( 'imapsync_runs' ) || 0 ; @@ -3723,23 +3729,28 @@ sub cgibuildheader -path => '/cgi-bin/imapsync', ) ; my $httpheader ; - if ( $mysync->{ abort } ) { + if ( $mysync->{ abort } ) + { $httpheader = $mysync->{cgi}->header( -type => 'text/plain; charset=UTF-8', - -status => '200 OK to abort syncing IMAP boxes' . ". Here is " . hostname(), + -status => '200 OK to abort syncing IMAP boxes. ' . load_message( $mysync ), ) ; - }elsif( $mysync->{ loaddelay } ) { + } + elsif( $mysync->{ heavy_load_reached } ) + { # https://tools.ietf.org/html/rfc2616#section-10.5.4 # 503 Service Unavailable # The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. $httpheader = $mysync->{cgi}->header( -type => 'text/plain; charset=UTF-8', - -status => '503 Service Unavailable' . ". Be back in $mysync->{ loaddelay } min. Load on " . hostname() . " is $mysync->{ loadavg }", + -status => '503 Service Unavailable. ' . "Be back later. " . load_message( $mysync ), ) ; - }else{ + } + else + { $httpheader = $mysync->{cgi}->header( -type => 'text/plain; charset=UTF-8', - -status => '200 OK to sync IMAP boxes' . ". Load on " . hostname() . " is $mysync->{ loadavg }", + -status => '200 OK to sync IMAP boxes. ' . load_message( $mysync ), -cookie => $cookie, ) ; } @@ -3748,22 +3759,193 @@ sub cgibuildheader return ; } -sub cgiload +sub load_message +{ + my $mysync = shift @ARG ; + + my $message = "Load on " . hostname() . " is $mysync->{ loadavg }" ; + return $message ; +} + +sub cgi_exit_on_heavy_load { # Exit on heavy load in CGI context - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! under_cgi_context( $mysync ) ) { return ; } if ( $mysync->{ abort } ) { return ; } # keep going to abort since some ressources will be free soon - if ( $mysync->{ loaddelay } ) + if ( $mysync->{ heavy_load_reached } ) { - $mysync->{nb_errors}++ ; + $mysync->{ nb_errors }++ ; exit_clean( $mysync, $EX_UNAVAILABLE, - "Server is on heavy load. Be back in $mysync->{ loaddelay } min. Load is $mysync->{ loadavg }\n" + "Server is on heavy load. Be back later. " . load_message( $mysync ) . "\n" ) ; } return ; +} + + + +sub tests_heavy_load_reached +{ + note( 'Entering tests_is_heavy_load_reached()' ) ; + + like( heavy_load_reached( ), qr{^(0|1)$}xms, 'heavy_load_reached: no args => 0 or 1' ) ; + + my $mysync = { } ; + like( heavy_load_reached( $mysync ), qr{^(0|1)$}xms, 'heavy_load_reached: { } => 0 or 1' ) ; + + $mysync->{ exitonload } = 0 ; + is( 0, heavy_load_reached( $mysync ), 'heavy_load_reached: exitonload=0 => 0 ' ) ; + + note( 'Leaving tests_heavy_load_reached()' ) ; + return ; } +sub heavy_load_reached +{ + my $mysync = shift @ARG ; + + my $heavy_load_reached = 0 ; + + if ( defined( $mysync->{ exitonload } ) && ( ! $mysync->{ exitonload } ) ) + { + return 0 ; + } + + my $heavy_load_reached_by_memory = heavy_load_reached_by_memory( $mysync ) ; + my $heavy_load_reached_by_cpu = heavy_load_reached_by_cpu( $mysync ) ; + + if ( $heavy_load_reached_by_memory || $heavy_load_reached_by_cpu ) + { + $heavy_load_reached = 1 ; + } + else + { + $heavy_load_reached = 0 ; + } + + return $heavy_load_reached ; +} + + +sub tests_heavy_load_reached_by_cpu +{ + note( 'Entering tests_heavy_load_reached_by_cpu()' ) ; + + note( join( " ", loadavg( ), 'heavy_load_reached_by_cpu ', heavy_load_reached_by_cpu( ) ) ) ; + like( heavy_load_reached_by_cpu( ), qr{^(0|1)$}xms, 'heavy_load_reached_by_cpu: no args => 0 or 1' ) ; + + my $mysync = { } ; + like( heavy_load_reached_by_cpu( $mysync ), qr{^(0|1)$}xms, 'heavy_load_reached_by_cpu: { } => 0 or 1' ) ; + + note( 'Leaving tests_heavy_load_reached_by_cpu()' ) ; + return ; +} + +sub heavy_load_reached_by_cpu +{ + my $mysync = shift @ARG ; + + my $heavy_load_reached = 0 ; + + my $load_and_delay = load_per_cpu( $mysync ) ; + + if ( $load_and_delay ) + { + $heavy_load_reached = 1 ; + } + else + { + $heavy_load_reached = 0 ; + } + + return $heavy_load_reached ; +} + + +sub tests_load_per_cpu +{ + note( 'Entering tests_load_per_cpu()' ) ; + + note( join( " ", 'loadavg:', loadavg( ), 'cpu_number:', cpu_number( ), 'load_per_cpu ', load_per_cpu( ) ) ) ; + like( load_per_cpu( ), qr{^([0-9.]+)$}xms, 'load_per_cpu: no args => number' ) ; + + my $mysync = { } ; + like( load_per_cpu( $mysync ), qr{^([0-9.]+)$}xms, 'load_per_cpu: { } => number' ) ; + + note( 'Leaving tests_load_per_cpu()' ) ; + return ; +} + + +sub load_per_cpu +{ + my $mysync = shift @ARG ; + + return load_and_delay( 1, cpu_number( ), loadavg( ) ) ; +} + +sub tests_heavy_load_reached_by_memory +{ + note( 'Entering tests_heavy_load_reached_by_memory()' ) ; + + like( heavy_load_reached_by_memory( ), qr{^(0|1)$}xms, 'heavy_load_reached_by_memory: no args => 0 or 1' ) ; + + my $mysync = { } ; + like( heavy_load_reached_by_memory( $mysync ), qr{^(0|1)$}xms, 'heavy_load_reached_by_memory: { } => 0 or 1' ) ; + + note( 'Leaving tests_heavy_load_reached_by_memory()' ) ; + return ; +} + + +sub heavy_load_reached_by_memory +{ + my $mysync = shift @ARG ; + + my $heavy_load_reached = 0 ; + + my $heavy_load_percent_threshold = heavy_load_percent_threshold( $mysync ) ; + my $memory_consumption_all_pids_percent = memory_consumption_all_pids_percent( $mysync ) ; + + if ( $memory_consumption_all_pids_percent > $heavy_load_percent_threshold ) + { + $heavy_load_reached = 1 ; + } + else + { + $heavy_load_reached = 0 ; + } + + return $heavy_load_reached ; +} + +sub tests_heavy_load_percent_threshold +{ + note( 'Entering tests_heavy_load_percent_threshold()' ) ; + note( heavy_load_percent_threshold( ) . " (%)" ) ; + like( heavy_load_percent_threshold( ), qr{^\d+$}xms, 'heavy_load_percent_threshold: no args => integer' ) ; + my $mysync = { } ; + like( heavy_load_percent_threshold( ), qr{^\d+$}xms, 'heavy_load_percent_threshold: { } => integer' ) ; + + note( 'Leaving tests_heavy_load_percent_threshold()' ) ; + return ; +} + + +sub heavy_load_percent_threshold +{ + my $mysync = shift @ARG ; + + my $total_memory_bytes = total_ram_memory_bytes( ) || return 0 ; + my $memory_footprint_average_bytes = 250_000_000 ; + my $heavy_load_percent_threshold = max( 0, int( 100 * ( $total_memory_bytes - ( 4 * $memory_footprint_average_bytes ) ) / $total_memory_bytes ) ) ; + + return $heavy_load_percent_threshold ; +} + + + sub tests_set_umask { note( 'Entering tests_set_umask()' ) ; @@ -3784,7 +3966,7 @@ sub tests_set_umask sub set_umask { - my $mysync = shift ; + my $mysync = shift @ARG ; my $previous_umask = umask_str( ) ; my $new_umask = umask_str( $UMASK_PARANO ) ; output( $mysync, "Umask set with $new_umask (was $previous_umask)\n" ) ; @@ -3831,7 +4013,7 @@ sub tests_umask_str sub umask_str { - my $value = shift ; + my $value = shift @ARG ; if ( defined $value ) { umask oct( $value ) ; @@ -3865,25 +4047,19 @@ sub tests_umask return ; } -sub buggyflagsregex -{ - # From /X analyse - # cut -d: -f1 Error_112_all_syncs.txt | xargs egrep -oih 'Invalid system flag [^( ]+' | sort | uniq -c | sort -g - my @buggyflagsregex = ( 's/\\\\RECEIPTCHECKED|\\\\Indexed|\\\\X-EON-HAS-ATTACHMENT|\\\\UNSEEN|\\\\ATTACHED|\\\\X-HAS-ATTACH|\\\\FORWARDED|\\\\FORWARD|\\\\X-FORWARDED|\\\\\$FORWARDED|\\\\PRIORITY|\\\\READRCPT//g' ) ; - return( @buggyflagsregex ) ; -} - sub make_var_array_to_a_hash { my $mysync = shift @ARG ; %{ $mysync->{ varh } } = split_around_equal( @{ $mysync->{ var } } ) ; + + return ; } sub cgisetcontext { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! under_cgi_context( $mysync ) ) { return ; } output( $mysync, "Under cgi context\n" ) ; @@ -3962,6 +4138,10 @@ sub cgisetcontext # log the logfile name by default in cgi context $mysync->{ loglogfile } = defined $mysync->{ loglogfile } ? $mysync->{ loglogfile } : 1 ; + + # exit on heavy load + $mysync->{ exitonload } = defined $mysync->{ exitonload } ? $mysync->{ exitonload } : 1 ; + return ; } @@ -4020,11 +4200,11 @@ sub cgienvcontext my $envval = $ENV{ $envvar } || q{} ; my $varval = $mysync->{ varh }->{ $envvar } ; - if ( $envval and ! $varval ) + if ( $envval and not $varval ) { $output .= "$envvar is $envval\n" ; } - elsif ( ! $envval and $varval ) + elsif ( not $envval and $varval ) { $output .= "$envvar is $varval\n" ; } @@ -4039,7 +4219,7 @@ sub cgienvcontext sub announcelogfile { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( $mysync->{ log } ) { @@ -4054,34 +4234,96 @@ sub announcelogfile } -sub loglogfile + + + + + +sub tests_loglogfile { - my $mysync = shift ; - if ( ! $mysync->{ loglogfile } ) { return ; } - if ( ! $mysync->{ log } ) { return ; } - - my $cwd = getcwd( ) ; - my $absolutelogfilepath ; - # Fixme: add case when the logfile name is already absolute - $absolutelogfilepath = "$cwd/$mysync->{ logfile }" ; - my $loglogfilename = '../list_all_logs_auto.txt' ; - myprint( "Writing log file name $absolutelogfilepath to $loglogfilename\n" ) ; - if ( open( my $fh, '>>', $loglogfilename ) ) - { - print $fh "$absolutelogfilepath\n" ; - close $fh ; - } - else - { - myprint( "Could not open loglogfile $loglogfilename $!\n" ) ; - } + note( 'Entering tests_loglogfile()' ) ; + + is( undef, loglogfile( ), 'loglogfile: no args => undef' ) ; + my $mysync = { } ; + is( undef, loglogfile( $mysync ), 'loglogfile: undef => undef' ) ; + $mysync->{ loglogfile } = 1 ; + $mysync->{ log } = 1 ; + is( undef, loglogfile( $mysync ), 'loglogfile: no logfile => undef' ) ; + $mysync->{ logfile } = "logfile.txt" ; + $mysync->{ loglogfilename } = "W/tmp/tests/list_all_logs_auto.txt" ; + like( loglogfile( $mysync ), qr{logfile.txt}xms, 'loglogfile: logfile=logfile.txt => ' ) ; + note( 'Leaving tests_loglogfile()' ) ; return ; } +sub loglogfile +{ + my $mysync = shift @ARG ; + if ( ! $mysync->{ loglogfile } ) { return ; } + if ( ! $mysync->{ log } ) { return ; } + if ( ! $mysync->{ logfile } ) { return ; } + + my $loglogfilename = $mysync->{ loglogfilename } || return ; + + my $absolutelogfilepath = absolutelogfilepath( $mysync ) ; + + if ( condition_to_loglogfile( $mysync ) ) + { + myprint( "Writing log file name $absolutelogfilepath to $loglogfilename\n" ) ; + append_to_file( $absolutelogfilepath, $loglogfilename ) ; + } + + return $absolutelogfilepath ; +} + +sub condition_to_loglogfile +{ + my $mysync = shift @ARG ; + + if ( defined $mysync->{ cmdcgi } and scalar( @{ $mysync->{ cmdcgi } } ) ) + { + return 1 ; + } + else + { + return 0 ; + } +} + +sub absolutelogfilepath +{ + my $mysync = shift @ARG ; + + # Fixme: add case when the logfile name is already absolute + + my $cwd = getcwd( ) ; + my $absolutelogfilepath = "$cwd/$mysync->{ logfile }" ; + + return $absolutelogfilepath ; +} + + +sub append_to_file +{ + my $string = shift @ARG ; + my $filename = shift @ARG ; + + if ( open( my $fh, '>>', $filename ) ) + { + print $fh "$string\n" ; + close $fh ; + } + else + { + myprint( "Could not append $string to file $filename $!\n" ) ; + } + return ; +} + sub checkselectable { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( $mysync->{ checkselectable } ) { my @h1_folders_wanted_selectable ; @@ -4111,7 +4353,7 @@ sub checkselectable sub setcheckselectable { - my $mysync = shift ; + my $mysync = shift @ARG ; my $h1_folders_wanted_nb = scalar @{ $mysync->{ h1_folders_wanted } } ; # 152 because 98% of host1 accounts have less than 152 folders on /X service. @@ -4268,11 +4510,11 @@ sub foldersizes sub foldersize_diff_present { - my $mysync = shift ; - my $folder1 = shift ; - my $folder2 = shift ; - my $counter_str = shift ; - my $force = shift ; + my $mysync = shift @ARG ; + my $folder1 = shift @ARG ; + my $folder2 = shift @ARG ; + my $counter_str = shift @ARG ; + my $force = shift @ARG ; my $values1_str ; my $values2_str ; @@ -4338,10 +4580,10 @@ sub foldersize_diff_present sub foldersize_diff_compute { - my $mysync = shift ; - my $folder1 = shift ; - my $folder2 = shift ; - my $force = shift ; + my $mysync = shift @ARG ; + my $folder1 = shift @ARG ; + my $folder2 = shift @ARG ; + my $force = shift @ARG ; @@ -4429,8 +4671,8 @@ sub foldersize_diff_compute sub diff { - my $x = shift ; - my $y = shift ; + my $x = shift @ARG ; + my $y = shift @ARG ; $x ||= 0 ; $y ||= 0 ; @@ -4438,15 +4680,40 @@ sub diff return $x - $y ; } +sub tests_add +{ + note( 'Entering tests_add()' ) ; + + is( 0, add( ), 'tests_add: no args => 0' ) ; + is( 0, add( undef ), 'tests_add: undef => 0' ) ; + is( 0, add( 0 ), 'tests_add: 0 => 0' ) ; + is( 0, add( 0, 0 ), 'tests_add: 0 0 => 0' ) ; + is( 0, add( 0, 0, 0 ), 'tests_add: 0 0 0 => 0' ) ; + is( 1, add( 1 ), 'tests_add: 1 => 1' ) ; + is( 2, add( 1, 1 ), 'tests_add: 1 1 => 2' ) ; + is( 3, add( 1, 1, 1 ), 'tests_add: 1 1 1 => 3' ) ; + is( 2, add( 1, undef, 1 ), 'tests_add: 1 undef 1 => 2' ) ; + is( 0, add( -1, 1 ), 'tests_add: -1 1 => 0' ) ; + + is( 2.2, add( 1.1, 1.1 ), 'tests_add: 1.1 1.1 => 2.2' ) ; + + is( 100, add( (1) x 100 ), 'tests_add: 1 1 ... 1 100 times => 100 list' ) ; + my @hundred_ones = (1) x 100 ; + is( 100, add( @hundred_ones ), 'tests_add: 1 1 ... 1 100 times => 100 array' ) ; + + note( 'Leaving tests_add()' ) ; + return ; +} + + sub add { - my $x = shift ; - my $y = shift ; - - $x ||= 0 ; - $y ||= 0 ; - - return $x + $y ; + my $sum = 0 ; + foreach my $number ( @ARG ) + { + $sum += $number || 0 ; + } + return $sum ; } sub tests_checknoabletosearch @@ -4512,8 +4779,8 @@ sub checknoabletosearch sub foldersizes_diff_list { - my $mysync = shift ; - my $force = shift ; + my $mysync = shift @ARG ; + my $force = shift @ARG ; my @folders = @{ $mysync->{h1_folders_wanted} } ; my $nb_folders = scalar @folders ; @@ -4532,7 +4799,7 @@ sub foldersizes_diff_list sub foldersizes_total { - my $mysync = shift ; + my $mysync = shift @ARG ; my @folders_1 = @{ $mysync->{h1_folders_wanted} } ; my @folders_2 = @h2_folders_from_1_wanted ; @@ -4578,7 +4845,7 @@ sub foldersizes_total sub foldersizesatend_old { - my $mysync = shift ; + my $mysync = shift @ARG ; timenext( $mysync ) ; return if ( $mysync->{imap1}->IsUnconnected( ) ) ; return if ( $mysync->{imap2}->IsUnconnected( ) ) ; @@ -4599,7 +4866,7 @@ sub foldersizesatend_old sub foldersizesatend { - my $mysync = shift ; + my $mysync = shift @ARG ; timenext( $mysync ) ; return if ( $mysync->{imap1}->IsUnconnected( ) ) ; return if ( $mysync->{imap2}->IsUnconnected( ) ) ; @@ -4627,7 +4894,7 @@ sub foldersizesatend sub foldersizes_at_the_beggining { - my $mysync = shift ; + my $mysync = shift @ARG ; myprint( << 'END_SIZE' ) ; @@ -4672,7 +4939,7 @@ END_SIZE sub foldersizes_at_the_beggining_old { - my $mysync = shift ; + my $mysync = shift @ARG ; myprint( << 'END_SIZE' ) ; @@ -4736,7 +5003,7 @@ sub tests_total_bytes_max_reached sub total_bytes_max_reached { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! defined $mysync ) { return ; } @@ -4833,7 +5100,7 @@ sub tests_mock_capability sub sig_install_toggle_sleep { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( 'MSWin32' ne $OSNAME ) { #myprint( "sig_install( $mysync, \&toggle_sleep, 'USR1' )\n" ) ; sig_install( $mysync, 'toggle_sleep', 'USR1' ) ; @@ -4845,7 +5112,7 @@ sub sig_install_toggle_sleep sub mock_capability { - my $myimap = shift ; + my $myimap = shift @ARG ; my @has_capability_value = @ARG ; my ( $has_capability_value ) = @has_capability_value ; @@ -4984,7 +5251,7 @@ sub tests_appendlimit_from_capability sub appendlimit_from_capability { - my $myimap = shift ; + my $myimap = shift @ARG ; if ( ! $myimap ) { myprint( "Warn: no imap with call to appendlimit_from_capability\n" ) ; @@ -5239,8 +5506,8 @@ sub tests_hashsynclocal sub hashsynclocal { - my $mysync = shift ; - my $hashkey = shift ; # Optional, only there for tests + my $mysync = shift @ARG ; + my $hashkey = shift @ARG ; # Optional, only there for tests my $hashfile = $mysync->{ hashfile } ; $hashfile = createhashfileifneeded( $hashfile, $hashkey ) ; if ( ! $hashfile ) { @@ -5326,8 +5593,8 @@ sub tests_hashsync sub hashsync { - my $mysync = shift ; - my $hashkey = shift ; + my $mysync = shift @ARG ; + my $hashkey = shift @ARG ; my $mystring = join( q{}, $mysync->{ host1 } || q{}, @@ -5434,7 +5701,7 @@ sub tests_hmac_sha1_hex_robust sub hmac_sha1_hex_robust { - my $string = shift ; + my $string = shift @ARG ; my $val ; if ( defined( $val = eval{ hmac_sha1_hex( $string, @ARG ) } ) ) { @@ -5462,7 +5729,7 @@ sub tests_createhashfileifneeded sub createhashfileifneeded { - my $hashfile = shift ; + my $hashfile = shift @ARG ; my $hashkey = shift || rand32( ) ; # no name @@ -5517,7 +5784,7 @@ sub rand32 sub imap_id_stuff { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( not $mysync->{id} ) { return ; } ; @@ -5558,8 +5825,8 @@ sub imap_id sub imapsync_id { - my $mysync = shift ; - my $overhashref = shift ; + my $mysync = shift @ARG ; + my $overhashref = shift @ARG ; # See http://tools.ietf.org/html/rfc2971.html my $imapsync_id = { } ; @@ -5571,7 +5838,7 @@ sub imapsync_id vendor => 'Gilles LAMIRAL', 'support-url' => 'https://imapsync.lamiral.info/', # Example of date-time: 19-Sep-2015 08:56:07 - date => date_from_rcs( q{$Date: 2022/04/04 16:05:55 $ } ), + date => date_from_rcs( q{$Date: 2022/09/14 18:08:24 $ } ), } ; my $imapsync_id_github = { @@ -5580,7 +5847,7 @@ sub imapsync_id os => $OSNAME, vendor => 'github', 'support-url' => 'https://github.com/imapsync/imapsync', - date => date_from_rcs( q{$Date: 2022/04/04 16:05:55 $ } ), + date => date_from_rcs( q{$Date: 2022/09/14 18:08:24 $ } ), } ; $imapsync_id = $imapsync_id_lamiral ; @@ -5614,7 +5881,7 @@ sub tests_imapsync_id sub format_for_imap_arg { - my $ref = shift ; + my $ref = shift @ARG ; my $string = q{} ; my %terms = %{ $ref } ; @@ -5699,19 +5966,25 @@ sub tests_quota_extract_storage_limit_in_bytes '* QUOTA "Messages quota" (MESSAGE 2 100000)', '5 OK Getquotaroot completed.' ] ; - ok( $NUMBER_104_857_600 * $KIBI == quota_extract_storage_limit_in_bytes( $mysync, $imap_output ), 'quota_extract_storage_limit_in_bytes ') ; - + is( $NUMBER_104_857_600 * $KIBI, quota_extract_storage_limit_in_bytes( $mysync, $imap_output ), 'quota_extract_storage_limit_in_bytes (STORAGE 1 104857600) => 104857600 * 1024') ; + $imap_output = [ + '* QUOTAROOT "INBOX" "Storage quota" "Messages quota"', + 'QUOTA "user-defined quota (konsoleH)" (STORAGE 988 48829 MESSAGE 20 20)', + '5 OK Getquotaroot completed.' + ] ; + is( 48829 * 1024, quota_extract_storage_limit_in_bytes( $mysync, $imap_output ), 'quota_extract_storage_limit_in_bytes (STORAGE 988 48829 MESSAGE 20 20) => 48829 * 1024') ; + note( 'Leaving tests_quota_extract_storage_limit_in_bytes()' ) ; return ; } sub quota_extract_storage_limit_in_bytes { - my $mysync = shift ; - my $imap_output = shift ; + my $mysync = shift @ARG ; + my $imap_output = shift @ARG ; my $limit_kb ; - $limit_kb = ( map { /.*\(\s*STORAGE\s+\d+\s+(\d+)\s*\)/x ? $1 : () } @{ $imap_output } )[0] ; + $limit_kb = ( map { /STORAGE\s+\d+\s+(\d+)/x ? $1 : () } @{ $imap_output } )[0] ; $limit_kb ||= 0 ; $mysync->{ debug } and myprint( "storage_limit_kb = $limit_kb\n" ) ; return( $KIBI * $limit_kb ) ; @@ -5729,19 +6002,27 @@ sub tests_quota_extract_storage_current_in_bytes '* QUOTA "Messages quota" (MESSAGE 2 100000)', '5 OK Getquotaroot completed.' ] ; - ok( 1*$KIBI == quota_extract_storage_current_in_bytes( $mysync, $imap_output ), 'quota_extract_storage_current_in_bytes: 1 => 1024 ') ; + is( 1*$KIBI, quota_extract_storage_current_in_bytes( $mysync, $imap_output ), 'quota_extract_storage_current_in_bytes: 1 => 1024 ') ; - note( 'Leaving tests_quota_extract_storage_current_in_bytes()' ) ; + $imap_output = [ + '* QUOTAROOT "INBOX" "Storage quota" "Messages quota"', + 'QUOTA "user-defined quota (konsoleH)" (STORAGE 988 48829 MESSAGE 20 20)', + '5 OK Getquotaroot completed.' + ] ; + is( 988 * 1024, quota_extract_storage_current_in_bytes( $mysync, $imap_output ), 'quota_extract_storage_current_in_bytes (STORAGE 988 48829 MESSAGE 20 20) => 988 * 1024') ; + + + note( 'Leaving tests_quota_extract_storage_current_in_bytes()' ) ; return ; } sub quota_extract_storage_current_in_bytes { - my $mysync = shift ; - my $imap_output = shift ; + my $mysync = shift @ARG ; + my $imap_output = shift @ARG ; my $current_kb ; - $current_kb = ( map { /.*\(\s*STORAGE\s+(\d+)\s+\d+\s*\)/x ? $1 : () } @{ $imap_output } )[0] ; + $current_kb = ( map { /STORAGE\s+(\d+)\s+\d+/x ? $1 : () } @{ $imap_output } )[0] ; $current_kb ||= 0 ; $mysync->{ debug } and myprint( "storage_current_kb = $current_kb\n" ) ; return( $KIBI * $current_kb ) ; @@ -5754,6 +6035,8 @@ sub make_f1f2_array_to_a_hash { my $mysync = shift @ARG ; %{ $mysync->{ f1f2h } } = split_around_equal( @{ $mysync->{ f1f2 } } ) ; + + return ; } @@ -5784,7 +6067,7 @@ sub automap sub build_guess_special { - my ( $mysync ) = shift ; + my ( $mysync ) = shift @ARG ; foreach my $h1_fold ( sort keys %{ $mysync->{h1_folders_all} } ) { my $special = guess_special( $h1_fold, $mysync->{possible_special}, $mysync->{h1_prefix} ) ; @@ -5844,7 +6127,7 @@ sub tests_guess_special sub build_automap { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ debug } and myprint( "Entering build_automap\n" ) ; foreach my $h1_fold ( @{ $mysync->{h1_folders_wanted} } ) { my $h2_fold ; @@ -5896,7 +6179,7 @@ sub build_automap # because it works well without sub build_possible_special { - my $mysync = shift ; + my $mysync = shift @ARG ; my $possible_special = { } ; # All|Archive|Drafts|Flagged|Junk|Sent|Trash @@ -6145,7 +6428,7 @@ sub tests_error_type sub error_type { - my $error = shift ; + my $error = shift @ARG ; if ( ! defined $error ) { return 'ERR_NOTHING_REPORTED' ; } if ( ! $error ) { return 'ERR_NOTHING_REPORTED' ; } @@ -6273,7 +6556,7 @@ sub tests_most_common_error sub most_common_error { - my $errors_counted_ref = shift ; + my $errors_counted_ref = shift @ARG ; if ( ! defined $errors_counted_ref ) { return 'ERR_NOTHING_REPORTED' ; } @@ -6371,7 +6654,7 @@ sub errorsdump sub errors_listing { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ most_common_error } = errorsanalyse( errors_log( $mysync ) ) ; my $errors_listing = '' ; @@ -6441,7 +6724,7 @@ sub tests_live_result { note( 'Entering tests_live_result()' ) ; - my $nb_errors = shift ; + my $nb_errors = shift @ARG ; if ( $nb_errors ) { myprint( "Live tests failed with $nb_errors errors\n" ) ; } else { @@ -6454,8 +6737,8 @@ sub tests_live_result sub size_filtered_flag { - my $mysync = shift ; - my $h1_size = shift ; + my $mysync = shift @ARG ; + my $h1_size = shift @ARG ; if ( defined $mysync->{ maxsize } and $h1_size >= $mysync->{ maxsize } ) { return( 1 ) ; @@ -6542,7 +6825,7 @@ sub sync_flags sub _filter { - my $mysync = shift ; + my $mysync = shift @ARG ; my $str = shift or return q{} ; my $sz = $SIZE_MAX_STR ; my $len = length $str ; @@ -6580,7 +6863,7 @@ sub lost_connection sub imap_last_error { - my $imap = shift ; + my $imap = shift @ARG ; my $einfo = $imap->LastError || @{$imap->History}[$LAST] || q{} ; chomp( $einfo ) ; return( $einfo ) ; @@ -6679,7 +6962,7 @@ sub tests_is_number sub is_number { - my $item = shift ; + my $item = shift @ARG ; if ( ! defined $item ) { return ; } @@ -6749,7 +7032,7 @@ sub min sub check_lib_version { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ debug } and myprint( "IMAPClient $Mail::IMAPClient::VERSION\n" ) ; if ( '2.2.9' eq $Mail::IMAPClient::VERSION ) { myprint( "imapsync no longer supports Mail::IMAPClient 2.2.9, upgrade it\n" ) ; @@ -6919,7 +7202,7 @@ sub get_stdin_masked sub ask_for_password_new { - my $prompt = shift ; + my $prompt = shift @ARG ; my $password = get_stdin_masked( $prompt ) ; return $password ; } @@ -6928,7 +7211,7 @@ sub ask_for_password_new sub ask_for_password { - my $prompt = shift ; + my $prompt = shift @ARG ; myprint( $prompt ) ; Term::ReadKey::ReadMode( 2 ) ; ## no critic (InputOutput::ProhibitExplicitStdin) @@ -6944,7 +7227,7 @@ sub ask_for_password sub get_password1 { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ password1 } || $mysync->{ passfile1 } @@ -6986,7 +7269,7 @@ FIN_PASSFILE sub get_password2 { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{password2} || $mysync->{ passfile2 } @@ -7047,7 +7330,7 @@ sub remove_tmp_files sub cleanup_before_exit { - my $mysync = shift ; + my $mysync = shift @ARG ; remove_tmp_files( $mysync ) ; @@ -7140,8 +7423,8 @@ sub exit_clean sub missing_option { - my $mysync = shift ; - my $option = shift ; + my $mysync = shift @ARG ; + my $option = shift @ARG ; $mysync->{nb_errors}++ ; exit_clean( $mysync, $EX_USAGE, "$option option is mandatory, for help run $PROGRAM_NAME --help\n" ) ; return ; @@ -7150,11 +7433,11 @@ sub missing_option sub catch_ignore { - my $mysync = shift ; - my $signame = shift ; + my $mysync = shift @ARG ; + my $signame = shift @ARG ; my $sigcounter = ++$mysync->{ sigcounter }{ $signame } ; - myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", getppid( ), + myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", mygetppid( ), "). Received $sigcounter $signame signals so far. Thanks!\n" ) ; do_and_print_stats( $mysync ) ; return ; @@ -7164,15 +7447,15 @@ sub catch_ignore sub catch_exit { - my $mysync = shift ; + my $mysync = shift @ARG ; my $signame = shift || q{} ; if ( $signame ) { - myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", getppid( ), + myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", mygetppid( ), "). Asked to terminate\n" ) ; if ( $mysync->{can_do_stats} ) { do_and_print_stats( $mysync ) ; myprint( "Ended by a signal $signame (my PID is $PROCESS_ID my PPID is ", - getppid( ), "). I am asked to terminate immediately.\n" ) ; + mygetppid( ), "). I am asked to terminate immediately.\n" ) ; } myprint( "You should resynchronize those accounts by running a sync again,\n", "since some messages and entire folders might still be missing on host2.\n" @@ -7205,18 +7488,18 @@ sub catch_exit sub catch_print { - my $mysync = shift ; - my $signame = shift ; + my $mysync = shift @ARG ; + my $signame = shift @ARG ; my $sigcounter = ++$mysync->{ sigcounter }{ $signame } ; - myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", getppid( ), + myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", mygetppid( ), "). Received $sigcounter $signame signals so far. Thanks!\n" ) ; return ; } sub here_twice { - my $mysync = shift ; + my $mysync = shift @ARG ; my $now = time ; my $previous = $mysync->{lastcatch} || 0 ; $mysync->{lastcatch} = $now ; @@ -7231,13 +7514,13 @@ sub here_twice sub catch_reconnect { - my $mysync = shift ; - my $signame = shift ; + my $mysync = shift @ARG ; + my $signame = shift @ARG ; if ( here_twice( $mysync ) ) { myprint( "Got two signals $signame within $INTERVAL_TO_EXIT seconds. Exiting...\n" ) ; catch_exit( $mysync, $signame ) ; }else{ - myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", getppid( ), ")\n", + myprint( "\nGot a signal $signame (my PID is $PROCESS_ID my PPID is ", mygetppid( ), ")\n", "Hit 2 ctr-c within 2 seconds to exit the program\n", "Hit only 1 ctr-c to reconnect to both imap servers\n", ) ; @@ -7277,7 +7560,7 @@ sub catch_reconnect sub install_signals { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( under_docker_context( $mysync ) ) { @@ -7330,7 +7613,7 @@ sub tests_reconnect_12_if_needed sub reconnect_12_if_needed { - my $mysync = shift ; + my $mysync = shift @ARG ; #return 2 ; if ( ! reconnect_if_needed( $mysync->{imap1} ) ) { return ; @@ -7369,7 +7652,7 @@ sub reconnect_if_needed # return undef upon failure. # return 1 upon connection success, with or without reconnection. - my $imap = shift ; + my $imap = shift @ARG ; if ( ! defined $imap ) { return ; } if ( ! $imap->Server( ) ) { return ; } @@ -7398,7 +7681,7 @@ sub reconnect_if_needed sub justconnect { - my $mysync = shift ; + my $mysync = shift @ARG ; my $justconnect1 = justconnect1( $sync ) ; my $justconnect2 = justconnect2( $sync ) ; return "$justconnect1 $justconnect2"; @@ -7406,7 +7689,7 @@ sub justconnect sub justconnect1 { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( $mysync->{host1} ) { myprint( "Host1: Will just connect to $mysync->{host1} without login\n" ) ; @@ -7425,7 +7708,7 @@ sub justconnect1 sub justconnect2 { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( $mysync->{host2} ) { myprint( "Host2: Will just connect to $mysync->{host2} without login\n" ) ; @@ -7681,7 +7964,7 @@ sub tests_probe_imapssl sub probe_imapssl { - my $host = shift ; + my $host = shift @ARG ; if ( ! $host ) { return ; } $sync->{ debug } and $IO::Socket::SSL::DEBUG = 4 ; @@ -7863,7 +8146,7 @@ sub tests_compress sub acc_compress_imap { - my $acc = shift ; + my $acc = shift @ARG ; if ( ! defined( $acc ) ) { return ; } @@ -7915,7 +8198,7 @@ sub tests_login_imap # certificate has expired # Fix: ssh root@test1.lamiral.info 'apt update && apt upgrade && /etc/init.d/dovecot restart' # - # or + # or this one: # echo | openssl s_client -crlf -connect test1.lamiral.info:993 # ... # Verify return code: 9 (certificate is not yet valid) @@ -8713,7 +8996,7 @@ sub xmasterauth # This code comes from # https://github.com/imapsync/imapsync/pull/53/files - my $imap = shift ; + my $imap = shift @ARG ; my $user = $imap->User( ) ; my $password = $imap->Password( ) ; @@ -8759,7 +9042,7 @@ sub xmasterauth sub keepalive1 { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ acc1 }->{ keepalive } = defined $mysync->{ acc1 }->{ keepalive } ? $mysync->{ acc1 }->{ keepalive } : 1 ; @@ -8771,11 +9054,13 @@ sub keepalive1 { myprint( "Host1: imap connection keepalive is off on host1. Use --keepalive1 to enable it.\n" ) ; } + + return ; } sub keepalive2 { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ acc2 }->{ keepalive } = defined $mysync->{ acc2 }->{ keepalive } ? $mysync->{ acc2 }->{ keepalive } : 1 ; @@ -8787,6 +9072,8 @@ sub keepalive2 { myprint( "Host2: imap connection keepalive is off on host2. Use --keepalive2 to enable it.\n" ) ; } + + return ; } @@ -8798,8 +9085,8 @@ sub banner_imapsync my $banner_imapsync = join q{}, q{$RCSfile: imapsync,v $ }, - q{$Revision: 2.200 $ }, - q{$Date: 2022/04/04 16:05:55 $ }, + q{$Revision: 2.229 $ }, + q{$Date: 2022/09/14 18:08:24 $ }, "\n", "Command line used, run by $EXECUTABLE_NAME:\n", "$PROGRAM_NAME ", command_line_nopassword( $mysync, @argv ), "\n" ; @@ -9009,7 +9296,7 @@ sub tail # return undef on failures # return 1 on success - my $mysync = shift ; + my $mysync = shift @ARG ; # no tail when aborting! if ( $mysync->{ abort } ) { return ; } @@ -9066,8 +9353,8 @@ sub tail sub isrunning { - my $pidtocheck = shift ; - my $moretimes_ref = shift ; + my $pidtocheck = shift @ARG ; + my $moretimes_ref = shift @ARG ; if ( kill 'ZERO', $pidtocheck ) { @@ -9285,7 +9572,7 @@ sub tests_jux_utf8_old sub jux_utf8_old { # juxtapose utf8 at the right if different - my ( $s_utf7 ) = shift ; + my ( $s_utf7 ) = shift @ARG ; my ( $s_utf8 ) = imap_utf7_decode_old( $s_utf7 ) ; if ( $s_utf7 eq $s_utf8 ) { @@ -9302,7 +9589,7 @@ sub jux_utf8_old # https://rt.cpan.org/Public/Bug/Display.html?id=11172 sub imap_utf7_decode_old { - my ( $s ) = shift ; + my ( $s ) = shift @ARG ; # Algorithm # On remplace , par / dans les BASE 64 (, entre & et -) @@ -9359,7 +9646,7 @@ sub jux_utf8 { #use utf8 ; # juxtapose utf8 at the right if different - my ( $s_utf7 ) = shift ; + my ( $s_utf7 ) = shift @ARG ; my ( $s_utf8 ) = imap_utf7_decode( $s_utf7 ) ; if ( $s_utf7 eq $s_utf8 ) { @@ -9374,14 +9661,14 @@ sub jux_utf8 sub imap_utf7_decode { #use utf8 ; - my ( $s ) = shift ; + my ( $s ) = shift @ARG ; return( Encode::IMAPUTF7::decode("IMAP-UTF-7", $s ) ) ; } sub imap_utf7_encode { #use utf8 ; - my ( $s ) = shift ; + my ( $s ) = shift @ARG ; return( Encode::IMAPUTF7::encode("IMAP-UTF-7", $s ) ) ; } @@ -9981,7 +10268,7 @@ sub help_to_guess_prefix sub folders_list_to_help { - my( $imap ) = shift ; + my( $imap ) = shift @ARG ; my @folders = $imap->folders ; my $listing = join q{}, map { "[$_]\n" } @folders ; @@ -10009,7 +10296,7 @@ sub private_folders_separators_and_prefixes sub subfolder1 { - my $mysync = shift ; + my $mysync = shift @ARG ; my $subfolder1 = sanitize_subfolder( $mysync->{ subfolder1 } ) ; if ( $subfolder1 ) @@ -10035,7 +10322,7 @@ sub subfolder1 sub subfolder2 { - my $mysync = shift ; + my $mysync = shift @ARG ; my $subfolder2 = sanitize_subfolder( $mysync->{ subfolder2 } ) ; if ( $subfolder2 ) { @@ -10073,7 +10360,7 @@ sub tests_sanitize_subfolder sub sanitize_subfolder { - my $subfolder = shift ; + my $subfolder = shift @ARG ; if ( ! $subfolder ) { @@ -10115,7 +10402,7 @@ sub tests_sanitize_host sub sanitize_host { - my $host = shift ; + my $host = shift @ARG ; if ( ! defined $host ) { return ; } $host =~ tr{ /}{}d ; @@ -10154,7 +10441,7 @@ sub tests_add_subfolder1_to_folderrec sub add_subfolder1_to_folderrec { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync || ! $mysync->{ subfolder1 } ) { return ; @@ -10182,7 +10469,7 @@ sub add_subfolder1_to_folderrec sub set_regextrans2_for_subfolder2 { - my $mysync = shift ; + my $mysync = shift @ARG ; unshift @{ $mysync->{ regextrans2 } }, @@ -10393,8 +10680,8 @@ EOS sub imap2_folder_name { - my $mysync = shift ; - my ( $h1_fold ) = shift ; + my $mysync = shift @ARG ; + my ( $h1_fold ) = shift @ARG ; my ( $h2_fold ) ; if ( $mysync->{f1f2h}{ $h1_fold } ) { $h2_fold = $mysync->{f1f2h}{ $h1_fold } ; @@ -10447,8 +10734,8 @@ sub tests_remove_last_char_if_is sub remove_last_char_if_is { - my $string = shift ; - my $char = shift ; + my $string = shift @ARG ; + my $char = shift @ARG ; if ( ! defined $string ) { @@ -10527,8 +10814,8 @@ sub tests_prefix_seperator_invertion sub prefix_seperator_invertion { - my $mysync = shift ; - my $h1_fold = shift ; + my $mysync = shift @ARG ; + my $h1_fold = shift @ARG ; my $h2_fold ; if ( not defined $h1_fold ) { return ; } @@ -10633,7 +10920,7 @@ sub tests_decompose_regex sub decompose_regex { - my $regex = shift ; + my $regex = shift @ARG ; my( $left_part, $right_part ) ; ( $left_part, $right_part ) = $regex =~ m{^s/((?:[^/]|\\/)+)/((?:[^/]|\\/)+)/}x; @@ -10662,7 +10949,7 @@ sub tests_timenext sub timenext { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! defined $mysync ) { @@ -10698,7 +10985,7 @@ sub timesince my ( $timenow, $timediff ) ; $timenow = time ; $timediff = $timenow - $timeinit ; - # Often used in a division so no 0 but a nano seconde. + # Often used in a division so no 0 but a nano second. return( max( $timediff, min( 1e-09, $timediff ) ) ) ; } @@ -10801,20 +11088,6 @@ sub tests_regexflags #regexflags( '\Deleted Flagged \Answered \Flagged \Draft \Flagged' ), # 'regexflags: remove \Flagged 3 mistery...' ) ; - $mysync->{ regexflag } = [ ] ; - $mysync->{ filterbuggyflags } = 1 ; - filterbuggyflags( $mysync ) ; - - is( '\Deleted \Answered \Draft \Flagged', - regexflags( $mysync, '\\Deleted \\Answered \\RECEIPTCHECKED \\Draft \\Indexed \\Flagged' ), - 'regexflags: remove famous /X 1' ) ; - - is( '\\Deleted \\Flagged \\Answered \\Draft', - regexflags( $mysync, '\\Deleted \\RECEIPTCHECKED \\Flagged \\Answered \\Indexed \\Draft' ), - 'regexflags: remove famous /X 2' ) ; - - is( '\ ', '\\ ', 'regexflags: \ is \\ ' ) ; - is( '\\ ', '\\ ', 'regexflags: \\ is \\ ' ) ; is( '\\ \ ', '\ \\ ', 'regexflags: \\ \ is \ \\ ' ) ; note( 'Leaving tests_regexflags()' ) ; return ; @@ -10822,8 +11095,8 @@ sub tests_regexflags sub regexflags { - my $mysync = shift ; - my $flags = shift ; + my $mysync = shift @ARG ; + my $flags = shift @ARG ; foreach my $regexflag ( @{ $mysync->{ regexflag } } ) { @@ -10839,10 +11112,48 @@ sub regexflags return( $flags ) ; } +sub tests_filterbuggyflags +{ + note( 'Entering tests_regexflags()' ) ; + + my $mysync = {} ; + + + $mysync->{ regexflag } = [ ] ; + $mysync->{ filterbuggyflags } = 1 ; + filterbuggyflags( $mysync ) ; + + # + is( '\Deleted \Answered \Draft \Flagged ', + regexflags( $mysync, '\\Deleted \\Answered \\RECEIPTCHECKED \\Draft \\Indexed \\Flagged \\JUNK \\Junk' ), + 'regexflags: remove famous /X 1' ) ; + + is( '\\Deleted \\Flagged \\Answered \\Draft', + regexflags( $mysync, '\\Deleted \\RECEIPTCHECKED \\Flagged \\Answered \\Indexed \\Draft' ), + 'regexflags: remove famous /X 2' ) ; + + is( '\ ', '\\ ', 'regexflags: \ is \\ ' ) ; + is( '\\ ', '\\ ', 'regexflags: \\ is \\ ' ) ; + + + note( 'Leaving tests_regexflags()' ) ; + return ; + + +} + +sub buggyflagsregex +{ + # From /X analyse + # cut -d: -f1 Error_112_all_syncs.txt | xargs egrep -oih 'Invalid system flag [^( ]+' | sort | uniq -c | sort -g + my @buggyflagsregex = ( 's/\\\\RECEIPTCHECKED|\\\\JUNK|\\\\Indexed|\\\\X-EON-HAS-ATTACHMENT|\\\\UNSEEN|\\\\ATTACHED|\\\\X-HAS-ATTACH|\\\\FORWARDED|\\\\FORWARD|\\\\X-FORWARDED|\\\\\$FORWARDED|\\\\PRIORITY|\\\\READRCPT//gi' ) ; + return( @buggyflagsregex ) ; +} + sub filterbuggyflags { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( $mysync->{ filterbuggyflags } ) { unshift @{ $mysync->{ regexflag } }, buggyflagsregex( ) ; @@ -10883,7 +11194,7 @@ sub tests_remove_doublequotes_if_any sub remove_doublequotes_if_any { - my $string = shift ; + my $string = shift @ARG ; if ( ! defined $string ) { return ; } $string =~ s/\\\"//g ; @@ -10959,11 +11270,11 @@ sub tests_permanentflags sub permanentflags { - my $mysync = shift ; + my $mysync = shift @ARG ; - my @lines = @_ ; + my @lines = @ARG ; - foreach my $line (@lines) { + foreach my $line ( @lines ) { if ( $line =~ m{\[PERMANENTFLAGS\s\(([^)]+?)\)\]}x ) { ( $mysync->{ debugflags } or $mysync->{ debug } ) and myprint( "permanentflags: $line" ) ; my $permanentflags = $1 ; @@ -11026,7 +11337,7 @@ sub tests_flagscase sub flagscase { - my $flags = shift ; + my $flags = shift @ARG ; my @flags = split /\s+/x, $flags ; my %rfc_flags = map { $_ => 1 } split q{ }, '\Answered \Flagged \Deleted \Seen \Draft' ; @@ -11084,9 +11395,9 @@ sub tests_flags_for_host2 sub flags_for_host2 { - my $mysync = shift ; - my $h1_flags = shift ; - my $permanentflags2 = shift ; + my $mysync = shift @ARG ; + my $h1_flags = shift @ARG ; + my $permanentflags2 = shift @ARG ; if ( ! all_defined( $mysync, $h1_flags ) ) { return ; } ; @@ -11115,7 +11426,7 @@ sub flags_for_host2 sub ucsecond { - my $string = shift ; + my $string = shift @ARG ; my $output ; return( $string ) if ( 1 >= length $string ) ; @@ -11352,9 +11663,9 @@ sub info_date_from_uid sub lastuid { - my $imap = shift ; - my $folder = shift ; - my $lastuid_guess = shift ; + my $imap = shift @ARG ; + my $folder = shift @ARG ; + my $lastuid_guess = shift @ARG ; my $lastuid ; # rfc3501: The only reliable way to identify recent messages is to @@ -11418,8 +11729,8 @@ sub message_exists # $mysync->{ h1_nb_msg_processed } sub stats_update_skip_message { - my $mysync = shift ; # to be used - my $h1_size = shift ; + my $mysync = shift @ARG ; # to be used + my $h1_size = shift @ARG ; $mysync->{ total_bytes_skipped } += $h1_size ; $mysync->{ nb_msg_skipped } += 1 ; @@ -11717,8 +12028,8 @@ sub tests_truncmess sub truncmess { - my $string = shift ; - my $length = shift ; + my $string = shift @ARG ; + my $length = shift @ARG ; if ( not defined $string ) { return ; } if ( not defined $length ) { return $string ; } @@ -11843,8 +12154,8 @@ sub tests_labels_remove_subfolder1 sub labels_remove_subfolder1 { - my $labels = shift ; - my $subfolder1 = shift ; + my $labels = shift @ARG ; + my $subfolder1 = shift @ARG ; if ( not defined $labels ) { return ; } if ( not defined $subfolder1 ) { return $labels ; } @@ -11908,7 +12219,7 @@ sub tests_labels_remove_special sub labels_remove_special { - my $labels = shift ; + my $labels = shift @ARG ; if ( not defined $labels ) { return ; } @@ -11981,8 +12292,8 @@ sub tests_labels_add_subfolder2 sub labels_add_subfolder2 { - my $labels = shift ; - my $subfolder2 = shift ; + my $labels = shift @ARG ; + my $subfolder2 = shift @ARG ; my $h1_folder = shift || q{} ; if ( not defined $labels ) { return ; } @@ -12285,7 +12596,7 @@ sub uniq sub length_ref { - my $string_ref = shift ; + my $string_ref = shift @ARG ; my $string_len = defined ${ $string_ref } ? length( ${ $string_ref } ) : q{} ; # length or empty string return $string_len ; } @@ -12333,7 +12644,7 @@ sub date_for_host2 sub subject { - my $string = shift ; + my $string = shift @ARG ; my $subject = q{} ; my $header = extract_header( $string ) ; @@ -12512,7 +12823,7 @@ sub tests_sleep_if_needed sub sleep_if_needed { - my( $mysync ) = shift ; + my( $mysync ) = shift @ARG ; if ( ! $mysync ) { return ; @@ -12744,8 +13055,8 @@ sub tests_uidexpunge_or_expunge sub uidexpunge_or_expunge { - my $mysync = shift ; - my $imap = shift ; + my $mysync = shift @ARG ; + my $imap = shift @ARG ; my @messages = @ARG ; if ( ! $imap ) { return ; } ; @@ -12767,7 +13078,7 @@ sub uidexpunge_or_expunge sub eta_print { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( my $eta = eta( $mysync ) ) { myprint( "$eta\n" ) ; @@ -12807,7 +13118,7 @@ sub tests_eta sub eta { - my( $mysync ) = shift ; + my( $mysync ) = shift @ARG ; if ( ! $mysync ) { @@ -12990,7 +13301,7 @@ sub tests_cache_map sub cache_dir_fix { - my $cache_dir = shift ; + my $cache_dir = shift @ARG ; $cache_dir =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\\])/\\$1/xg ; #myprint( "cache_dir_fix: $cache_dir\n" ) ; return( $cache_dir ) ; @@ -13016,7 +13327,7 @@ sub tests_cache_dir_fix sub cache_dir_fix_win { - my $cache_dir = shift ; + my $cache_dir = shift @ARG ; $cache_dir =~ s/(\[|\])/[$1]/xg ; #myprint( "cache_dir_fix_win: $cache_dir\n" ) ; return( $cache_dir ) ; @@ -13163,7 +13474,7 @@ sub tests_get_cache sub match_a_cache_file { - my $file = shift ; + my $file = shift @ARG ; my ( $cache_uid1, $cache_uid2 ) ; return( ( undef, undef ) ) if ( ! $file ) ; @@ -13464,7 +13775,7 @@ sub tests_tmpdir_has_colon_bug sub tmpdir_has_colon_bug { - my $path = shift ; + my $path = shift @ARG ; my $path_filtered = filter_forbidden_characters( $path ) ; if ( $path_filtered ne $path ) { @@ -13476,7 +13787,7 @@ sub tmpdir_has_colon_bug sub tmpdir_fix_colon_bug { - my $mysync = shift ; + my $mysync = shift @ARG ; my $err = 0 ; if ( not (-d $mysync->{ tmpdir } and -r _ and -w _) ) { myprint( "tmpdir $mysync->{ tmpdir } is not valid\n" ) ; @@ -13591,7 +13902,7 @@ sub tests_filter_forbidden_characters sub filter_forbidden_characters { - my $string = shift ; + my $string = shift @ARG ; if ( ! defined $string ) { return ; } @@ -14940,7 +15251,7 @@ sub tests_useheader_suggestion sub useheader_suggestion { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! defined $mysync->{ h1_nb_msg_noheader } ) { return ; @@ -14958,7 +15269,7 @@ sub useheader_suggestion sub do_and_print_stats { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync->{can_do_stats} ) { return ; @@ -14973,7 +15284,7 @@ sub do_and_print_stats my $cpu_percent = cpu_percent( $mysync, $cpu_time, $timediff ) ; my $cpu_percent_global = cpu_percent_global( $mysync, $cpu_percent ) ; - my $memory_consumption_at_end = memory_consumption( ) || 0 ; + my $memory_consumption_at_end = memory_consumption_of_myself( ) || 0 ; my $memory_consumption_at_start = $mysync->{ memory_consumption_at_start } || 0 ; my $memory_ratio = ( $mysync->{ biggest_message_transferred } ) ? mysprintf( '%.1f', $memory_consumption_at_end / $mysync->{ biggest_message_transferred } ) : 'NA' ; @@ -15010,9 +15321,12 @@ sub do_and_print_stats myprintf("Average bandwidth rate : %.1f KiB/s\n", $mysync->{total_bytes_transferred} / $KIBI / $timediff ) ; myprint( "Reconnections to host1 : $mysync->{imap1}->{IMAPSYNC_RECONNECT_COUNT}\n" ) ; myprint( "Reconnections to host2 : $mysync->{imap2}->{IMAPSYNC_RECONNECT_COUNT}\n" ) ; - myprintf("Memory consumption at the end : %.1f MiB (started with %.1f MiB)\n", + + myprintf("Memory consumption at the end : %.1f MiB (*time %.1f MiB*h) (started with %.1f MiB)\n", $memory_consumption_at_end / $KIBI / $KIBI, + memory_consumption_surface( $mysync, $memory_consumption_at_end, $timediff ), $memory_consumption_at_start / $KIBI / $KIBI ) ; + myprint( "Load end is : " . ( join( q{ }, loadavg( ) ) || 'unknown' ), " on $mysync->{cpu_number} cores\n" ) ; myprint( "CPU time and %cpu : $cpu_time sec $cpu_percent %cpu $cpu_percent_global %allcpus\n" ) ; myprintf("Biggest message transferred : %s bytes (%s)\n", @@ -15047,6 +15361,36 @@ sub do_and_print_stats } + +sub tests_memory_consumption_surface +{ + note( 'Entering tests_memory_consumption_surface()' ) ; + + is( undef, memory_consumption_surface( ), 'memory_consumption_surface: no args => undef' ) ; + my $mysync = { } ; + is( undef, memory_consumption_surface( $mysync ), 'memory_consumption_surface: { } => undef' ) ; + is( "1.0", memory_consumption_surface( $mysync, 1_048_576, 3600 ), 'memory_consumption_surface: 1 MB 1 hour => 1' ) ; + is( "238.4", memory_consumption_surface( $mysync, 500_000_000, 1800 ), 'memory_consumption_surface: 500 MB 30 min => 238' ) ; + + + note( 'Leaving tests_memory_consumption_surface()' ) ; + return ; +} + +sub memory_consumption_surface +{ + my ( $mysync, $memory_consumption_at_end, $timediff ) = @ARG ; + + if ( ! all_defined( $mysync, $memory_consumption_at_end, $timediff ) ) { return } ; + + my $memory_consumption_surface = sprintf( "%.1f", $timediff * $memory_consumption_at_end / $KIBI / $KIBI / 3600 ) ; + + return $memory_consumption_surface ; +} + + + + sub tests_email_report_message_id { note( 'Entering tests_email_report_message_id()' ) ; @@ -15379,8 +15723,8 @@ sub email_report sub email_report_append { - my $acc = shift ; - my $text = shift ; + my $acc = shift @ARG ; + my $text = shift @ARG ; if ( $acc->{ imap }->IsAuthenticated && $text ) { @@ -15401,6 +15745,32 @@ sub email_report_append } } + +sub final_emails_reports +{ + my $mysync = shift @ARG ; + + if ( condition_to_put_final_emails_reports( $mysync ) ) + { + $mysync->{ emailreport2 } and email_report_append( $mysync->{ acc2 }, email_report( $mysync, email_report_body_extra2( ) ) ) ; + $mysync->{ emailreport1 } and email_report_append( $mysync->{ acc1 }, email_report( $mysync, email_report_body_extra1( ) ) ) ; + } + + return ; +} + + +sub condition_to_put_final_emails_reports +{ + my $mysync = shift @ARG ; + + if ( $mysync->{ dry } ) { return 0 ; } + if ( $mysync->{ justfolders } ) { return 0 ; } + + return 1 ; +} + + sub diff_or_NA { my( $n1, $n2 ) = @ARG ; @@ -15736,7 +16106,7 @@ sub firstline # extract the first line of a file (without \n) # return empty string if error or empty string - my $file = shift ; + my $file = shift @ARG ; my $line ; $line = nthline( $file, 1 ) ; @@ -15768,7 +16138,7 @@ sub secondline # extract the second line of a file (without \n) # return empty string if error or empty string - my $file = shift ; + my $file = shift @ARG ; my $line ; $line = nthline( $file, 2 ) ; @@ -15800,8 +16170,8 @@ sub nthline # extract the nth line of a file (without \n) # return empty string if error or empty string - my $file = shift ; - my $num = shift ; + my $file = shift @ARG ; + my $num = shift @ARG ; if ( ! all_defined( $file, $num ) ) { return q{} ; } @@ -15838,7 +16208,7 @@ sub tests_file_to_array sub file_to_array { - my( $file ) = shift ; + my( $file ) = shift @ARG ; if ( ! $file ) { return ; } if ( ! -e $file ) { return ; } if ( ! -f $file ) { return ; } @@ -15883,7 +16253,7 @@ sub tests_file_to_string sub file_to_string { - my $file = shift ; + my $file = shift @ARG ; if ( ! $file ) { return ; } if ( ! -e $file ) { return ; } if ( ! -f $file ) { return ; } @@ -16108,7 +16478,7 @@ sub tests_is_a_release_number sub is_a_release_number { - my $number = shift ; + my $number = shift @ARG ; if ( ! defined $number ) { return ; } return( $number =~ m{^\d+\.\d+$}xo ) ; } @@ -16147,7 +16517,7 @@ sub not_long_imapsync_version_public { #myprint( "Entering not_long_imapsync_version_public\n" ) ; - my $fake = shift ; + my $fake = shift @ARG ; if ( $fake ) { return $fake } my $val ; @@ -16204,7 +16574,7 @@ sub tests_not_long_imapsync_version_public sub check_last_release { - my $fake = shift ; + my $fake = shift @ARG ; my $public_release = not_long_imapsync_version_public( $fake ) ; $sync->{ debug } and myprint( "check_last_release: [$public_release]\n" ) ; my $inline_help_when_on = '( Use --noreleasecheck to avoid this release check. )' ; @@ -16263,7 +16633,7 @@ sub tests_imapsync_context sub imapsync_context { - my $mysync = shift ; + my $mysync = shift @ARG ; my $context = q{} ; @@ -16290,7 +16660,7 @@ sub imapsync_context sub imapsync_version { - my $mysync = shift ; + my $mysync = shift @ARG ; my $rcs = $mysync->{rcs} ; my $version ; @@ -16315,7 +16685,7 @@ sub tests_version_from_rcs sub version_from_rcs { - my $rcs = shift ; + my $rcs = shift @ARG ; if ( ! $rcs ) { return ; } my $version = 'UNKNOWN' ; @@ -16349,12 +16719,12 @@ sub imapsync_basename sub localhost_info { - my $mysync = shift ; + my $mysync = shift @ARG ; my( $infos ) = join( q{}, "Here is imapsync ", imapsync_version( $mysync ), " on host " . hostname(), ", a $OSNAME system with ", - ram_memory_info( ), + ram_memory_info( $mysync ), "\n", 'with Perl ', mysprintf( '%vd ', $PERL_VERSION), @@ -16390,6 +16760,7 @@ sub tests_cpu_number skip( 'cpu_number on host != petite (Linux)', 1 ) ; } is( 2, cpu_number( ), "cpu_number: on petite (Linux) => 2" ) ; + #is( 1, cpu_number( ), "cpu_number: on petite (Linux) => 2" ) ; } ; SKIP: { @@ -16424,7 +16795,7 @@ sub tests_cpu_number sub cpu_number { - my $cpu_number_forced = shift ; + my $cpu_number_forced = shift @ARG ; # Well, here 1 is better than 0 or undef my $cpu_number = 1 ; # Default value, erased if better found @@ -16481,7 +16852,7 @@ sub tests_integer_or_1 sub integer_or_1 { - my $number = shift ; + my $number = shift @ARG ; if ( is_integer( $number ) ) { return $number ; } @@ -16510,7 +16881,7 @@ sub tests_is_integer sub is_integer { - my $number = shift ; + my $number = shift @ARG ; if ( ! defined $number ) { return ; } return( $number =~ m{^\d+$}xo ) ; } @@ -16575,7 +16946,7 @@ sub loadavg sub loadavg_linux { - my $line = shift ; + my $line = shift @ARG ; if ( ! $line ) { $line = firstline( '/proc/loadavg' ) or return ; @@ -16591,14 +16962,14 @@ sub loadavg_linux sub loadavg_freebsd { - my $file = shift ; + my $file = shift @ARG ; # Example of output of command "sysctl vm.loadavg": # vm.loadavg: { 0.15 0.08 0.08 } my $loadavg ; if ( ! defined $file ) { eval { - $loadavg = `/sbin/sysctl vm.loadavg` ; + $loadavg = `LANG=C /sbin/sysctl vm.loadavg` ; #myprint( "LOADAVG FREEBSD: $loadavg\n" ) ; } ; if ( $EVAL_ERROR ) { myprint( "[$EVAL_ERROR]\n" ) ; return ; } @@ -16614,7 +16985,7 @@ sub loadavg_freebsd sub loadavg_darwin { - my $line = shift ; + my $line = shift @ARG ; # Example of output of command "sysctl vm.loadavg": # vm.loadavg: { 0.15 0.08 0.08 } my $loadavg ; @@ -16622,7 +16993,7 @@ sub loadavg_darwin if ( ! defined $line ) { eval { # $loadavg = `/usr/sbin/sysctl vm.loadavg` ; - $loadavg = `LANG= /usr/sbin/sysctl vm.loadavg` ; + $loadavg = `LANG=C /usr/sbin/sysctl vm.loadavg` ; #myprint( "LOADAVG DARWIN: $loadavg\n" ) ; } ; if ( $EVAL_ERROR ) { myprint( "[$EVAL_ERROR]\n" ) ; return ; } @@ -16638,7 +17009,7 @@ sub loadavg_darwin sub loadavg_windows { - my $file = shift ; + my $file = shift @ARG ; # Example of output of command "wmic cpu get loadpercentage": # LoadPercentage # 12 @@ -16668,69 +17039,94 @@ sub loadavg_windows -sub tests_load_and_delay +sub tests_load_and_delay { note( 'Entering tests_load_and_delay()' ) ; - is( undef, load_and_delay( ), 'load_and_delay: no args => undef ' ) ; - is( undef, load_and_delay( 1 ), 'load_and_delay: not 4 args => undef ' ) ; - is( undef, load_and_delay( 0, 1, 1, 1 ), 'load_and_delay: division per 0 => undef ' ) ; + is( undef, load_and_delay( ), 'load_and_delay: no args => undef ' ) ; + is( undef, load_and_delay( 1, 2 ), 'load_and_delay: not 3 args => undef ' ) ; + is( undef, load_and_delay( 2, 0, 1, 1, 1 ), 'load_and_delay: division per 0 => undef ' ) ; -# ( $cpu_num, $avg_1_min, $avg_5_min, $avg_15_min ) +# ( $max_load_per_core, $cpu_num, $avg_1_min, $avg_5_min, $avg_15_min ) - is( 0, load_and_delay( 1, 1, 1, 1 ), 'load_and_delay: one core, loads are all 1 => ok ' ) ; - is( 0, load_and_delay( 1, 1, 1, 1, 'lalala' ), 'load_and_delay: five arguments is ok' ) ; - is( 0, load_and_delay( 2, 2, 2, 2 ), 'load_and_delay: two core, loads are all 2 => ok ' ) ; - is( 0, load_and_delay( 2, 2, 4, 5 ), 'load_and_delay: two core, load1m is 2 => ok ' ) ; + # load max = 1 per cpu + is( 0, load_and_delay( 1, 1, 0 ), 'load_and_delay: max=1, one core, loads is 0 => ok ' ) ; + is( 0, load_and_delay( 1, 1, 0, 0, 0 ), 'load_and_delay: max=1, one core, loads are all 0 => ok ' ) ; + is( 0, load_and_delay( 3, 1, 1, 1, 1, 1 ), 'load_and_delay: six arguments => ok' ) ; + is( 0, load_and_delay( 1, 2, 1, 1, 1 ), 'load_and_delay: max=1, two core, loads are all 1 => ok ' ) ; + is( 0, load_and_delay( 1, 2, 1, 4, 5 ), 'load_and_delay: max=1, two core, load1m is 1 => ok ' ) ; + is( 0, load_and_delay( 1, 1, 0, 0, 0 ), 'load_and_delay: max=1, one core, load1m=0 load5m=0 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, 0, 0, 2 ), 'load_and_delay: max=1, one core, load1m=0 load5m=0 load15m=2 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, 0, 2, 0 ), 'load_and_delay: max=1, one core, load1m=0 load5m=2 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, 0, 2, 2 ), 'load_and_delay: max=1, one core, load1m=0 load5m=2 load15m=2 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, 0, 3, 3 ), 'load_and_delay: max=1, one core, load1m=0 load5m=3 load15m=3 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, 0, 4, 4 ), 'load_and_delay: max=1, one core, load1m=0 load5m=3 load15m=3 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, .2, 0, 0 ), 'load_and_delay: max=1, one core, load1m=.2 load5m=0 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, .2, 0, .2 ), 'load_and_delay: max=1, one core, load1m=.2 load5m=0 load15m=.2 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, .2, .2, 0 ), 'load_and_delay: max=1, one core, load1m=2 load5m=2 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 1, 1, .2, .2, .2 ), 'load_and_delay: max=1, one core, load1m=.2 load5m=.2 load15m=.2 => 0 ' ) ; + is( 1, load_and_delay( 1, 1, 1, 0, 0 ), 'load_and_delay: max=1, one core, load1m=3 load5m=0 load15m=0 => 0 ' ) ; + is( 1, load_and_delay( 1, 1, 1, .9, .9 ), 'load_and_delay: max=1, one core, load1m=3 load5m=.9 load15m=.9 => 0 ' ) ; + is( 5, load_and_delay( 1, 1, 1, 1, .9 ), 'load_and_delay: max=1, one core, load1m=3 load5m=3 load15m=.9 => 5 ' ) ; + is( 15, load_and_delay( 1, 1, 1, 1, 1 ), 'load_and_delay: max=1, one core, load1m=3 load5m=3 load15m=3 => 15 ' ) ; + is( 0, load_and_delay( 1, 1, .9, .9, .9 ), 'load_and_delay: max=1, one core, load1m=.9 load5m=.9 load15m=.9 => 0 ' ) ; + + # load max = 3 per cpu + is( 0, load_and_delay( 3, 1, 1, 1, 1 ), 'load_and_delay: max=3, one core, loads are all 1 => ok ' ) ; + is( 0, load_and_delay( 3, 2, 2, 2, 2 ), 'load_and_delay: max=3, two core, loads are all 2 => ok ' ) ; + is( 0, load_and_delay( 3, 2, 2, 4, 5 ), 'load_and_delay: max=3, two core, load1m is 2 => ok ' ) ; + is( 0, load_and_delay( 3, 1, 0, 0, 0 ), 'load_and_delay: max=3, one core, load1m=0 load5m=0 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 0, 0, 2 ), 'load_and_delay: max=3, one core, load1m=0 load5m=0 load15m=2 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 0, 2, 0 ), 'load_and_delay: max=3, one core, load1m=0 load5m=2 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 0, 2, 2 ), 'load_and_delay: max=3, one core, load1m=0 load5m=2 load15m=2 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 0, 3, 3 ), 'load_and_delay: max=3, one core, load1m=0 load5m=3 load15m=3 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 0, 4, 4 ), 'load_and_delay: max=3, one core, load1m=0 load5m=3 load15m=3 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 2, 0, 0 ), 'load_and_delay: max=3, one core, load1m=2 load5m=0 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 2, 0, 2 ), 'load_and_delay: max=3, one core, load1m=2 load5m=0 load15m=2 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 2, 2, 0 ), 'load_and_delay: max=3, one core, load1m=2 load5m=2 load15m=0 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 2, 2, 2 ), 'load_and_delay: max=3, one core, load1m=2 load5m=2 load15m=2 => 0 ' ) ; + is( 1, load_and_delay( 3, 1, 3, 0, 0 ), 'load_and_delay: max=3, one core, load1m=3 load5m=0 load15m=0 => 0 ' ) ; + is( 1, load_and_delay( 3, 1, 3, 2.9, 2.9 ), 'load_and_delay: max=3, one core, load1m=3 load5m=2.9 load15m=2.9 => 0 ' ) ; + is( 5, load_and_delay( 3, 1, 3, 3, 2.9 ), 'load_and_delay: max=3, one core, load1m=3 load5m=3 load15m=2.9 => 0 ' ) ; + is( 15, load_and_delay( 3, 1, 3, 3, 3 ), 'load_and_delay: max=3, one core, load1m=3 load5m=3 load15m=3 => 0 ' ) ; + is( 0, load_and_delay( 3, 1, 2.9, 2.9, 2.9 ), 'load_and_delay: max=3, one core, load1m=2.9 load5m=2.9 load15m=2.9 => 0 ' ) ; - is( 0, load_and_delay( 1, 0, 0, 0 ), 'load_and_delay: one core, load1m=0 load5m=0 load15m=0 => 0 ' ) ; - is( 0, load_and_delay( 1, 0, 0, 2 ), 'load_and_delay: one core, load1m=0 load5m=0 load15m=2 => 0 ' ) ; - is( 0, load_and_delay( 1, 0, 2, 0 ), 'load_and_delay: one core, load1m=0 load5m=2 load15m=0 => 0 ' ) ; - is( 0, load_and_delay( 1, 0, 2, 2 ), 'load_and_delay: one core, load1m=0 load5m=2 load15m=2 => 0 ' ) ; - is( 0, load_and_delay( 1, 0, 3, 3 ), 'load_and_delay: one core, load1m=0 load5m=3 load15m=3 => 0 ' ) ; - is( 0, load_and_delay( 1, 0, 4, 4 ), 'load_and_delay: one core, load1m=0 load5m=3 load15m=3 => 0 ' ) ; - is( 0, load_and_delay( 1, 2, 0, 0 ), 'load_and_delay: one core, load1m=2 load5m=0 load15m=0 => 0 ' ) ; - is( 0, load_and_delay( 1, 2, 0, 2 ), 'load_and_delay: one core, load1m=2 load5m=0 load15m=2 => 0 ' ) ; - is( 0, load_and_delay( 1, 2, 2, 0 ), 'load_and_delay: one core, load1m=2 load5m=2 load15m=0 => 0 ' ) ; - is( 0, load_and_delay( 1, 2, 2, 2 ), 'load_and_delay: one core, load1m=2 load5m=2 load15m=2 => 0 ' ) ; - is( 0, load_and_delay( 1, 2.9, 2.9, 2.9 ), 'load_and_delay: one core, load1m=2.9 load5m=2.9 load15m=2.9 => 0 ' ) ; - - is( 0, load_and_delay( 1, 3, 0, 0 ), 'load_and_delay: one core, load1m=3 load5m=0 load15m=0 => 0 ' ) ; - is( 0, load_and_delay( 1, 3, 2.9, 2.9 ), 'load_and_delay: one core, load1m=3 load5m=2.9 load15m=2.9 => 0 ' ) ; - is( 0, load_and_delay( 1, 3, 3, 2.9 ), 'load_and_delay: one core, load1m=3 load5m=3 load15m=2.9 => 0 ' ) ; - is( 0, load_and_delay( 1, 3, 3, 3 ), 'load_and_delay: one core, load1m=3 load5m=3 load15m=3 => 0 ' ) ; - - is( 1, load_and_delay( 1, 6, 0, 0 ), 'load_and_delay: one core, load1m=3 load5m=0 load15m=0 => 1 ' ) ; - is( 1, load_and_delay( 1, 6, 5.9, 5.9 ), 'load_and_delay: one core, load1m=3 load5m=2.9 load15m=2.9 => 1 ' ) ; - is( 5, load_and_delay( 1, 6, 6, 5.9 ), 'load_and_delay: one core, load1m=3 load5m=3 load15m=2.9 => 5 ' ) ; - is( 15, load_and_delay( 1, 6, 6, 6 ), 'load_and_delay: one core, load1m=3 load5m=3 load15m=3 => 15 ' ) ; - + is( 1, load_and_delay( 6, 1, 6, 0, 0 ), 'load_and_delay: max=6, one core, load1m=6 load5m=0 load15m=0 => 1 ' ) ; + is( 1, load_and_delay( 6, 1, 6, 5.9, 5.9 ), 'load_and_delay: max=6, one core, load1m=6 load5m=5.9 load15m=5.9 => 1 ' ) ; + is( 5, load_and_delay( 6, 1, 6, 6, 5.9 ), 'load_and_delay: max=6, one core, load1m=6 load5m=6 load15m=5.9 => 5 ' ) ; + is( 15, load_and_delay( 6, 1, 6, 6, 6 ), 'load_and_delay: max=6, one core, load1m=6 load5m=6 load15m=6 => 15 ' ) ; + is( 0, load_and_delay( 6, 1, 5.9, 5.9, 5.9 ), 'load_and_delay: max=6, one core, load1m=5.9 load5m=5.9 load15m=5.9 => 1 ' ) ; note( 'Leaving tests_load_and_delay()' ) ; return ; -} +} -sub load_and_delay +sub load_and_delay { - # Basically return 0 if load is not heavy, ie <= 1 per processor + # Basically return 0 if load is not heavy, ie load 1 min <= $max_load_per_core - # Not enough arguments - if ( 4 > scalar @ARG ) { return ; } + # 5 arguments at least (loadavg return 4 arguments like "0.19 0.16 0.17 3/444" ) + if ( 3 > scalar @ARG ) { return ; } - my ( $cpu_num, $avg_1_min, $avg_5_min, $avg_15_min ) = @ARG ; + my ( $max_load_per_core, $cpu_num, $avg_1_min, $avg_5_min, $avg_15_min ) = @ARG ; if ( 0 == $cpu_num ) { return ; } + # No avg_5_min nor avg_15_min on Windows + $avg_5_min ||= 0 ; + $avg_15_min ||= 0 ; + # Let divide by number of cores ( $avg_1_min, $avg_5_min, $avg_15_min ) = map { $_ / $cpu_num } ( $avg_1_min, $avg_5_min, $avg_15_min ) ; - # One of avg ok => ok, for now it is a OR - if ( $avg_1_min < 6 ) { return 0 ; } - if ( $avg_5_min < 6 ) { return 1 ; } # Retry in 1 minute - if ( $avg_15_min < 6 ) { return 5 ; } # Retry in 5 minutes - return 15 ; # Retry in 15 minutes -} + + # If one period 1m is ok => ok ( 0 ) else Nok ( return > 0, 1 or 5 or 15 ) + if ( $avg_1_min < $max_load_per_core ) { return 0 ; } + if ( $avg_5_min < $max_load_per_core ) { return 1 ; } # Message: retry in 1 minute + if ( $avg_15_min < $max_load_per_core ) { return 5 ; } # Message: retry in 5 minutes + return 15 ; # Message: retry in 15 minutes +} sub tests_cpu_time @@ -16749,7 +17145,7 @@ sub tests_cpu_time sub cpu_time { - my $mysync = shift ; + my $mysync = shift @ARG ; my @cpu_times = times ; if ( ! @cpu_times ) { return ; } @@ -16782,7 +17178,7 @@ sub tests_cpu_percent sub cpu_percent { - my $mysync = shift ; + my $mysync = shift @ARG ; my $cpu_time = shift || 0 ; my $timediff = shift || 1 ; # no division by 0 @@ -16798,7 +17194,7 @@ sub cpu_percent } -sub tests_cpu_percent_global +sub tests_cpu_percent_global { note( 'Entering tests_cpu_percent_global()' ) ; @@ -16822,15 +17218,16 @@ sub tests_cpu_percent_global skip( 'cpu_percent_global on host != petite', 1 ) ; } is( '50.0', cpu_percent_global( $mysync, 100 ), 'cpu_percent_global: {} 100 => 50 on host petite' ) ; + #is( '100.0', cpu_percent_global( $mysync, 100 ), 'cpu_percent_global: {} 100 => 100 on host petite' ) ; } ; note( 'Leaving tests_cpu_percent_global()' ) ; return ; -} +} sub cpu_percent_global { - my $mysync = shift ; + my $mysync = shift @ARG ; my $cpu_percent = shift || 0 ; my $cpu_number = cpu_number( ) ; @@ -16843,16 +17240,78 @@ sub cpu_percent_global } +sub tests_ram_memory_info +{ + note( 'Entering tests_ram_memory_info()' ) ; + + note( "ram_memory_info:", ram_memory_info( ) ) ; + note( "total_ram_memory_bytes_sys_meminfo:", total_ram_memory_bytes_sys_meminfo( ) ) ; + #note( "total_ram_memory_bytes_hw_memsize:", total_ram_memory_bytes_hw_memsize( ) ) ; + + ok( ram_memory_info( ), 'ram_memory_info: => some text' ) ; + + note( 'Leaving tests_ram_memory_info()' ) ; + return ; +} + + +sub total_ram_memory_bytes +{ + my $total_ram_memory_bytes ; + + # Found Sys::MemInfo::get( "totalmem" ) + # wrong on macOS 11.5.2 (20G95) + # good on Mac OS X 10.7.5 (11G63) + # ( commands "sw_vers" or "system_profiler SPSoftwareDataType" ) + + if ( 'darwin' eq $OSNAME ) + { + $total_ram_memory_bytes = total_ram_memory_bytes_hw_memsize( ) ; + } + else + { + $total_ram_memory_bytes = total_ram_memory_bytes_sys_meminfo( ) ; + } +} + + + +sub total_ram_memory_bytes_hw_memsize +{ + my $total_ram_memory_bytes = `sysctl -n hw.memsize` ; + chomp $total_ram_memory_bytes ; + return $total_ram_memory_bytes ; +} + + +sub total_ram_memory_bytes_sys_meminfo +{ + my $total_ram_memory_bytes = Sys::MemInfo::get( "totalmem" ) ; + return $total_ram_memory_bytes ; +} + + + + sub ram_memory_info { + my $mysync = shift @ARG ; # In GigaBytes so division by 1024 * 1024 * 1024 # - return( - sprintf( "%.1f/%.1f free GiB of RAM", + + my $ram_memory_info = sprintf( + "%.1f/%.1f free GiB of RAM", Sys::MemInfo::get("freemem") / ( $KIBI ** 3 ), - Sys::MemInfo::get("totalmem") / ( $KIBI ** 3 ), - ) - ) ; + total_ram_memory_bytes( ) / ( $KIBI ** 3 ), + ) ; + + my $memory_consumption_all_pids_percent = memory_consumption_all_pids_percent( $mysync ) || 0 ; + if ( $memory_consumption_all_pids_percent ) + { + $ram_memory_info .= ", $memory_consumption_all_pids_percent% used by processes." + } + + return $ram_memory_info ; } @@ -16860,7 +17319,8 @@ sub ram_memory_info sub tests_memory_stress { note( 'Entering tests_memory_stress()' ) ; - + my $mysync = { } ; + sig_install( $mysync, 'catch_ignore', ( 'QUIT', 'TERM', 'INT' ) ) ; is( undef, memory_stress( ), 'memory_stress: => undef' ) ; note( 'Leaving tests_memory_stress()' ) ; @@ -16869,34 +17329,35 @@ sub tests_memory_stress sub memory_stress { - my $total_ram_in_MB = Sys::MemInfo::get("totalmem") / ( $KIBI * $KIBI ) ; + my $total_ram_in_MB = total_ram_memory_bytes( ) / ( $KIBI * $KIBI ) ; my $i = 1 ; - myprintf("Stress memory consumption before: %.1f MiB\n", memory_consumption( ) / $KIBI / $KIBI ) ; - while ( $i < $total_ram_in_MB / 1.7 ) { $a .= "A" x 1000_000; $i++ } ; - myprintf("Stress memory consumption after: %.1f MiB\n", memory_consumption( ) / $KIBI / $KIBI ) ; + myprintf("Stress memory consumption before: %.1f MiB of %.1f MiB\n", memory_consumption_of_myself( ) / $KIBI / $KIBI, $total_ram_in_MB ) ; + while ( $i < $total_ram_in_MB / 1.7 ) + { + $a .= "A" x 1000_000; + myprintf( "$i " ) ; + $i++ ; + } ; + myprintf( "\nStress memory consumption after: %.1f MiB of %.1f MiB\n", memory_consumption_of_myself( ) / $KIBI / $KIBI, $total_ram_in_MB ) ; return ; } -sub tests_memory_consumption +sub tests_memory_consumption_of_myself { - note( 'Entering tests_memory_consumption()' ) ; + note( 'Entering tests_memory_consumption_of_myself()' ) ; - note( "memory_consumption: " . memory_consumption() . " bytes aka " . bytes_display_string_dec( memory_consumption() ) ) ; - like( memory_consumption( ), qr{\d+}xms,'memory_consumption no args') ; - like( memory_consumption( 1 ), qr{\d+}xms,'memory_consumption 1') ; - like( memory_consumption( $PROCESS_ID ), qr{\d+}xms,"memory_consumption_of_pids $PROCESS_ID") ; - - like( memory_consumption_ratio(), qr{\d+}xms, 'memory_consumption_ratio' ) ; - like( memory_consumption_ratio(1), qr{\d+}xms, 'memory_consumption_ratio 1' ) ; - like( memory_consumption_ratio(10), qr{\d+}xms, 'memory_consumption_ratio 10' ) ; + note( "memory_consumption_of_myself: " . memory_consumption_of_myself( ) . " bytes aka " . bytes_display_string_dec( memory_consumption_of_myself( ) ) ) ; + like( memory_consumption_of_myself( ), qr{\d+}xms,'tests_memory_consumption_of_myself no args') ; + like( memory_consumption_of_myself( 1 ), qr{\d+}xms,'tests_memory_consumption_of_myself 1') ; + like( memory_consumption_of_myself( $PROCESS_ID ), qr{\d+}xms,"tests_memory_consumption_of_myself $PROCESS_ID") ; - note( 'Leaving tests_memory_consumption()' ) ; + note( 'Leaving tests_memory_consumption_of_myself()' ) ; return ; } -sub memory_consumption +sub memory_consumption_of_myself { # memory consumed by imapsync until now in bytes return( ( memory_consumption_of_pids( ) )[0] ); @@ -16904,43 +17365,35 @@ sub memory_consumption sub debugmemory { - my $mysync = shift ; - if ( ! $mysync->{debugmemory} ) { return q{} ; } + my $mysync = shift @ARG ; + if ( ! $mysync->{ debugmemory } ) { return q{} ; } - my $precision = shift ; - return( mysprintf( "Memory consumption$precision: %.1f MiB\n", memory_consumption( ) / $KIBI / $KIBI ) ) ; + my $precision = shift @ARG ; + return( mysprintf( "Memory consumption$precision: %.1f MiB\n", memory_consumption_of_myself( ) / $KIBI / $KIBI ) ) ; } -sub memory_consumption_of_pids +sub memory_consumption_of_pids { - - my @pid = @_; + my @pid = @ARG ; + # No pid in ARG means find myself memory @pid = ( @pid ) ? @pid : ( $PROCESS_ID ) ; - $sync->{ debug } and myprint( "memory_consumption_of_pids PIDs: @pid\n" ) ; + #$sync->{ debug } and myprint( "memory_consumption_of_pids PIDs: @pid\n" ) ; my @val ; - if ( ( 'MSWin32' eq $OSNAME ) or ( 'cygwin' eq $OSNAME ) ) { - @val = memory_consumption_of_pids_win32( @pid ) ; - } - elsif ( 'darwin' eq $OSNAME ) + if ( ( 'MSWin32' eq $OSNAME ) or ( 'cygwin' eq $OSNAME ) ) { - @val = memory_consumption_of_pids_mac( @pid ) ; + @val = memory_consumption_of_pids_win32( @pid ) ; } else { - # Unix - my @ps = qx{ ps -o vsz -p @pid } ; - shift @ps ; # First line is column name "VSZ" - chomp @ps ; - # convert to octets - - @val = map { $_ * $KIBI } @ps ; + # Unix, Mac OS X included + @val = memory_consumption_of_pids_unix( @pid ) ; } return( @val ) ; -} +} -sub memory_consumption_of_pids_mac +sub memory_consumption_of_pids_unix { my @pid = @_ ; # Use IPC::Open3 from perlcrit -3 @@ -16948,14 +17401,86 @@ sub memory_consumption_of_pids_mac #my @ps = backtick( "ps -o rss -p @pid" ) ; #myprint( "ps: @ps" ) ; my @ps = qx{ ps -o rss -p @pid } ; - shift @ps ; # First line is column name "RSS" + shift @ps ; # First line is the column name "RSS" chomp @ps ; + # convert to octets my @val = map { $_ * $KIBI } @ps ; return( @val ) ; } -sub memory_consumption_of_pids_win32 + +sub tests_memory_consumption_of_all_pids { + note( 'Entering tests_memory_consumption_of_all_pids()' ) ; + + note( "memory_consumption_of_all_pids: " . memory_consumption_of_all_pids( ) . " bytes aka " . bytes_display_string_dec( memory_consumption_of_all_pids( ) ) ) ; + like( memory_consumption_of_all_pids( ), qr{\d+}xms, 'tests_memory_consumption_of_all_pids no args') ; + + note( 'Leaving tests_memory_consumption_of_all_pids()' ) ; + return ; +} + + +sub memory_consumption_of_all_pids +{ + my @all_pids = all_pids( ) ; + my @memory_consumption_of_all_pids = memory_consumption_of_pids( @all_pids ) ; + my $memory_consumption_of_all_pids = add( @memory_consumption_of_all_pids ) ; + return $memory_consumption_of_all_pids ; +} + + +sub tests_all_pids +{ + note( 'Entering tests_all_pids()' ) ; + + note( 'all_pids', join( ' ', all_pids( ) ) ) ; + ok( all_pids( ), 'tests_all_pids: no args => list of pids' ) ; + + + note( 'Leaving tests_all_pids()' ) ; + return ; +} + + +sub all_pids +{ + my @all_pids ; + if ( ( 'MSWin32' eq $OSNAME ) or ( 'cygwin' eq $OSNAME ) ) { + @all_pids = all_pids_win32( ) ; + } + else + { + # Unix + @all_pids = all_pids_unix( ) ; + } + return( @all_pids ) ; +} + +sub all_pids_unix +{ + my @ps = qx{ ps -e -o pid } ; + shift @ps ; # First line is the column name "PID" + chomp @ps ; + return @ps ; +} + + + +sub tests_memory_consumption_of_pids_win32 +{ + note( 'Entering tests_memory_consumption_of_pids_win32()' ) ; + + note( memory_consumption_of_pids_win32( $PROCESS_ID ) ) ; + #ok( memory_consumption_of_pids_win32( $PROCESS_ID ), 'tests_memory_consumption_of_pids_win32: no args => ' ) ; + + note( 'Leaving tests_memory_consumption_of_pids_win32()' ) ; + return ; +} + + +sub memory_consumption_of_pids_win32 +{ # Windows my @PID = @_; my %PID; @@ -16965,28 +17490,174 @@ sub memory_consumption_of_pids_win32 # Does not work but should work reading the tasklist documentation #@ps = qx{ tasklist /FI "PID eq @PID" }; - my @ps = qx{ tasklist /NH /FO CSV } ; - #my @ps = backtick( 'tasklist /NH /FO CSV' ) ; + my @ps = qx{ tasklist /NH /FO TABLE } ; + #my @ps = backtick( 'tasklist /NH /FO TABLE' ) ; #myprint( "-" x $STD_CHAR_PER_LINE, "\n", @ps, "-" x $STD_CHAR_PER_LINE, "\n" ) ; - my @val; - foreach my $line (@ps) { - my($name, $pid, $mem) = (split ',', $line )[0,1,4]; + my @val ; + #myprint( @ps ) ; + foreach my $line ( @ps ) { + my( $name, $pid, $mem ) = ( split / +/, $line )[ 0, 1, 4 ] ; next if (! $pid); - #myprint( "[$name][$pid][$mem]" ) ; - if ($PID{remove_qq($pid)}) { - #myprint( "MATCH !\n" ) ; + #myprint( "[$name][$pid][$mem]\n" ) ; + $pid = remove_qq( $pid ) ; + if ( $PID{ $pid } ) + { + #myprint( "MATCH $pid\n" ) ; chomp $mem ; - $mem = remove_qq($mem); - $mem = remove_Ko($mem); - $mem = remove_not_num($mem); - #myprint( "[$mem]\n" ) ; - push @val, $mem * $KIBI; + $mem = remove_qq( $mem ) ; + $mem = remove_not_num( $mem ) ; + if ( is_number( $mem ) ) + { + #myprint( "[$mem] ", $mem * $KIBI, "\n" ) ; + push @val, $mem * $KIBI ; + } } } - return(@val); + return( @val ) ; +} + + + +sub all_pids_win32 +{ + my @ps = qx{ tasklist /NH /FO CSV } ; + my @pids ; + foreach my $line ( @ps ) + { + my( $name, $pid, $mem ) = ( split ',', $line )[ 0, 1, 4 ] ; + next if ( ! $pid ) ; + #myprint( "[$name][$pid][$mem]\n" ) ; + $pid = remove_qq( $pid ) ; + push @pids, $pid ; + } + return( @pids ) ; } + +sub tests_memory_consumption_all_pids_percent +{ + note( 'Entering tests_memory_consumption_all_pids_percent()' ) ; + + note( memory_consumption_all_pids_percent( ) . " (%)" ) ; + like( memory_consumption_all_pids_percent( ), qr{^0|^(\d+\.\d+)$}xms, 'tests_memory_consumption_all_pids_percent: no args => like 12.34' ) ; + + ok( 0 <= memory_consumption_all_pids_percent( ), 'tests_memory_consumption_all_pids_percent: > 0' ) ; + ok( 100 >= memory_consumption_all_pids_percent( ), 'tests_memory_consumption_all_pids_percent: <= 100' ) ; + note( 'Leaving tests_memory_consumption_all_pids_percent()' ) ; + + return ; +} + + + +sub memory_consumption_all_pids_percent +{ + my $percent ; + + my $memory_consumption_of_all_pids = memory_consumption_of_all_pids( ) ; + my $total_memory_bytes = total_ram_memory_bytes( ) || return 0 ; + + $percent = sprintf( "%.2f", 100 * $memory_consumption_of_all_pids / $total_memory_bytes ) ; + return $percent ; +} + + + +sub tests_memory_consumption_all_pids_percent_Proc_ProcessTable +{ + note( 'Entering tests_memory_consumption_all_pids_percent_Proc_ProcessTable()' ) ; + require_ok( 'Proc::ProcessTable' ) ; + + note( memory_consumption_all_pids_percent_Proc_ProcessTable( ) . " (%)" ) ; + like( memory_consumption_all_pids_percent_Proc_ProcessTable( ), qr{^0|^(\d+\.\d+)$}xms, 'tests_memory_consumption_all_pids_percent_Proc_ProcessTable: no args => like 12.34' ) ; + + my $mysync = { } ; + + like( memory_consumption_all_pids_percent_Proc_ProcessTable( $mysync ), qr{^0|^(\d+\.\d+)$}xms, 'tests_memory_consumption_all_pids_percent_Proc_ProcessTable: { } => like 12.34' ) ; + note( 'Leaving tests_memory_consumption_all_pids_percent_Proc_ProcessTable()' ) ; + + return ; +} + +# Proc::ProcessTable pctmem does NOT work for Win32 Darwin +# Negative values and negative zeros for Darwin +# zeros for Win32 +# +sub memory_consumption_all_pids_percent_Proc_ProcessTable +{ + my $mysync = shift @ARG ; + + my $percent ; + if ( eval { require Proc::ProcessTable } ) + { + my $table_all_processes = Proc::ProcessTable->new( ) ; + + if ( pctmem_available( $table_all_processes ) ) + { + #pctmem is memory percentage of a process + foreach my $process ( @{ $table_all_processes->table( ) } ) + { + #myprint( "pctmem: ", $process->pctmem( ), "\n" ) ; + # + $percent += max( 0, $process->pctmem( ) ) ; + } + } + else + { + $percent = 0 ; + } + } + else + { + $percent = 0 ; + } + + $percent = sprintf( "%.2f", $percent ) ; + + return $percent ; +} + + +sub tests_pctmem_available +{ + note( 'Entering tests_pctmem_available()' ) ; + + is( undef, pctmem_available( ), 'pctmem_available: no args => undef' ) ; + + SKIP: { + skip( 'no Proc::ProcessTable', 1 ) if ( ! eval { require Proc::ProcessTable } ) ; + my $table_all_processes = Proc::ProcessTable->new( ) ; + like( pctmem_available( $table_all_processes ), qr{^(0|1)$}xms, 'pctmem_available: => 0 or 1' ) ; + } + + note( 'Leaving tests_pctmem_available()' ) ; + return ; +} + + +sub pctmem_available +{ + my $table_all_processes = shift @ARG ; + + if ( ! defined $table_all_processes ) { return ; } ; + + my @fields = $table_all_processes->fields( ) ; + + my %fields = map { defined( $_ ) ? ( $_ => 1 ) : ( ) } @fields ; + + if ( exists( $fields{ pctmem } ) ) + { + return 1 ; + } + else + { + return 0 ; + } + + return ; +} + sub tests_backtick { note( 'Entering tests_backtick()' ) ; @@ -17042,7 +17713,7 @@ sub tests_backtick sub backtick { - my $command = shift ; + my $command = shift @ARG ; if ( ! $command ) { return ; } @@ -17161,7 +17832,7 @@ sub search_dyn_lib_locale_MSWin32 sub remove_not_num { - my $string = shift ; + my $string = shift @ARG ; $string =~ tr/0-9//cd ; #myprint( "tr [$string]\n" ) ; return( $string ) ; @@ -17171,48 +17842,58 @@ sub tests_remove_not_num { note( 'Entering tests_remove_not_num()' ) ; - ok( '123' eq remove_not_num( 123 ), 'remove_not_num( 123 )' ) ; - ok( '123' eq remove_not_num( '123' ), q{remove_not_num( '123' )} ) ; - ok( '123' eq remove_not_num( '12 3' ), q{remove_not_num( '12 3' )} ) ; - ok( '123' eq remove_not_num( 'a 12 3 Ko' ), q{remove_not_num( 'a 12 3 Ko' )} ) ; + is( '123', remove_not_num( 123 ), 'remove_not_num( 123 )' ) ; + is( '123', remove_not_num( '123' ), q{remove_not_num( '123' )} ) ; + is( '123', remove_not_num( '12 3' ), q{remove_not_num( '12 3' )} ) ; + is( '123', remove_not_num( 'a 12 3 Ko' ), q{remove_not_num( 'a 12 3 Ko' )} ) ; + is( '123', remove_not_num( 'a 12 3 K' ), q{remove_not_num( 'a 12 3 K' )} ) ; + is( '123', remove_not_num( 'a 12,3 K' ), q{remove_not_num( 'a 12, 3 K' )} ) ; + is( '173892', remove_not_num( 'a 173,892 K' ), q{remove_not_num( 'a 173,892 K' )} ) ; note( 'Leaving tests_remove_not_num()' ) ; return ; } -sub remove_Ko + + + +sub tests_remove_qq { - my $string = shift; - if ($string =~ /^(.*)\sKo$/xo) { - return($1); + note( 'Entering tests_remove_qq()' ) ; + + is( undef, remove_qq( ), 'tests_remove_qq: no args => undef' ) ; + is( '', remove_qq( '' ), 'tests_remove_qq: empty => empty' ) ; + is( 'ABC', remove_qq( 'ABC' ), 'tests_remove_qq: ABC => ABC' ) ; + is( 'ABC', remove_qq( '"ABC"' ), 'tests_remove_qq: "ABC" => ABC' ) ; + is( '"ABC', remove_qq( '""ABC"' ), 'tests_remove_qq: ""ABC" => "ABC' ) ; + is( 'ABC"', remove_qq( '"ABC""' ), 'tests_remove_qq: "ABC"" => ABC"' ) ; + is( '"ABC"', remove_qq( '""ABC""' ), 'tests_remove_qq: ""ABC"" => "ABC"' ) ; + + note( 'Leaving tests_remove_qq()' ) ; + return ; +} + + +sub remove_qq +{ + my $string = shift ; + + if ( ! defined $string ) { return ; } + + #myprint( "$string\n" ) ; + + if ( $string =~ /^"(.*)"$/xo ) + { + return( $1 ) ; }else{ - return($string); + return( $string ) ; } -} - -sub remove_qq -{ - my $string = shift; - if ($string =~ /^"(.*)"$/xo) { - return($1); - }else{ - return($string); - } -} - -sub memory_consumption_ratio -{ - - my ($base) = @_; - $base ||= 1; - my $consu = memory_consumption(); - return($consu / $base); -} +} sub date_from_rcs { - my $d = shift ; + my $d = shift @ARG ; my %num2mon = qw( 01 Jan 02 Feb 03 Mar 04 Apr 05 May 06 Jun 07 Jul 08 Aug 09 Sep 10 Oct 11 Nov 12 Dec ) ; if ($d =~ m{(\d{4})/(\d{2})/(\d{2})\s(\d{2}):(\d{2}):(\d{2})}xo ) { @@ -17248,7 +17929,7 @@ sub good_date # outgoing format: internal date format # 24-Aug-2010 16:00:00 +0200 - my $d = shift ; + my $d = shift @ARG ; return(q{}) if not defined $d; SWITCH: { @@ -17483,7 +18164,7 @@ sub tests_nb_messages_in_2_not_in_1 sub nb_messages_in_2_not_in_1 { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( not defined $mysync ) { return ; } $mysync->{ nb_messages_in_2_not_in_1 } = scalar( @@ -17497,7 +18178,7 @@ sub nb_messages_in_2_not_in_1 sub nb_messages_in_1_not_in_2 { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( not defined $mysync ) { return ; } $mysync->{ nb_messages_in_1_not_in_2 } = scalar( @@ -17512,7 +18193,7 @@ sub nb_messages_in_1_not_in_2 sub comment_on_final_diff_in_1_not_in_2 { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( not defined $mysync or $mysync->{ justfolders } @@ -17569,7 +18250,7 @@ sub comment_on_final_diff_in_1_not_in_2 sub comment_on_final_diff_in_2_not_in_1 { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( not defined $mysync or $mysync->{ justfolders } @@ -17771,7 +18452,7 @@ sub delete_folder sub delete1emptyfolders { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync ) { return ; } # abort if no parameter if ( ! $mysync->{delete1emptyfolders} ) { return ; } # abort if --delete1emptyfolders off my $imap = $mysync->{imap1} ; @@ -17962,9 +18643,9 @@ sub tests_delete1emptyfolders_unit { note( 'Entering tests_delete1emptyfolders_unit()' ) ; - my $syncT = shift ; - my $folders1wanted_init_ref = shift ; - my $folders1wanted_after_ref = shift ; + my $syncT = shift @ARG ; + my $folders1wanted_init_ref = shift @ARG ; + my $folders1wanted_after_ref = shift @ARG ; my $comment = shift || q{delete1emptyfolders:} ; my @folders1wanted_init = @{ $folders1wanted_init_ref } ; @@ -17982,7 +18663,7 @@ sub tests_delete1emptyfolders_unit sub extract_header { - my $string = shift ; + my $string = shift @ARG ; my ( $header ) = split /\n\n/x, $string ; if ( ! $header ) { return( q{} ) ; } @@ -18018,7 +18699,7 @@ EOM } sub decompose_header{ - my $string = shift ; + my $string = shift @ARG ; # a hash, for a keyword header KEY value are list of strings [VAL1, VAL1_other, etc] # Think of multiple "Received:" header lines. @@ -18192,7 +18873,7 @@ sub epoch # outgoing format: epoch - my $d = shift ; + my $d = shift @ARG ; return(q{}) if not defined $d; my ( $mday, $month, $year, $hour, $min, $sec, $sign, $zone_h, $zone_m ) ; @@ -18265,7 +18946,7 @@ sub tests_max_line_length sub max_line_length { - my $string = shift ; + my $string = shift @ARG ; my $max = 0 ; while ( $string =~ m/([^\n]*\n?)/msxg ) { @@ -18653,7 +19334,7 @@ sub tests_localtimez sub localtimez { - my $time = shift ; + my $time = shift @ARG ; $time = defined( $time ) ? $time : time ; @@ -18686,7 +19367,7 @@ sub tests_slash_to_underscore sub slash_to_underscore { - my $string = shift ; + my $string = shift @ARG ; if ( ! defined $string ) { return ; } @@ -18721,17 +19402,6 @@ sub tests_million_folders_baby_2 -sub tests_always_fail -{ - note( 'Entering tests_always_fail()' ) ; - - is( 0, 1, 'always_fail: 0 is 1' ) ; - - note( 'Leaving tests_always_fail()' ) ; - return ; -} - - sub tests_logfileprepa { note( 'Entering tests_logfileprepa()' ) ; @@ -18746,7 +19416,7 @@ sub tests_logfileprepa sub logfileprepa { - my $logfile = shift ; + my $logfile = shift @ARG ; if ( ! defined( $logfile ) ) { @@ -18870,7 +19540,7 @@ sub teefinish sub getpwuid_any_os { - my $uid = shift ; + my $uid = shift @ARG ; return( scalar getlogin ) if ( 'MSWin32' eq $OSNAME ) ; # Windows system return( scalar getpwuid $uid ) ; # Unix system @@ -18882,7 +19552,7 @@ sub getpwuid_any_os sub abortifneeded { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( -e $mysync->{ abortfile } ) { myprint( "Asked to terminate by file $mysync->{ abortfile }\n" ) ; @@ -18901,7 +19571,7 @@ sub abortifneeded sub simulong { - my $mysync = shift ; + my $mysync = shift @ARG ; my $max_seconds = $mysync->{ simulong } ; @@ -18934,7 +19604,7 @@ sub printenv sub unittestssuite { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! ( $mysync->{ tests } or $mysync->{ testsdebug } or $mysync->{ testsunit } ) ) { return ; } @@ -18982,8 +19652,8 @@ sub cleanup_mess_from_tests sub after_get_options { - my $mysync = shift ; - my $numopt = shift ; + my $mysync = shift @ARG ; + my $numopt = shift @ARG ; # exit with --help option or no option at all @@ -19013,7 +19683,7 @@ sub tests_remove_edging_blanks sub remove_edging_blanks { - my $string = shift ; + my $string = shift @ARG ; if ( ! defined $string ) { return ; @@ -19044,7 +19714,7 @@ sub tests_sanitize sub sanitize { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! defined $mysync ) { return ; @@ -19059,7 +19729,7 @@ sub sanitize sub easyany { - my $mysync = shift ; + my $mysync = shift @ARG ; # Gmail if ( $mysync->{gmail1} and $mysync->{gmail2} ) { @@ -19109,7 +19779,7 @@ sub easyany # From and for https://imapsync.lamiral.info/FAQ.d/FAQ.Gmail.txt sub gmail12 { - my $mysync = shift ; + my $mysync = shift @ARG ; # Gmail at host1 and host2 $mysync->{host1} ||= 'imap.gmail.com' ; $mysync->{ssl1} = ( defined $mysync->{ssl1} ) ? $mysync->{ssl1} : 1 ; @@ -19131,7 +19801,7 @@ sub gmail12 sub gmail1 { - my $mysync = shift ; + my $mysync = shift @ARG ; # Gmail at host2 $mysync->{host1} ||= 'imap.gmail.com' ; $mysync->{ssl1} = ( defined $mysync->{ssl1} ) ? $mysync->{ssl1} : 1 ; @@ -19149,7 +19819,7 @@ sub gmail1 sub gmail2 { - my $mysync = shift ; + my $mysync = shift @ARG ; # Gmail at host2 $mysync->{ host2 } ||= 'imap.gmail.com' ; $mysync->{ ssl2 } = ( defined $mysync->{ ssl2 } ) ? $mysync->{ ssl2 } : 1 ; @@ -19184,7 +19854,7 @@ sub gmail2 sub office1 { # Office 365 at host1 - my $mysync = shift ; + my $mysync = shift @ARG ; output( $mysync, q{Option --office1 is like: --host1 outlook.office365.com --ssl1 --exclude "^Files$"} . "\n" ) ; output( $mysync, "Option --office1 (cont) : unless overrided with --host1 otherhost --nossl1 --noexclude\n" ) ; @@ -19200,7 +19870,7 @@ sub office1 sub office2 { # Office 365 at host2 - my $mysync = shift ; + my $mysync = shift @ARG ; output( $mysync, qq{Option --office2 is like: --host2 outlook.office365.com --ssl2 --maxsize 45_000_000 --maxmessagespersecond 4\n} ) ; output( $mysync, qq{Option --office2 (cont) : --disarmreadreceipts --regexmess "wrap 10500" --f1f2 "Files=Files_renamed_by_imapsync"\n} ) ; output( $mysync, qq{Option --office2 (cont) : unless overrided with --host2 otherhost --nossl2 ... --nodisarmreadreceipts --noregexmess\n} ) ; @@ -19227,7 +19897,7 @@ sub office2 sub exchange1 { # Exchange 2010/2013 at host1 - my $mysync = shift ; + my $mysync = shift @ARG ; output( $mysync, "Option --exchange1 does nothing (except printing this line...)\n" ) ; # Well nothing to do so far return ; @@ -19236,7 +19906,7 @@ sub exchange1 sub exchange2 { # Exchange 2010/2013 at host2 - my $mysync = shift ; + my $mysync = shift @ARG ; output( $mysync, "Option --exchange2 is like: --maxsize 10_000_000 --maxmessagespersecond 4 --disarmreadreceipts\n" ) ; output( $mysync, "Option --exchange2 (cont) : --regexflag del Flagged --regexmess wrap 10500\n" ) ; output( $mysync, "Option --exchange2 (cont) : unless overrided with --maxsize xxx --nodisarmreadreceipts --noregexflag --noregexmess\n" ) ; @@ -19256,7 +19926,7 @@ sub exchange2 sub domino1 { # Domino at host1 - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ sep1 } = q{\\} ; $prefix1 = q{} ; @@ -19267,7 +19937,7 @@ sub domino1 sub domino2 { # Domino at host1 - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{ sep2 } = q{\\} ; $prefix2 = q{} ; @@ -19445,7 +20115,7 @@ sub tests_imapsping sub imapsping { - my $host = shift ; + my $host = shift @ARG ; return tcpping( $host, $IMAP_SSL_PORT ) ; } @@ -19559,7 +20229,7 @@ sub tests_sslcheck sub sslcheck { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync->{sslcheck} ) { return ; @@ -19609,7 +20279,7 @@ sub sslcheck sub testslive_init { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{host1} ||= 'test1.lamiral.info' ; $mysync->{user1} ||= 'test1' ; $mysync->{password1} ||= 'secret1' ; @@ -19621,7 +20291,7 @@ sub testslive_init sub testslive6_init { - my $mysync = shift ; + my $mysync = shift @ARG ; $mysync->{host1} ||= 'ks6ipv6.lamiral.info' ; $mysync->{user1} ||= 'test1' ; $mysync->{password1} ||= 'secret1' ; @@ -19653,7 +20323,7 @@ sub tests_backslash_caret sub backslash_caret { - my $string = shift ; + my $string = shift @ARG ; $string =~ s{\\ $ }{^}gxms ; @@ -19744,9 +20414,9 @@ sub tests_sig_install # sub sig_install { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync ) { return ; } - my $mysubname = shift ; + my $mysubname = shift @ARG ; if ( ! $mysubname ) { return ; } if ( ! @ARG ) { return ; } @@ -19758,7 +20428,7 @@ sub sig_install $mysync->{ debugsig } and myprint( "In sig_install with sub $mysubname and signal @ARG\n" ) ; my $subsignal = sub { - my $signame = shift ; + my $signame = shift @ARG ; $mysync->{ debugsig } and myprint( "In subsignal with $signame and $mysubname\n" ) ; &$mysub( $mysync, $signame ) ; } ; @@ -19775,7 +20445,7 @@ sub sig_install sub tototo { - my $mysync = shift ; + my $mysync = shift @ARG ; myprint("In tototo with @ARG\n" ) ; $mysync->{ tototo_calls } += 1 ; return ; @@ -19843,7 +20513,7 @@ sub tests_toggle_sleep sub toggle_sleep { - my $mysync = shift ; + my $mysync = shift @ARG ; myprint("In toggle_sleep with @ARG\n" ) ; @@ -19857,7 +20527,7 @@ sub toggle_sleep sub mypod2usage { - my $fh_pod2usage = shift ; + my $fh_pod2usage = shift @ARG ; pod2usage( -exitval => 'NOEXIT', @@ -19874,7 +20544,7 @@ sub mypod2usage sub usage { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! defined $mysync ) { return ; } @@ -19916,7 +20586,7 @@ sub tests_usage sub usage_footer { - my $mysync = shift ; + my $mysync = shift @ARG ; my $footer = q{} ; @@ -20391,7 +21061,7 @@ sub tests_get_options_cgi_context -sub get_options_cgi +sub get_options_cgi { # In CGI context arguments are not in @ARGV but in QUERY_STRING variable (with GET). my $mysync = shift @ARG ; @@ -20452,6 +21122,7 @@ sub get_options_cgi 'tail!' => \$mysync->{ tail }, 'tmphash=s' => \$mysync->{ tmphash }, 'exitwhenover=i' => \$mysync->{ exitwhenover }, + 'exitonload!' => \$mysync->{ exitonload }, 'syncduplicates!' => \$mysync->{ syncduplicates }, 'skipcrossduplicates!' => \$mysync->{ skipcrossduplicates }, 'debugcrossduplicates!'=> \$mysync->{ debugcrossduplicates }, @@ -20473,7 +21144,7 @@ sub get_options_cgi return ; } return $numopt ; -} +} sub get_options_cmd { @@ -20672,6 +21343,7 @@ sub get_options_cmd 'useuid!' => \$useuid, 'addheader!' => \$mysync->{addheader}, 'exitwhenover=i' => \$mysync->{ exitwhenover }, + 'exitonload!' => \$mysync->{ exitonload }, 'checkselectable!' => \$mysync->{ checkselectable }, 'checkfoldersexist!' => \$mysync->{ checkfoldersexist }, 'checkmessageexists!' => \$checkmessageexists, @@ -20714,6 +21386,7 @@ sub get_options_cmd 'emailreport1!' => \$mysync->{ emailreport1 }, 'emailreport2!' => \$mysync->{ emailreport2 }, 'var=s@' => \$mysync->{ var }, + 'memorystress!' => \$mysync->{ memorystress }, ) ; #myprint( Data::Dumper->Dump( [ $mysync ] ) ) ; $mysync->{ debug } and output( $mysync, "get options: [$opt_ret][$numopt]\n" ) ; @@ -20817,33 +21490,32 @@ sub get_options } -sub tests_infos +sub tests_infos { note( 'Entering tests_infos()' ) ; note( "OSNAME=$OSNAME" ) ; - note( "hostname=". hostname() ) ; + note( "hostname=". hostname( ) ) ; note( "cwd=" . getcwd( ) ) ; note( "PROGRAM_NAME=$PROGRAM_NAME" ) ; - my $stat = stat("$PROGRAM_NAME") ; - my $perms = sprintf( "%04o\n", $stat->mode & oct($PERMISSION_FILTER) ) ; + my $stat = stat( "$PROGRAM_NAME" ) ; + my $perms = sprintf( "%04o\n", $stat->mode & oct( $PERMISSION_FILTER ) ) ; note( "permissions=$perms" ) ; note( "PROCESS_ID=$PROCESS_ID" ) ; note( "REAL_USER_ID=$REAL_USER_ID" ) ; note( "EFFECTIVE_USER_ID=$EFFECTIVE_USER_ID" ) ; note( "context: " . imapsync_context( $sync ) ) ; - note( "memory_consumption: " . memory_consumption() . " bytes aka " . bytes_display_string_dec( memory_consumption() ) ) ; - cpu_number - note( "cpu_number: " . cpu_number() ) ; - note( $sync->{rcs} ) ; + note( "memory_consumption_of_myself: " . memory_consumption_of_myself( ) . " bytes aka " . bytes_display_string_dec( memory_consumption_of_myself( ) ) ) ; + note( "cpu_number: " . cpu_number( ) ) ; + note( $sync->{ rcs } ) ; note( 'Leaving tests_infos()' ) ; return ; -} +} sub condition_to_leave_after_tests { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( $mysync->{ testslive } or $mysync->{ testslive6 } ) { return 0 ; @@ -20861,7 +21533,7 @@ sub condition_to_leave_after_tests sub testunitsession { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync ) { return ; } if ( ! $mysync->{ testsunit } ) { return ; } @@ -20935,11 +21607,25 @@ sub tests_true { note( 'Entering tests_true()' ) ; - is( 1, 1, 'true: 1 is 1' ) ; + is( 1, 1, 'true: 1 is 1' ) ; + is( 'A', 'A', 'true: A is A' ) ; note( 'Leaving tests_true()' ) ; return ; } + +sub tests_always_fail +{ + note( 'Entering tests_always_fail()' ) ; + + is( 0, 1, 'always_fail: 0 is 1' ) ; + isnt( 'A', 'A', 'always_fail: A is A' ) ; + + note( 'Leaving tests_always_fail()' ) ; + return ; +} + + sub tests_testsunit { note( 'Entering tests_testunit()' ) ; @@ -20981,11 +21667,11 @@ sub testsunit return ; } -sub testsdebug +sub testsdebug { # Now a little obsolete since there is # imapsync ... --testsunit "anyfunction" - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync->{ testsdebug } ) { return ; } SKIP: { if ( ! $mysync->{ testsdebug } ) { @@ -21000,24 +21686,42 @@ sub testsdebug #tests_kill_zero( ) ; #tests_connect_socket( ) ; #tests_probe_imapssl( ) ; - #tests_cpu_number( ) ; #tests_mailimapclient_connect( ) ; - #tests_loadavg( ) ; #tests_always_fail( ) ; - tests_localtimez( ) ; - tests_year_month_day_hour_min_sec_ms( ) ; - tests_date_rfc822( ) ; - tests_email_report_message_id( ) ; + #tests_localtimez( ) ; + #tests_year_month_day_hour_min_sec_ms( ) ; + #tests_date_rfc822( ) ; + #tests_email_report_message_id( ) ; + tests_all_pids( ) ; + tests_memory_consumption_of_myself( ) ; + tests_ram_memory_info( ) ; + tests_memory_consumption_of_all_pids( ) ; + tests_memory_consumption_all_pids_percent( ) ; + + #tests_memory_stress( ) ; + + tests_memory_consumption_of_pids_win32( ) ; + + #tests_load_and_delay( ) ; + #tests_cpu_number( ) ; + #tests_loadavg( ) ; + #tests_load_per_cpu( ) ; + #tests_all_pids( ) ; + #tests_remove_qq( ) ; + #tests_remove_not_num( ) ; + + tests_infos( ) ; + note( 'Leaving testsdebug()' ) ; done_testing( ) ; } return ; -} +} sub tests { - my $mysync = shift ; + my $mysync = shift @ARG ; if ( ! $mysync->{ tests } ) { return ; } SKIP: { @@ -21037,7 +21741,7 @@ sub tests tests_good_date( ) ; tests_max( ) ; tests_remove_not_num(); - tests_memory_consumption( ) ; + tests_memory_consumption_of_myself( ) ; tests_is_a_release_number(); tests_imapsync_basename(); tests_list_keys_in_2_not_in_1(); @@ -21178,7 +21882,6 @@ sub tests tests_eta( ) ; tests_timesince( ) ; tests_timenext( ) ; - tests_imapsync_context( ) ; tests_abort( ) ; tests_probe_imapssl( ) ; @@ -21223,6 +21926,22 @@ sub tests tests_logfilesuffix( ) ; tests_cgienvcontext( ) ; tests_usecache_and_skipcrossduplicates( ) ; + tests_loglogfile( ) ; + tests_heavy_load_reached( ) ; + tests_heavy_load_percent_threshold( ) ; + tests_pctmem_available( ) ; + tests_filterbuggyflags( ) ; + tests_heavy_load_reached_by_memory( ) ; + tests_heavy_load_reached_by_cpu( ) ; + tests_load_per_cpu( ) ; + tests_memory_consumption_surface( ) ; + tests_add( ) ; + tests_all_pids( ) ; + tests_memory_consumption_of_all_pids( ) ; + tests_remove_qq( ) ; + tests_memory_consumption_all_pids_percent( ) ; + tests_ram_memory_info( ) ; + tests_infos( ) ; #tests_resolv( ) ; @@ -21233,7 +21952,8 @@ sub tests #tests_kill_zero( ) ; #tests_always_fail( ) ; - done_testing( 1922 ) ; + + done_testing( 1992 ) ; note( 'Leaving tests()' ) ; } return ; @@ -21243,11 +21963,11 @@ sub tests_template { note( 'Entering tests_template()' ) ; - is( undef, template( ), 'template: no args => undef' ) ; + is( undef, template( ), 'tests_template: no args => undef' ) ; my $mysync = { } ; - is( undef, template( $mysync ), 'template: undef => undef' ) ; - is_deeply( {}, {}, 'template: a hash is a hash' ) ; - is_deeply( [], [], 'template: an array is an array' ) ; + is( undef, template( $mysync ), 'tests_template: { } => undef' ) ; + is_deeply( {}, {}, 'tests_template: a hash is a hash' ) ; + is_deeply( [], [], 'tests_template: an array is an array' ) ; note( 'Leaving tests_template()' ) ; return ; diff --git a/index.shtml b/index.shtml index a9a327e..57a366e 100644 --- a/index.shtml +++ b/index.shtml @@ -54,7 +54,7 @@
    • Installation
    • Documentation
    • News about imapsync , previous and next releases
    • -
    • List of the 86 imap software server applications supported by imapsync
    • +
    • List of the 88 imap software server applications supported by imapsync
    • Similar software tools and external services
    • Discuss or search on the mailing-list
    • Imapsync Terms and Conditions
    • @@ -294,7 +294,7 @@ but without the 3 GB limit.
    • Imapsync Perl source code for any operating system, Unix, Windows, OS X.
    • The visual interface, similar to /X, - to install the service on your own Linux server (not working on Windows yet).
    • + to install the service on your own Linux server (not working on Windows yet).
    • Lifetime of imapsync updates without extra payment.
    • @@ -470,88 +470,139 @@ Maybe one day those little crypto coins will be like gold? (I will like that!)
        -
      • There are 6000 to 7000 imapsync users per month (50 000 users for the year 2021). +
      • There are 6000 to 8000 imapsync users per month (52 000 users for the year 2021). Well, if all users could be buyers!
      • -
      • 9 M to 16 M mailboxes transfers per month during 2020.
      • -
      • 136 M transfers for 2020, -that is 4 whole mailboxes completely synced each second on average (136*10^6/365/24/3600 ~ 4), -and an estimation of 60 Petabytes transferred in 2020 ( 1 PiB = 2^50 bytes = 1024^5 ~ 10^15), +
      • 10 M to 18 M mailboxes transfers per month during 2021.
      • +
      • 161 M transfers for 2021, +that is 5 whole mailboxes completely synced each second on average (161*10^6/365/24/3600 ~ 5), +and an estimation of 69 Petabytes transferred in 2021 ( 1 PiB = 2^50 bytes = 1024^5 ~ 10^15), taking a mean of 500 Megabytes per transfer (an estimated mean given by online /X real stats). -60 Petabytes = 500*10^6*136*10^6. The 2020 global internet traffic was 2580 Exabytes -(2580 ~ (174+41) * 12 ) -(1 EiB = 2^60 bytes = 1024^6 ~ 10^18) so imapsync is a very very tiny thing (23 per million, 60/2580000). +69 Petabytes = 480*10^6*161*10^6. The 2021 global internet traffic was 2580 Exabytes +(3312 ~ (219+57) * 12 ) +(1 EiB = 2^60 bytes = 1024^6 ~ 10^18) so imapsync is a very very tiny thing (21 per million, 69/3312000).
      • -Let's see it another way, imapsync did 136 M transfers for 2020, -that's nearly 492 M email messages transferred every day (136*1325/366) -taking a mean of 1325 messages per transfer (an estimated mean given by online /X real stats). +Let's see it another way, imapsync did 161 M transfers for 2021, +that's nearly 611 M email messages transferred every day (161*1388/366) +taking a mean of 1388 messages per transfer (an estimated mean given by online /X 2021 real stats). The internet global estimated number of messages sent every day is -306 billions in 2020 +320 billions in 2021 (55% being spam but that's another story...). -So imapsync does 0.16% (492/306000*100) of all email traffic, not that bad for a command-line tool! +So imapsync does 0.19% (611/320000*100) of all email traffic, not that bad for a command-line tool!
      • @@ -617,16 +667,16 @@ See the Wikipedia Highest use rate: about 56 M IMAP mailbox transfers by just one host (it was in 2014).
      • Biggest known account migrated: 2.4 M folders (figure independently reported).
      • -
      • Operating systems run by the visual /X online imapsync users: +
      • Operating systems run by the visual /X online imapsync users in 2021: +
          -
        • Windows 70%
        • -
        • Macintosh 23%
        • +
        • Windows 71%
        • +
        • Macintosh 22%
        • Linux 7%
        • +
        • iPhone 0.22%
        • +
        • iPad 0.03%
        • +
        • Android 0.02%
      • @@ -869,6 +923,7 @@ you some struggling hours later, believe me. So read the three columns main
      • Office365.
      • Exchange 20xx.
      • +
      • iCloud.
      • Yahoo.
      • Domino.
      • Zimbra.
      • @@ -989,7 +1044,7 @@ like written in the https://imapsync.lamiral.info/LICENSE This document last modified on -($Id: index.shtml,v 1.511 2022/04/06 10:38:35 gilles Exp gilles $)
        +($Id: index.shtml,v 1.516 2022/05/24 11:58:23 gilles Exp gilles $)
        Top of the page

        diff --git a/oauth2/README_OAUTH2.txt b/oauth2/README_OAUTH2.txt old mode 100755 new mode 100644 index 162ab19..3f0c576 --- a/oauth2/README_OAUTH2.txt +++ b/oauth2/README_OAUTH2.txt @@ -1,5 +1,5 @@ -# $Id: README_OAUTH2.txt,v 1.1 2021/07/06 01:45:43 gilles Exp gilles $ +# $Id: README_OAUTH2.txt,v 1.2 2022/07/25 16:44:43 gilles Exp gilles $ 1) Do you have a refresh_token? Yes: Good! @@ -12,8 +12,7 @@ No: Get one. How? Run the commands: You will be asked to go to a long url with a browser, like this: To authorize token, visit this url and follow the directions: -https://accounts.google.com/o/oauth2/auth?client_id=108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com&redirect_uri=urn%3Aietf% -3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fmail.google.com%2F +https://accounts.google.com/o/oauth2/auth?client_id=108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fmail.google.com%2F Go to this url, the url above should be the same as presented by the script. diff --git a/tests.sh b/tests.sh index 3c7d431..e26cb15 100644 --- a/tests.sh +++ b/tests.sh @@ -1,6 +1,6 @@ #!/bin/sh -# $Id: tests.sh,v 1.372 2022/04/06 10:07:32 gilles Exp gilles $ +# $Id: tests.sh,v 1.374 2022/09/15 08:43:20 gilles Exp gilles $ # To run these tests, you need a running imap server somewhere # with several accounts. And be on Linux or Unix. @@ -3604,7 +3604,7 @@ ll_useheader_noheader() --passfile2 ../../var/pass/secret.titi \ --folder INBOX.yop.yap \ --useheader 'NoExist' \ - --debug --delete2 + --debug --delete2 --addheader echo 'rm /home/vmail/titi/.yop.yap/cur/*' } @@ -5528,11 +5528,12 @@ easygmail_gmail1_gmail2() { --justfolders } -easygmail_gmail2() { +easygmail_gmail2() +{ $CMD_PERL ./imapsync \ --user1 gilles.lamiral@gmail.com \ --passfile1 ../../var/pass/secret.gilles_gmail \ - --host1 imap.gmail.com --ssl1 \ + --host1 imap.gmail.com \ --gmail2 \ --user2 imapsync.gl@gmail.com \ --passfile2 ../../var/pass/secret.imapsync.gl_gmail \ @@ -5611,7 +5612,6 @@ all_login_tests() } - gmail_glX_all_justlogin() { error_list="" @@ -5626,9 +5626,29 @@ test "X$error_list" = X; } +gmail_glX_all_justfolderlist() +{ +error_list="" +for X in "" 0 1 2 3; do + $CMD_PERL ./imapsync \ + --gmail1 --user1 imapsync.gl${X}@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl${X}_gmail \ + --gmail2 --user2 imapsync.gl${X}@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl${X}_gmail \ + --no-modulesversion --justfolderlists --nocheckfoldersexist || { error_list="${error_list}[imapsync.gl${X}@gmail.com] " ; } +done +echo3 "error_list=$error_list" +test "X$error_list" = X; +} -gmail_gmail() { +gmail_gmail_slash_in_foldername() +{ + ./imapsync --gmail1 --user1 imapsync.gl1@gmail.com --passfile1 ../../var/pass/secret.imapsync.gl1_gmail \ + --gmail2 --user2 imapsync.gl2@gmail.com --passfile2 ../../var/pass/secret.imapsync.gl2_gmail \ + --no-modulesversion --dry --justfolders +} + +gmail_gmail() +{ ! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \ --host1 imap.gmail.com \ --user1 gilles.lamiral@gmail.com \ @@ -5636,9 +5656,37 @@ gmail_gmail() { --host2 imap.gmail.com \ --user2 imapsync.gl@gmail.com \ --passfile2 ../../var/pass/secret.imapsync.gl_gmail \ - --justfolders --exclude Gmail --exclude "blanc\ $" + --justfolders --exclude Gmail --exclude "blanc\ $" } +gmail_gmail_exclude() +{ + ! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \ + --host1 imap.gmail.com \ + --user1 gilles.lamiral@gmail.com \ + --passfile1 ../../var/pass/secret.gilles_gmail \ + --host2 imap.gmail.com \ + --user2 imapsync.gl@gmail.com \ + --passfile2 ../../var/pass/secret.imapsync.gl_gmail \ + --justfolders --exclude "/Trash" +} + + + + +gmail_gmail_inet4() { + ! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \ + --host1 imap.gmail.com \ + --user1 gilles.lamiral@gmail.com \ + --passfile1 ../../var/pass/secret.gilles_gmail \ + --host2 imap.gmail.com \ + --user2 imapsync.gl@gmail.com \ + --passfile2 ../../var/pass/secret.imapsync.gl_gmail \ + --justlogin --inet4 +} + + + gmail_gmail_ipv6() { ! ping6 -c1 imap.gmail.com || $CMD_PERL ./imapsync \