This commit is contained in:
Nick Bebout 2021-08-04 14:14:36 -05:00
parent 4ce248c075
commit f26b2573c3
370 changed files with 14441 additions and 136699 deletions

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: cgi_memo,v 1.54 2020/01/04 00:13:49 gilles Exp gilles $
# $Id: cgi_memo,v 1.73 2021/06/30 20:10:12 gilles Exp gilles $
if test -n "$1"; then
echoq() { echo "$@" ; } # not quiet mode
@ -8,55 +8,150 @@ else
echoq() { : ; } # quiet mode: nop
fi
run_test() {
tests_count=`expr 1 + $tests_count`
# do not run anything between the two following instructions
"$@"; run_test_status=$?
# now you can run something since $? is saved
if test x"$run_test_status" = x"0"; then
echo "ok $tests_count $@"
else
echo "not ok $tests_count $@"
tests_failed_count=`expr 1 + $tests_failed_count`
tests_failed_list="$tests_failed_list $tests_count"
fi
return $run_test_status
}
run_tests() {
tests_count=0
tests_failed_count=0
tests_failed_list=
for t in "$@"; do
echo "### running $t"
"$t"
done
echo
echo "#### ALL tests done"
if test 0 -eq $tests_failed_count; then
echo "ALL $tests_count TESTS SUCCESSFUL"
return 0
else
# At least one failed
echo "FAILED $tests_failed_count/$tests_count TESTS: $tests_failed_list"
return 1
fi
}
tests()
{
:
# All tests
run_tests \
tests_pattern_filename
}
tests_all_verbose_if_failure()
{
# Run tests silent but if failure then rerun them verbose.
# return 0 if all tests passed
# return 1 if some tests failed
if ! tests > /dev/null 3>&1 ; then
tests
return 1
fi
return 0
}
#### Variable definitions
tests_count=0
tests_failed_count=0
here_is_freebsd()
{
test FreeBSD = `uname -s`
}
here_is_linux()
{
test Linux = `uname -s`
}
echoq list_all_logs
list_all_logs() {
list_all_logs()
{
cat list_all_logs.txt
}
echoq list_all_logs_generate
list_all_logs_generate() {
list_all_logs_generate()
{
echo Result in list_all_logs.txt
sortmtimef . | grep -v 385d7a4d8d428d7aa2b57c8982629e2bd67698ed/ | grep /LOG_imapsync/ > list_all_logs.txt.tmp
sortmtimef . | grep -v perl.core.txt | grep -v 385d7a4d8d428d7aa2b57c8982629e2bd67698ed/ | grep \./......................................../ | grep \.txt > list_all_logs.txt.tmp
mv list_all_logs.txt.tmp list_all_logs.txt
}
list_log_matching()
{
pattern="$1"
# Ignore no args runs going to 385d7a4d8d428d7aa2b57c8982629e2bd67698ed
cat list_all_logs_auto.txt | grep -v 385d7a4d8d428d7aa2b57c8982629e2bd67698ed | egrep -- "$pattern"
}
echoq biggest_transfer
biggest_transfer() {
biggest_transfer()
{
bytestohuman `datamash_file_op_index G_Total_bytes_transferred.txt max 5`
}
echoq total_bytes_transferred
total_bytes_transferred() {
total_bytes_transferred()
{
datamash_file_op_index G_Total_bytes_transferred.txt sum 5
}
# Total volume transferred
echoq total_volume_transferred
total_volume_transferred() {
total_volume_transferred()
{
#echo -n 'numfmt --to=iec-i '
bytestohuman `total_bytes_transferred`
}
echoq total_messages_transferred
total_messages_transferred() {
total_messages_transferred()
{
datamash_file_op_index G_Messages_transferred.txt sum 4 %16.0f | tr -d ' '
}
longest_transfer() {
printf "%.0f\n" `datamash_file_op_index G_Transfer_time.txt max 4`
longest_transfer()
{
LC_ALL=C printf "%.0f\n" `datamash_file_op_index G_Transfer_time.txt max 4`
}
echoq number_and_pids_of_imapsync_running
number_and_pids_of_imapsync_running() {
number_and_pids_of_imapsync_running()
{
echo "`number_of_imapsync_running` : `pids_of_imapsync_running`"
: # always return true
}
echoq number_of_imapsync_running
number_of_imapsync_running() {
number_of_imapsync_running()
{
pids_of_imapsync_running | wc -w
: # always return true
}
@ -127,14 +222,67 @@ EOF
echoq 'grep_stats_from_list_all_logs # long'
grep_stats_from_list_all_logs() {
echo results in grep_stats.txt
# remove empty lines because it would grep all lines of all logs
sed -i".bak" '/^[[:space:]]*$/d' stat_patterns.txt
list_all_logs | tr '\n' '\000'| xargs -0 egrep -i -f stat_patterns.txt > grep_stats.txt.tmp
mv grep_stats.txt.tmp grep_stats.txt
}
tests_pattern_filename()
{
run_test test "" = "`pattern_filename`"
run_test test "abcd" = "`pattern_filename abcd`"
run_test test "ab_0123__4567_cd" = "`pattern_filename ab[0123][4567]cd`"
run_test test "ab_cd" = "`pattern_filename ab cd`"
run_test test "ab_cd" = "`pattern_filename ab cd `"
run_test test "abcd" = "`pattern_filename ab\&cd`"
run_test test "abcd" = "`pattern_filename ab""cd`"
run_test test "abcd" = "`pattern_filename ab""cd`"
run_test test "ab_cd" = "`pattern_filename ab" "cd`"
run_test test "ab__cd" = "`pattern_filename ab" "cd`"
run_test test "ab__cd" = "`pattern_filename ab "" cd`"
run_test test "ab___cd" = "`pattern_filename ab " " cd`"
run_test test "ab____cd" = "`pattern_filename ab " " cd`"
run_test test "ab____cd" = "`pattern_filename ab " " cd`"
run_test test "ab_____cd" = "`pattern_filename ab " " cd`"
run_test test "a_b_c_d" = "`pattern_filename a b c d`"
}
pattern_filename()
{
echo "$@" | tr ' .[]' '____' | tr -cd '0-9a-zA-Z_.'
}
echoq 'grep_stats_from_list_log_matching lognamepattern'
grep_stats_from_list_log_matching() {
pattern="$1"
pattern_filename=`pattern_filename "$pattern"`
results_filename=grep_stats_"$pattern_filename".txt
echo results in "$results_filename"
# remove empty lines because it would grep all lines of all logs
sed -i".bak" '/^[[:space:]]*$/d' stat_patterns.txt
list_log_matching "$pattern" | tr '\n' '\000'| xargs -0 egrep -i -f stat_patterns.txt > "$results_filename".tmp
mv "$results_filename".tmp "$results_filename"
}
grep_any() {
file=G_`echo "$1" | tr ' .' '__' | tr -cd '0-9a-zA-Z_.\n'`.txt
pattern_filtered=`pattern_filename "$1" "$2"`
file="G_${pattern_filtered}.txt"
echo $file
egrep -i "$1" grep_stats.txt > $file.tmp
egrep -i "$1" grep_stats_"$2".txt > $file.tmp
mv $file.tmp $file
}
@ -143,31 +291,49 @@ grep_load() {
egrep -o 'Load is ..?\... ..?\... ..?\... .*' grep_stats.txt > G_Load.txt
}
grep_all2() {
for k in "$@" ; do
grep_any "$k"
done
}
echoq 'grep_all_stat_from_patterns_list # long'
echoq 'grep_all_stat_from_patterns_list lognamepattern # long'
grep_all_stat_from_patterns_list() {
grep_load
stat_patterns_list | while read k; do grep_all2 "$k" ; done
#grep_load
stat_patterns_list | while read k; do grep_any "$k" "$1"; done
}
stat_patterns_list() {
cat stat_patterns.txt | tr -d '^'
cat stat_patterns.txt | sed '/^[[:space:]]*$/d' | tr -d '^'
}
sum_first_column_G_HTTP_USER_AGENT_sorted()
{
awk '{sum += $1} END {print sum}' G_HTTP_USER_AGENT_sorted.txt
}
stat_useragent_X()
{
grep -o 'HTTP_USER_AGENT.*' G_HTTP_USER_AGENT.txt \
| tail -10000000 | sort | egrep -o -w 'Mozilla/5.0 \([^;]+' \
| sort | egrep -o '\([a-zA-Z]+' | sort | uniq -c | sort -g \
| grep -v KHTML | tr -d '('
| grep -v KHTML | tr -d '(' > G_HTTP_USER_AGENT_sorted.txt
}
echoq 'percent_stat_useragent_X'
percent_stat_useragent_X()
{
stat_useragent_X
sum_first_column_G_HTTP_USER_AGENT=`sum_first_column_G_HTTP_USER_AGENT_sorted`
{ while read num_useragent useragent ; do
#echo KK $num_useragent $useragent
PerCent=`echo "scale=2; 100*$num_useragent/$sum_first_column_G_HTTP_USER_AGENT" | bc -l`
echo "$useragent $PerCent % ( $num_useragent / $sum_first_column_G_HTTP_USER_AGENT )"
done
} < G_HTTP_USER_AGENT_sorted.txt
}
stat_load()
{
echo -n 'Load 1 min 5 min 15 min ' ; grep -o 'on.*cores' G_Load.txt|uniq
@ -198,27 +364,34 @@ stat_exit_value_by_value()
datamash_file_op_index() {
datamash_file_op_index() {
file="$1"
op="${2:-mean}"
index="${3:-4}" # the four field by default
format="${4:-%16.1f}" # --format=%16.1f by default
datamash --format="$format" -W "$op" "$index" < "$file"
}
func="${5:-}"
val_datamash_file_op_index=`LC_ALL=C datamash --format="$format" -W "$op" "$index" < "$file"`
func_return=
test -n "$func" && func_return=`eval $func $val_datamash_file_op_index`
echo "$val_datamash_file_op_index" $func_return
}
stat_any() {
file="$1"
index=${2:-4} # the four field by default
func="${3:-}"
for op in \
"min " \
"q1 " \
"median" \
"mean " \
"q3 " \
"max " \
"min " \
"perc:10 " \
"q1 " \
"median " \
"mean " \
"q3 " \
"perc:90 " \
"max " \
do
echo -n "$file $index $op " ; datamash_file_op_index $file $op $index
echo -n "$file $index $op " ; datamash_file_op_index $file $op $index %16.1f $func
done
echo
}
@ -229,7 +402,7 @@ echoq stat_all
stat_all()
{
stat_load ; echo
stat_useragent_X ; echo
# stat_any G_REMOTE_ADDR.txt
# stat_any G_REMOTE_HOST.txt
# stat_any G_HTTP_COOKIE.txt
@ -257,6 +430,8 @@ stat_all()
#
stat_any G_Transfer_time.txt
stat_any G_Host1_Total_size.txt
stat_any G_Host2_Total_size.txt
stat_any G_Total_bytes_transferred.txt 5
stat_any G_Message_rate.txt
stat_any G_Average_bandwidth_rate.txt 5
@ -265,6 +440,7 @@ stat_all()
stat_any G_Exiting_with_return_value.txt 5 # GROUP
stat_any G_Memory_consumption_at_the_end.txt 7
#stat_any G_failure_Error_login.txt
percent_stat_useragent_X ; echo
stat_exit_value
echo "Data made at" `date -r grep_stats.txt`
@ -287,7 +463,7 @@ stat_queue_mean()
stat_throuput_since_day_one_in_days=`stat_throuput_since_day_one_in_days`
stat_transfer_time_mean=`stat_transfer_time_mean`
stat_queue_mean_raw=`c "$stat_throuput_since_day_one_in_days * $stat_transfer_time_mean / 3600 / 24"`
printf "%2.2f\n" $stat_queue_mean_raw
LC_ALL=C printf "%2.2f\n" $stat_queue_mean_raw
}
echoq dirs_of_syncs_finished_recently
@ -310,9 +486,8 @@ logfiles_finished_recently()
find . -maxdepth 1 -mtime "${1:--1}" | grep -v "385d7a4d8d428d7aa2b57c8982629e2bd67698ed" | egrep [a-f0-9]{40} | while read d; do
test -f "$d" && continue
test -f $d/imapsync.pid && continue
test -d $d/LOG_imapsync || continue
# { ls -trb $f/LOG_imapsync/* ; }
ls -trb `find $d/LOG_imapsync/ -type f -mtime "${1:--1}"`
test -d $d/ || continue
ls -trb `find $d/ -type f -mtime "${1:--1}" | grep \.txt`
done
}
}
@ -324,7 +499,7 @@ last_dirs_written()
last_file_written_in_dir()
{
ls -trd $1/LOG_imapsync/* |tail -1
ls -trd $1/*.txt |tail -1
}
is_dir_running_imapsync()
@ -460,7 +635,7 @@ pidfiles_running_and_not_running() {
{ ps -p $PID -o comm= | tr '\n' ' ' && { test -f /proc/$PID/oom_score &&
{ echo -12 > /proc/$PID/oom_adj ; } && echo -n "oom_score " && cat /proc/$PID/oom_score | tr '\n' ' ' ; : ; }
} &&
{ ls -tr $f/LOG_imapsync/* |tail -1 ; }
{ ls -tr $f/*.txt |tail -1 ; }
done
}
@ -487,7 +662,7 @@ pidfiles_not_running() {
if pidfile_dandling "$f" ; then
pidfiles_not_running_PID=`head -1 $f/imapsync.pid`
echo -n "rm $f/imapsync.pid # "
{ ls -tr $f/LOG_imapsync/* 2>/dev/null |tail -1 ; } | tr '\n' ' '
{ ls -tr $f/*.txt 2>/dev/null |tail -1 ; } | tr '\n' ' '
echo "# PID $pidfiles_not_running_PID"
#head -2 $f/imapsync.pid
fi
@ -550,16 +725,16 @@ echoq summary_run
summary_run() {
for summary_run_DIR in "$@"; do
echo Analysing $summary_run_DIR
echo -n "Nb logs: "; ls $summary_run_DIR/LOG_imapsync/*.txt | wc -l
summary_run_LOGS_LIST=`ls $summary_run_DIR/LOG_imapsync/*.txt`
echo -n "Nb logs: "; ls $summary_run_DIR/*.txt | wc -l
summary_run_LOGS_LIST=`ls $summary_run_DIR/*.txt`
echo -n "List logs: "; echo $summary_run_LOGS_LIST
#echo connect failure
summary_run_CONNECT_FAIL=`grep -i 'failure: can not open imap connection on' $summary_run_DIR/LOG_imapsync/*.txt|wc -l`
summary_run_CONNECT_FAIL=`grep -i 'failure: can not open imap connection on' $summary_run_DIR/*.txt|wc -l`
echo CONN $summary_run_CONNECT_FAIL
#echo login failure
grep -i 'failure: Error login on' $summary_run_DIR/LOG_imapsync/*.txt
grep -i 'failure: Error login on' $summary_run_DIR/*.txt
#echo Differences
grep -i "difference host2 - host1" $summary_run_DIR/LOG_imapsync/*.txt
grep -i "difference host2 - host1" $summary_run_DIR/*.txt
done
}
@ -567,14 +742,14 @@ summary_run() {
logs_nb() {
logs_nb_DIR="$1"
logs_nb_LOGS_LIST="$logs_nb_DIR"/LOG_imapsync/*.txt
logs_nb_LOGS_LIST="$logs_nb_DIR"/*.txt
}
vnstat_init() {
test FreeBSD = `uname -s` && VNSTATI_DIR=/usr/local/www/apache24/data/vnstat/
test Linux = `uname -s` && VNSTATI_DIR=/var/www/vnstat/
test FreeBSD = `uname -s` && VNSTATI_DIR=/usr/local/www/apache24/data/vnstat
test Linux = `uname -s` && VNSTATI_DIR=/var/www/vnstat
test -d $VNSTATI_DIR || mkdir -p $VNSTATI_DIR
}
@ -587,6 +762,20 @@ vnstat_gen() {
done
}
echoq vnstat_index_hs
vnstat_index_hs()
{
(
vnstat_init || return
cd $VNSTATI_DIR/ || return
for f in `ls -r ./*/vnstat_hs.png`
do
echo '<img src="'$f'" border="0" alt="hourly"><br>'
done > index_hs.html
)
}
echoq vnstat_archive
vnstat_archive() {
(
@ -596,7 +785,8 @@ vnstat_archive() {
mkdir $VNSTATI_DIR/$now_ymdhms/ || return
cd $VNSTATI_DIR/$now_ymdhms/ || return
test "$1" && pwd
ln ../*.png ../*.html .
cp -a ../*.png ../*.html .
)
test "$1" && pwd
}
@ -634,37 +824,55 @@ nb_syncs_badly_finished()
| awk -v nb_logfiles_finished_recently=$nb_logfiles_finished_recently \
'{ printf "%.2g%% %s\n", 100*$1/nb_logfiles_finished_recently, $0 }'
cat <<EOF
logfiles_finished_recently $1 | xargs grep -i 'Exiting with return value' | grep -v 'return value 0'
logfiles_finished_recently $1 | xargs grep -i 'Exiting with return value' | grep -v 'return value 0 ' | cut -d: -f1 | xargs tail -11
EOF
}
echoq 'referrer_of_x /var/log/apache2/imapsync_access.log /var/log/apache/httpd-access.log | sort | uniq -c | sort -n'
echoq 'referrer_of_x /var/log/apache/access.log_2021*.gz | sort | uniq -c | sort -n'
referrer_of_x() {
zegrep -h -s -o 'GET /X/? .*http[^"]+' "${@:-/var/log/apache2/imapsync_access.log}" | grep -o 'http.*'
zegrep -h -s -o 'GET /X/? .*http[^"]+' "${@:-/var/log/apache/access.log}" | grep -o 'http.*'
}
biggest_message_seen() {
datamash -W max 4 < G_Biggest_message.txt | xargs bytestohuman
cat G_Biggest_message.txt | grep -v Memory| datamash -W max 4 | xargs bytestohuman
}
biggest_message_transferred() {
# With this, the "Biggest message" could not be transferred by imapsync itself.
grep 'Host2 Biggest message' < G_Biggest_message.txt | datamash -W max 4 | xargs bytestohuman
}
biggest_bandwidth_rate() {
datamash_file_op_index G_Average_bandwidth_rate.txt max 5 | tr -d ' ' | tr '\n' ' '
echo KiB/s
}
average_bandwidth_rate() {
datamash_file_op_index G_Average_bandwidth_rate.txt mean 5 | tr -d ' ' | tr '\n' ' '
echo KiB/s
}
max_number_of_messages_transferred() {
datamash_file_op_index G_Messages_transferred.txt max 4 "%.0f"
}
max_number_of_messages_skipped() {
datamash_file_op_index G_Messages_skipped.txt max 4 "%.0f"
}
echoq number_of_X_users
number_of_X_users() {
datamash_file_op_index G_REMOTE_ADDR.txt unique 3 | tr , '\n' | wc -l
}
echoq summary_compute2
summary_compute2() {
echoq summary_compute
summary_compute() {
list_all_logs_generate \
&& grep_stats_from_list_all_logs \
&& grep_all_stat_from_patterns_list \
@ -712,7 +920,7 @@ count_imap_server_all()
}
echoq server_survey_percent
#echoq server_survey_percent
server_survey_percent()
{
@ -738,7 +946,7 @@ server_survey_percent()
}
echoq server_survey
#echoq server_survey
server_survey()
{
banners_files=${1:-G_Host1_banner.txt}
@ -794,8 +1002,6 @@ server_survey_host2()
}
echoq summary_display
summary_display() {
vnstat_gen > /dev/null
@ -808,7 +1014,10 @@ summary_display() {
echo -n "Biggest transfer: " ; biggest_transfer
echo -n "Biggest message seen: " ; biggest_message_seen
echo -n "Biggest message transferred: " ; biggest_message_transferred
echo -n "Biggest bandwidth rate: " ; biggest_bandwidth_rate
echo -n "Biggest bandwidth rate: " ; biggest_bandwidth_rate
echo -n "Average bandwidth rate: " ; average_bandwidth_rate
echo -n "Max messages transferred: " ; max_number_of_messages_transferred
echo -n "Max messages skipped: " ; max_number_of_messages_skipped
echo -n "Longest transfer: " ; seconds_to_days_hours `longest_transfer`
echo -n "Queue length mean is: " ; stat_queue_mean
echo "Data made at" `date -r grep_stats.txt`
@ -825,7 +1034,7 @@ sync_ks2_i005()
&& date \
&& cd /home/imapsync_cgi_ks2/ \
&& rsync -a root@ks2:/var/tmp/imapsync_cgi/ /home/imapsync_cgi_ks2/ \
&& summary_compute2 \
&& summary_compute \
&& echo sending txt back to ks2 \
&& rsync -av /home/imapsync_cgi_ks2/*txt root@ks2:/var/tmp/imapsync_cgi/ \
&& summary_display \
@ -864,6 +1073,61 @@ watch_number_of_imapsync_running()
sleep 6
date_if_new_hour
done
}
#echoq number_of_bytes_sent_received_per_second_during
number_of_bytes_sent_received_per_second_during()
{
# $1 : number of seconds to watch
here_is_freebsd && netstat -I em0 -w ${1:-1} -q 1 | tail -1 | awk -v sec="${1:-1}" '{ printf "%.0f", ($4+$7)/sec }'
here_is_linux && number_of_bytes_sent_received_per_second_during_linux ${1:-1}
}
number_of_bytes_sent_received_per_second_during_linux()
{
tx_1=`cat /sys/class/net/eth0/statistics/tx_bytes`
rx_1=`cat /sys/class/net/eth0/statistics/rx_bytes`
sleep ${1:-1}
tx_2=`cat /sys/class/net/eth0/statistics/tx_bytes`
rx_2=`cat /sys/class/net/eth0/statistics/rx_bytes`
c $tx_2 - $tx_1 + $rx_2 - $rx_1
}
div_1_by_2_or_zero()
{
if test X"$2" = X"0"; then
echo "0"
else
echo "$1 $2" | awk '{ printf "%.0f\n", $1/$2 }'
fi
}
echoq number_of_imapsync_running_bandwidth
number_of_imapsync_running_bandwidth()
{
nir=`number_of_imapsync_running`
nbsr=`number_of_bytes_sent_received_per_second_during ${1:-1}`
ratio=`div_1_by_2_or_zero $nbsr $nir`
date=`date_ymdhms`
date_u=`LANG= date -u`
nbsr_human=`bytestohuman $nbsr`
ratio_human=`bytestohuman $ratio`
echo "$date $nir $nbsr $ratio $nbsr_human$ratio_human"
echo "Current number of syncs: $nir; Current total bandwidth: $nbsr_human/s; Current bandwidth per sync: $ratio_human/s; Current date/time: $date_u; ">/var/tmp/imapsync_current.txt
}
echoq loop_number_of_imapsync_running_bandwidth
loop_number_of_imapsync_running_bandwidth()
{
while :
do
:
nirbd=`number_of_imapsync_running_bandwidth ${1:-1}`
echo $nirbd
echo $nirbd >> /var/tmp/number_of_imapsync_running_every_${1:-1}s.txt
done
}
@ -883,6 +1147,32 @@ datamash -s -W -g 4 count 4 < G_Host1_IMAP_server.txt | awk '{ print $2 " " $1 }
datamash -s -W -g 4 count 4 < G_Host2_IMAP_server.txt | awk '{ print $2 " " $1 }' | sort -g | tail -22
egrep -o '* ID .*' G_Read___ID.txt | sort | awk '{ print $1 " " $2 " " $3 " NIL" }' | datamash -s -W -g 3 count 3 | awk '{ print $2 " " $1 }' | sort -g
locate perl.core | xargs -n 1 gdb -q -x /tmp/gdb_quit.txt -c
zcat /var/log/apache/httpd-access.log.*.gz|egrep -o -w 'Mozilla/5.0 \([^;]+' | sort | egrep -o '\([a-zA-Z]+' | sort | uniq -c | sort -g | grep -v KHTML
zcat /var/log/apache/httpd-access.log.*.gz|grep 'POST /cgi-bin/imapsync' | egrep -o -w 'Mozilla/5.0 \([^;]+' | sort | egrep -o '\([a-zA-Z]+' | sort | uniq -c | sort -g | grep -v KHTML
egrep -o '\[.+@[^]]+]' G_success_login.txt |head -222222 | sort | uniq -c | sort -g
list_all_logs |tail -9999 | xargs grep -i 'Exiting with return value 112' | tee Error_112_last_9999_syncs.txt
cut -d: -f1 Error_112_last_30_days.txt | xargs grep -oih 'Invalid system flag.*' | sort | uniq -c
list_all_logs | xargs grep -i 'Exiting with return value 112' | tee Error_112_all_syncs.txt
cut -d: -f1 Error_112_all_syncs.txt | tail -100 | xargs egrep -oih 'Invalid system flag [^(]+' | sort | uniq -c
cat G_success_login_on.txt | ./domains_servers_map | sort | uniq -c | sort -g
logfiles_finished_recently -300| xargs grep -i 'Exiting with return value 10 ' | grep -v 'return value 0 ' | cut -d: -f1 | xargs tail -11 | grep 'failure: can not open imap connection on' | uniq -c | sort -g | grep http | tee ../http_host_failures.txt
# Searching big messages copied over 500 MB
list_all_logs|tail -50000 | xargs egrep '{.?[56789]........} copied'
# online processes stats
cat /var/tmp/number_of_imapsync_running.txt | datamash -W min 2 max 2 mean 2 median 2 q1 2 q3 2
for v in 2 3 4; do cat /var/tmp/number_of_imapsync_running_every_6s.txt | datamash --format=%10.0f -W min $v max $v mean $v median $v q1 $v q3 $v ; done
netstat -I em0 -b -n -w 6 -q 1
while :; do ssh root@ks5 'cd /var/tmp/imapsync_cgi/ ; . cgi_memo ; loop_number_of_imapsync_running_bandwidth 6' ; echo $?; done
# Search memory eater
cat G_Memory_consumption_at_the_end.txt | sort -g -k7 | grep 202[01] |tail -100 | cut -f1 -d: | while read f; do echo $f ; grep 'Memory consumption at the end' $f; grep 'Host. Nb messages' $f ; grep 'Biggest message' $f ; grep 'Memory/biggest message ratio' $f ; done
cat G_Host2_Nb_messages.txt | sort -g -k4 | grep 202[01] |tail -100 | cut -f1 -d: | while read f; do echo $f ; grep 'Memory consumption at the end' $f; grep 'Host. Nb messages' $f ; grep 'Biggest message' $f ; grep 'Memory/biggest message ratio' $f ; done
cat G_Host1_Nb_messages.txt | sort -g -k4 | grep 202[01] |tail -100 | cut -f1 -d: | while read f; do echo $f ; grep 'Memory consumption at the end' $f; grep 'Host. Nb messages' $f ; grep 'Biggest message' $f ; grep 'Memory/biggest message ratio' $f ; done
EOF
}
@ -901,3 +1191,6 @@ perf_help() {
echo "iftop -i eth0 -f 'port imap or port imaps' -B # t p >"
}
}
tests_all_verbose_if_failure

777
X/crypto-js/core.js Normal file
View file

@ -0,0 +1,777 @@
/*globals window, global, require*/
/**
* CryptoJS core components.
*/
var CryptoJS = CryptoJS || (function (Math, undefined) {
var crypto;
// Native crypto from window (Browser)
if (typeof window !== 'undefined' && window.crypto) {
crypto = window.crypto;
}
// Native (experimental IE 11) crypto from window (Browser)
if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
crypto = window.msCrypto;
}
// Native crypto from global (NodeJS)
if (!crypto && typeof global !== 'undefined' && global.crypto) {
crypto = global.crypto;
}
// Native crypto import via require (NodeJS)
if (!crypto && typeof require === 'function') {
try {
crypto = require('crypto');
} catch (err) {}
}
/*
* Cryptographically secure pseudorandom number generator
*
* As Math.random() is cryptographically not safe to use
*/
var cryptoSecureRandomInt = function () {
if (crypto) {
// Use getRandomValues method (Browser)
if (typeof crypto.getRandomValues === 'function') {
try {
return crypto.getRandomValues(new Uint32Array(1))[0];
} catch (err) {}
}
// Use randomBytes method (NodeJS)
if (typeof crypto.randomBytes === 'function') {
try {
return crypto.randomBytes(4).readInt32LE();
} catch (err) {}
}
}
throw new Error('Native crypto module could not be used to get secure random number.');
};
/*
* Local polyfill of Object.create
*/
var create = Object.create || (function () {
function F() {}
return function (obj) {
var subtype;
F.prototype = obj;
subtype = new F();
F.prototype = null;
return subtype;
};
}())
/**
* CryptoJS namespace.
*/
var C = {};
/**
* Library namespace.
*/
var C_lib = C.lib = {};
/**
* Base object for prototypal inheritance.
*/
var Base = C_lib.Base = (function () {
return {
/**
* Creates a new object that inherits from this object.
*
* @param {Object} overrides Properties to copy into the new object.
*
* @return {Object} The new object.
*
* @static
*
* @example
*
* var MyType = CryptoJS.lib.Base.extend({
* field: 'value',
*
* method: function () {
* }
* });
*/
extend: function (overrides) {
// Spawn
var subtype = create(this);
// Augment
if (overrides) {
subtype.mixIn(overrides);
}
// Create default initializer
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
subtype.init = function () {
subtype.$super.init.apply(this, arguments);
};
}
// Initializer's prototype is the subtype object
subtype.init.prototype = subtype;
// Reference supertype
subtype.$super = this;
return subtype;
},
/**
* Extends this object and runs the init method.
* Arguments to create() will be passed to init().
*
* @return {Object} The new object.
*
* @static
*
* @example
*
* var instance = MyType.create();
*/
create: function () {
var instance = this.extend();
instance.init.apply(instance, arguments);
return instance;
},
/**
* Initializes a newly created object.
* Override this method to add some logic when your objects are created.
*
* @example
*
* var MyType = CryptoJS.lib.Base.extend({
* init: function () {
* // ...
* }
* });
*/
init: function () {
},
/**
* Copies properties into this object.
*
* @param {Object} properties The properties to mix in.
*
* @example
*
* MyType.mixIn({
* field: 'value'
* });
*/
mixIn: function (properties) {
for (var propertyName in properties) {
if (properties.hasOwnProperty(propertyName)) {
this[propertyName] = properties[propertyName];
}
}
// IE won't copy toString using the loop above
if (properties.hasOwnProperty('toString')) {
this.toString = properties.toString;
}
},
/**
* Creates a copy of this object.
*
* @return {Object} The clone.
*
* @example
*
* var clone = instance.clone();
*/
clone: function () {
return this.init.prototype.extend(this);
}
};
}());
/**
* An array of 32-bit words.
*
* @property {Array} words The array of 32-bit words.
* @property {number} sigBytes The number of significant bytes in this word array.
*/
var WordArray = C_lib.WordArray = Base.extend({
/**
* Initializes a newly created word array.
*
* @param {Array} words (Optional) An array of 32-bit words.
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
*
* @example
*
* var wordArray = CryptoJS.lib.WordArray.create();
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
*/
init: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes != undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 4;
}
},
/**
* Converts this word array to a string.
*
* @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
*
* @return {string} The stringified word array.
*
* @example
*
* var string = wordArray + '';
* var string = wordArray.toString();
* var string = wordArray.toString(CryptoJS.enc.Utf8);
*/
toString: function (encoder) {
return (encoder || Hex).stringify(this);
},
/**
* Concatenates a word array to this word array.
*
* @param {WordArray} wordArray The word array to append.
*
* @return {WordArray} This word array.
*
* @example
*
* wordArray1.concat(wordArray2);
*/
concat: function (wordArray) {
// Shortcuts
var thisWords = this.words;
var thatWords = wordArray.words;
var thisSigBytes = this.sigBytes;
var thatSigBytes = wordArray.sigBytes;
// Clamp excess bits
this.clamp();
// Concat
if (thisSigBytes % 4) {
// Copy one byte at a time
for (var i = 0; i < thatSigBytes; i++) {
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
}
} else {
// Copy one word at a time
for (var i = 0; i < thatSigBytes; i += 4) {
thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
}
}
this.sigBytes += thatSigBytes;
// Chainable
return this;
},
/**
* Removes insignificant bits.
*
* @example
*
* wordArray.clamp();
*/
clamp: function () {
// Shortcuts
var words = this.words;
var sigBytes = this.sigBytes;
// Clamp
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
words.length = Math.ceil(sigBytes / 4);
},
/**
* Creates a copy of this word array.
*
* @return {WordArray} The clone.
*
* @example
*
* var clone = wordArray.clone();
*/
clone: function () {
var clone = Base.clone.call(this);
clone.words = this.words.slice(0);
return clone;
},
/**
* Creates a word array filled with random bytes.
*
* @param {number} nBytes The number of random bytes to generate.
*
* @return {WordArray} The random word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.lib.WordArray.random(16);
*/
random: function (nBytes) {
var words = [];
for (var i = 0; i < nBytes; i += 4) {
words.push(cryptoSecureRandomInt());
}
return new WordArray.init(words, nBytes);
}
});
/**
* Encoder namespace.
*/
var C_enc = C.enc = {};
/**
* Hex encoding strategy.
*/
var Hex = C_enc.Hex = {
/**
* Converts a word array to a hex string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The hex string.
*
* @static
*
* @example
*
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var hexChars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
hexChars.push((bite >>> 4).toString(16));
hexChars.push((bite & 0x0f).toString(16));
}
return hexChars.join('');
},
/**
* Converts a hex string to a word array.
*
* @param {string} hexStr The hex string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
*/
parse: function (hexStr) {
// Shortcut
var hexStrLength = hexStr.length;
// Convert
var words = [];
for (var i = 0; i < hexStrLength; i += 2) {
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
}
return new WordArray.init(words, hexStrLength / 2);
}
};
/**
* Latin1 encoding strategy.
*/
var Latin1 = C_enc.Latin1 = {
/**
* Converts a word array to a Latin1 string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The Latin1 string.
*
* @static
*
* @example
*
* var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var latin1Chars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
latin1Chars.push(String.fromCharCode(bite));
}
return latin1Chars.join('');
},
/**
* Converts a Latin1 string to a word array.
*
* @param {string} latin1Str The Latin1 string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
*/
parse: function (latin1Str) {
// Shortcut
var latin1StrLength = latin1Str.length;
// Convert
var words = [];
for (var i = 0; i < latin1StrLength; i++) {
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
}
return new WordArray.init(words, latin1StrLength);
}
};
/**
* UTF-8 encoding strategy.
*/
var Utf8 = C_enc.Utf8 = {
/**
* Converts a word array to a UTF-8 string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The UTF-8 string.
*
* @static
*
* @example
*
* var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
*/
stringify: function (wordArray) {
try {
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
} catch (e) {
throw new Error('Malformed UTF-8 data');
}
},
/**
* Converts a UTF-8 string to a word array.
*
* @param {string} utf8Str The UTF-8 string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
*/
parse: function (utf8Str) {
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
}
};
/**
* Abstract buffered block algorithm template.
*
* The property blockSize must be implemented in a concrete subtype.
*
* @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
*/
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
/**
* Resets this block algorithm's data buffer to its initial state.
*
* @example
*
* bufferedBlockAlgorithm.reset();
*/
reset: function () {
// Initial values
this._data = new WordArray.init();
this._nDataBytes = 0;
},
/**
* Adds new data to this block algorithm's buffer.
*
* @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
*
* @example
*
* bufferedBlockAlgorithm._append('data');
* bufferedBlockAlgorithm._append(wordArray);
*/
_append: function (data) {
// Convert string to WordArray, else assume WordArray already
if (typeof data == 'string') {
data = Utf8.parse(data);
}
// Append
this._data.concat(data);
this._nDataBytes += data.sigBytes;
},
/**
* Processes available data blocks.
*
* This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
*
* @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
*
* @return {WordArray} The processed data.
*
* @example
*
* var processedData = bufferedBlockAlgorithm._process();
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
*/
_process: function (doFlush) {
var processedWords;
// Shortcuts
var data = this._data;
var dataWords = data.words;
var dataSigBytes = data.sigBytes;
var blockSize = this.blockSize;
var blockSizeBytes = blockSize * 4;
// Count blocks ready
var nBlocksReady = dataSigBytes / blockSizeBytes;
if (doFlush) {
// Round up to include partial blocks
nBlocksReady = Math.ceil(nBlocksReady);
} else {
// Round down to include only full blocks,
// less the number of blocks that must remain in the buffer
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
}
// Count words ready
var nWordsReady = nBlocksReady * blockSize;
// Count bytes ready
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
// Process blocks
if (nWordsReady) {
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
// Perform concrete-algorithm logic
this._doProcessBlock(dataWords, offset);
}
// Remove processed words
processedWords = dataWords.splice(0, nWordsReady);
data.sigBytes -= nBytesReady;
}
// Return processed words
return new WordArray.init(processedWords, nBytesReady);
},
/**
* Creates a copy of this object.
*
* @return {Object} The clone.
*
* @example
*
* var clone = bufferedBlockAlgorithm.clone();
*/
clone: function () {
var clone = Base.clone.call(this);
clone._data = this._data.clone();
return clone;
},
_minBufferSize: 0
});
/**
* Abstract hasher template.
*
* @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
*/
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
/**
* Configuration options.
*/
cfg: Base.extend(),
/**
* Initializes a newly created hasher.
*
* @param {Object} cfg (Optional) The configuration options to use for this hash computation.
*
* @example
*
* var hasher = CryptoJS.algo.SHA256.create();
*/
init: function (cfg) {
// Apply config defaults
this.cfg = this.cfg.extend(cfg);
// Set initial values
this.reset();
},
/**
* Resets this hasher to its initial state.
*
* @example
*
* hasher.reset();
*/
reset: function () {
// Reset data buffer
BufferedBlockAlgorithm.reset.call(this);
// Perform concrete-hasher logic
this._doReset();
},
/**
* Updates this hasher with a message.
*
* @param {WordArray|string} messageUpdate The message to append.
*
* @return {Hasher} This hasher.
*
* @example
*
* hasher.update('message');
* hasher.update(wordArray);
*/
update: function (messageUpdate) {
// Append
this._append(messageUpdate);
// Update the hash
this._process();
// Chainable
return this;
},
/**
* Finalizes the hash computation.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param {WordArray|string} messageUpdate (Optional) A final message update.
*
* @return {WordArray} The hash.
*
* @example
*
* var hash = hasher.finalize();
* var hash = hasher.finalize('message');
* var hash = hasher.finalize(wordArray);
*/
finalize: function (messageUpdate) {
// Final message update
if (messageUpdate) {
this._append(messageUpdate);
}
// Perform concrete-hasher logic
var hash = this._doFinalize();
return hash;
},
blockSize: 512/32,
/**
* Creates a shortcut function to a hasher's object interface.
*
* @param {Hasher} hasher The hasher to create a helper for.
*
* @return {Function} The shortcut function.
*
* @static
*
* @example
*
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
*/
_createHelper: function (hasher) {
return function (message, cfg) {
return new hasher.init(cfg).finalize(message);
};
},
/**
* Creates a shortcut function to the HMAC's object interface.
*
* @param {Hasher} hasher The hasher to use in this HMAC helper.
*
* @return {Function} The shortcut function.
*
* @static
*
* @example
*
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
*/
_createHmacHelper: function (hasher) {
return function (message, key) {
return new C_algo.HMAC.init(hasher, key).finalize(message);
};
}
});
/**
* Algorithm namespace.
*/
var C_algo = C.algo = {};
return C;
}(Math));

179
X/crypto-js/sha256.js Normal file
View file

@ -0,0 +1,179 @@
(function (Math) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
// Initialization and round constants tables
var H = [];
var K = [];
// Compute constants
(function () {
function isPrime(n) {
var sqrtN = Math.sqrt(n);
for (var factor = 2; factor <= sqrtN; factor++) {
if (!(n % factor)) {
return false;
}
}
return true;
}
function getFractionalBits(n) {
return ((n - (n | 0)) * 0x100000000) | 0;
}
var n = 2;
var nPrime = 0;
while (nPrime < 64) {
if (isPrime(n)) {
if (nPrime < 8) {
H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
}
K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
nPrime++;
}
n++;
}
}());
// Reusable object
var W = [];
/**
* SHA-256 hash algorithm.
*/
var SHA256 = C_algo.SHA256 = Hasher.extend({
_doReset: function () {
this._hash = new WordArray.init(H.slice(0));
},
_doProcessBlock: function (M, offset) {
// Shortcut
var H = this._hash.words;
// Working variables
var a = H[0];
var b = H[1];
var c = H[2];
var d = H[3];
var e = H[4];
var f = H[5];
var g = H[6];
var h = H[7];
// Computation
for (var i = 0; i < 64; i++) {
if (i < 16) {
W[i] = M[offset + i] | 0;
} else {
var gamma0x = W[i - 15];
var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
((gamma0x << 14) | (gamma0x >>> 18)) ^
(gamma0x >>> 3);
var gamma1x = W[i - 2];
var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
((gamma1x << 13) | (gamma1x >>> 19)) ^
(gamma1x >>> 10);
W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
}
var ch = (e & f) ^ (~e & g);
var maj = (a & b) ^ (a & c) ^ (b & c);
var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
var t1 = h + sigma1 + ch + K[i] + W[i];
var t2 = sigma0 + maj;
h = g;
g = f;
f = e;
e = (d + t1) | 0;
d = c;
c = b;
b = a;
a = (t1 + t2) | 0;
}
// Intermediate hash value
H[0] = (H[0] + a) | 0;
H[1] = (H[1] + b) | 0;
H[2] = (H[2] + c) | 0;
H[3] = (H[3] + d) | 0;
H[4] = (H[4] + e) | 0;
H[5] = (H[5] + f) | 0;
H[6] = (H[6] + g) | 0;
H[7] = (H[7] + h) | 0;
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
data.sigBytes = dataWords.length * 4;
// Hash final blocks
this._process();
// Return final computed hash
return this._hash;
},
clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
}
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA256('message');
* var hash = CryptoJS.SHA256(wordArray);
*/
C.SHA256 = Hasher._createHelper(SHA256);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA256(message, key);
*/
C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
}(Math));

15
X/domains_servers_map Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/perl
use strict ;
use warnings ;
# Is there a map between account xxx@domain and the imap host server
# cat G_success_login_on.txt | ./domains_servers_map | sort | uniq -c | sort -g
while ( my $line = <> )
{
if ( $line =~ /success login on \[(.*)\] with user \[.*\@(.*)\] auth / )
{
print "$2 $1\n" ;
}
}

699
X/imapsync_csv_wrapper Executable file
View file

@ -0,0 +1,699 @@
#!/bin/sh
# $Id: imapsync_csv_wrapper,v 1.5 2020/05/01 21:26:30 gilles Exp gilles $
exec 3>&1
debug=/bin/true
debug=/bin/false
echo3() {
echo "$@" >&3
}
echodebug()
{
$debug && echo3 "$@"
}
run_test() {
tests_count=`expr 1 + $tests_count`
# do not run anything between the two following instructions
"$@"; run_test_status=$?
# now you can run something since $? is saved
if test x"$run_test_status" = x"0"; then
echo "ok $tests_count $@"
else
echo "not ok $tests_count $@"
tests_failed_count=`expr 1 + $tests_failed_count`
tests_failed_list="$tests_failed_list $tests_count"
fi
return $run_test_status
}
run_tests() {
tests_count=0
tests_failed_count=0
tests_failed_list=
for t in "$@"; do
echo "### running $t"
"$t"
done
echo
echo "#### ALL tests done"
if test 0 -eq $tests_failed_count; then
echo "ALL $tests_count TESTS SUCCESSFUL"
return 0
else
# At least one failed
echo "FAILED $tests_failed_count/$tests_count TESTS: $tests_failed_list"
return 1
fi
}
uri_unescape()
{
#echo "$@" | perl -MURI::Escape -e 'print uri_unescape(<>)'
echo "$1" | perl -pe 's/\%(\w\w)/chr hex $1/ge'
}
tests_uri_unescape()
{
run_test test '' = ''
run_test test "" = ""
run_test test '1' = '1'
run_test test 'A B' = 'A B'
run_test test "'A B' = 'A B'"
run_test test '' = "`uri_unescape`"
run_test test "" = "`uri_unescape`"
run_test test 'A' = `uri_unescape A`
run_test test 'The cat' = "`uri_unescape The%20cat`"
run_test test "\r" = "\r"
run_test test '"\r" = "`uri_unescape %0D`"'
run_test test "\n" = "\n"
nl=`uri_unescape %0A`
nl="\n"
run_test test "_\n_" = "_${nl}_"
run_test test '!"#$%&'\''()' = "`uri_unescape %21%22%23%24%25%26%27%28%29`"
run_test test '*+,/:;=?@[]' = "`uri_unescape %2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D`"
run_test test '"_a\n\n\nz_" = "_`uri_unescape a%0A%0A%0Az`_"'
run_test test '"_`uri_unescape a%0A%0A%0Az`_" = "_`uri_unescape a%0A%0A%0Az`_"'
run_test test 'A B' = 'A B'
uri_unescape 'a%0A%0A%0Az' > /tmp/$$_zzz1.txt
/bin/echo -e "a\n\n\nz" > /tmp/$$_zzz2.txt
run_test diff /tmp/$$_zzz1.txt /tmp/$$_zzz2.txt
rm /tmp/$$_zzz1.txt /tmp/$$_zzz2.txt
z3=`uri_unescape a%0A%0A%0Az`
z4="a\n\n\nz"
run_test test '"$z3" = "$z4"'
run_test test '"\n" = "`uri_unescape %0A`"'
#run_test test '\n' = "`uri_unescape %0A`"
run_test test '"a\r\nz" = "a\r\nz"'
run_test test '"_a\r\nz_" = "`uri_unescape _a%0D%0Az_`"'
run_test test 'A' = `uri_unescape A`
}
value_of_key()
{
key="$1"
test 1 -le "$#" && shift
keyval="$1"
#echo "key:$key"
#echo "keyval:$keyval"
#set -x
echo "$keyval" | perl -ne "s/^.*$key"'=([^&]+).*$/$1/ and print'
#set +x
}
tests_value_of_key()
{
run_test test "" = "`value_of_key`"
run_test test "" = "`value_of_key badkey`"
run_test test "" = "`value_of_key badkey mykey=myvalue`"
run_test test "myvalue" = "`value_of_key mykey mykey=myvalue`"
run_test test "myvalue" = `value_of_key mykey "mykey=myvalue"`
run_test test "myvalue" = `value_of_key mykey "mykey=myvalue&other=rrr"`
run_test test "myvalue" = `value_of_key mykey "otra=zzz&mykey=myvalue"`
run_test test "myvalue" = `value_of_key mykey "otra=zzz&mykey=myvalue&other=rrr"`
}
remove_blanks_and_comments()
{
/bin/echo -n ''
echo "$1" | perl -ne '!/^ *#.*$|^[\r ]*$/ && print'
}
tests_remove_blanks_and_comments()
{
#set -x
run_test test "" = "`remove_blanks_and_comments`"
run_test test "a" = "`remove_blanks_and_comments a`"
myval="
"
run_test test "" = "`remove_blanks_and_comments $myval`"
myval="a
"
run_test test "a" = "`remove_blanks_and_comments $myval`"
myval="
a
"
run_test test "a" = "`remove_blanks_and_comments $myval`"
myval="
a
"
run_test test "a" = "`remove_blanks_and_comments $myval`"
myval="a
b"
run_test test '"$myval" = `remove_blanks_and_comments $myval`'
myval="# caca
a
"
run_test test '"a" = "`remove_blanks_and_comments $myval`"'
myval="# caca
a
b
# ooo
c
"
myval_filtered="a
b
c
"
run_test test '"$myval_filtered" = "`remove_blanks_and_comments $myval`"'
run_test remove_blanks_and_comments
run_test remove_blanks_and_comments ' '
run_test remove_blanks_and_comments ' # blabla '
run_test test "" = "`remove_blanks_and_comments ' ' `"
run_test test "" = "`remove_blanks_and_comments ' # blabla ' `"
}
is_blank_or_comment()
{
test "" = "`remove_blanks_and_comments $1 `"
}
tests_is_blank_or_comment()
{
run_test is_blank_or_comment
run_test is_blank_or_comment ''
run_test is_blank_or_comment ' '
run_test is_blank_or_comment '# blabla 1 '
run_test is_blank_or_comment ' # blabla 2 '
is_blank_or_comment 'blabla 1 ' ; run_test test 1 = $?
is_blank_or_comment ' blabla 2 ' ; run_test test 1 = $?
is_blank_or_comment ' blabla 3 # blibli ' ; run_test test 1 = $?
}
logfailures()
{
:
}
tests_logfailures()
{
:
}
run_on_each_line()
{
echodebug '### Entering run_on_each_line ###'
test -f abort_$$.txt && { echo abort demanded so not doing normal stuff ; return ; }
/bin/echo -n ''
test -z "$1" && { echo3 'First parameter is empty. Leaving run_on_each_line().' ; return ; }
csv_data_multilines="$1"
echodebug "csv_data_multilines=[$csv_data_multilines]"
test 1 -le "$#" && shift
failures_file=${1:-""}
echodebug failures_file="$failures_file"
test -x "$failures_file" && { echo3 "failure file $failures_file is an executable. Leaving run_on_each_line()." ; return ; }
test 1 -le "$#" && shift
command=${1:-echo}
echodebug command="$command" "$@"
test 1 -le "$#" && shift
line_number=0
csv_number=0
failures_number=0
echo "$csv_data_multilines" | while IFS=';' read h1 u1 p1 h2 u2 p2 fake; do
test -f abort_$$.txt && { echo abort demanded so not doing normal stuff ; return ; }
line_number=`expr 1 + $line_number`
if is_blank_or_comment "$h1$u1$p1$h2$u2$p2$fake" ; then
echo3 "Ignoring line " $line_number "$h1$u1$p1$h2$u2$p2$fake"
else
csv_number=`expr 1 + $csv_number`
echo3 "Processing line " $line_number run $csv_number "[$h1] [$u1] [xxx] [$h2] [$u2] [xxx] [$fake] $$"
$command "$@" --host1 "$h1" --user1 "$u1" --password1 "$p1" --host2 "$h2" --user2 "$u2" --password2 "$p2"
command_status=$?
test "0" != "$command_status" && failures_number=`expr 1 + $failures_number`
logfailures "$failures_file" "$command_status" "$line_number" "$csv_number"
fi
done
echodebug Leaving run_on_each_line
test "0" != "$failures_number" && return 1
return 0
}
tests_run_on_each_line()
{
# 1-4
run_test test '' = "`run_on_each_line`"
run_test test '' = "`run_on_each_line ''`"
run_test test '' = "`run_on_each_line '' 'log.txt'`"
run_test test '' = "`run_on_each_line '' 'log.txt' echo imapsync`"
# 5-7 blank data
run_test test '' = "`run_on_each_line ' '`"
run_test test '' = "`run_on_each_line ' ' 'log.txt'`"
run_test test '' = "`run_on_each_line ' ' 'log.txt' echo imapsync`"
# 8-10 comment data
run_test test '' = "`run_on_each_line '# '`"
run_test test '' = "`run_on_each_line '# ' 'log.txt'`"
run_test test '' = "`run_on_each_line '# ' 'log.txt' echo imapsync`"
# 11-13 empty line
myval='
'
myret=`run_on_each_line "$myval"`
run_test test "" = "$myret"
myret=`run_on_each_line "$myval" 'log.txt'`
run_test test "" = "$myret"
myret=`run_on_each_line "$myval" 'log.txt' echo imapsync`
run_test test "" = "$myret"
# 14-16 blanks or comments
myval='
# blabla 1
# blabla 2
'
myret=`run_on_each_line "$myval"`
run_test test "" = "$myret"
myret=`run_on_each_line "$myval" 'log.txt'`
run_test test "" = "$myret"
myret=`run_on_each_line "$myval" 'log.txt' echo imapsync`
run_test test "" = "$myret"
# 17-21
# csv data no blank no comment
lines='a1;b1;c1;d1;e1;f1
a2;b2;c2;d2;e2;f2
a3;b3;c3;d3;e3;f3'
# No failure file (so /dev/null), no command (so echo)
lines_out='--host1 a1 --user1 b1 --password1 c1 --host2 d1 --user2 e1 --password2 f1
--host1 a2 --user1 b2 --password1 c2 --host2 d2 --user2 e2 --password2 f2
--host1 a3 --user1 b3 --password1 c3 --host2 d3 --user2 e3 --password2 f3'
run_test test "$lines_out" = "`run_on_each_line "$lines"`"
# failure file is a command => BAD => do nothing
cp /bin/echo "/tmp/myecho$$"
run_test test "" = "`run_on_each_line "$lines" /tmp/myecho$$`"
run_test test "" = "`run_on_each_line "$lines" /tmp/myecho$$ echo`"
run_test test "" = "`run_on_each_line "$lines" /tmp/myecho$$ echo imapsync blabla bla`"
rm "/tmp/myecho$$"
# No failure file (so /dev/null), command = echo imapsync
lines_out='imapsync --host1 a1 --user1 b1 --password1 c1 --host2 d1 --user2 e1 --password2 f1
imapsync --host1 a2 --user1 b2 --password1 c2 --host2 d2 --user2 e2 --password2 f2
imapsync --host1 a3 --user1 b3 --password1 c3 --host2 d3 --user2 e3 --password2 f3'
run_test test "$lines_out" = "`run_on_each_line "$lines" '' echo imapsync`"
# 22-27
# csv data + blanks + comments
lines='a1;b1;c1;d1;e1;f1
# blabla 2
a2;b2;c2;d2;e2;f2
# bloblo 3
a3;b3;c3;d3;e3;f3
# end'
# No failure file (so /dev/null), no command (so echo)
lines_out='--host1 a1 --user1 b1 --password1 c1 --host2 d1 --user2 e1 --password2 f1
--host1 a2 --user1 b2 --password1 c2 --host2 d2 --user2 e2 --password2 f2
--host1 a3 --user1 b3 --password1 c3 --host2 d3 --user2 e3 --password2 f3'
run_test test "$lines_out" = "`run_on_each_line "$lines"`"
# failure file is a command => BAD => do nothing
cp /bin/echo "/tmp/myecho$$"
run_test test "" = "`run_on_each_line "$lines" /tmp/myecho$$`"
run_test test "" = "`run_on_each_line "$lines" /tmp/myecho$$ echo`"
run_test test "" = "`run_on_each_line "$lines" /tmp/myecho$$ echo imapsync blabla bla`"
rm "/tmp/myecho$$"
# No failure file (so /dev/null), command = echo imapsync
lines_out='imapsync --host1 a1 --user1 b1 --password1 c1 --host2 d1 --user2 e1 --password2 f1
imapsync --host1 a2 --user1 b2 --password1 c2 --host2 d2 --user2 e2 --password2 f2
imapsync --host1 a3 --user1 b3 --password1 c3 --host2 d3 --user2 e3 --password2 f3'
run_test test "$lines_out" = "`run_on_each_line "$lines" '' echo imapsync`"
}
hashsync()
{
#set -x
mystring=${1:-''}
mykey=${2:-''}
# impressive! is not it? quoting shit!
perl -MDigest::HMAC_SHA1 -e 'print Digest::HMAC_SHA1::hmac_sha1_hex( "'"$mystring"'", "'"$mykey"'" )'
#set +x
}
tests_hashsync()
{
run_test test 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d' = `hashsync`
run_test test 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d' = `hashsync ''`
run_test test 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d' = `hashsync '' ''`
run_test test 'e86a28a3611c1e7bbaf8057cd00ae122781a11fe' = `hashsync 'zzz' ''`
run_test test '6a7b451ac99eab1531ad8e6cd544b32420c552ac' = `hashsync 'zzz' 'A'`
}
tests_caca()
{
run_test test 'z' = ''
run_test test '1' = '1'
}
change_working_directory_if_under_cgi()
{
test -n "$SERVER_SOFTWARE" &&
{
pwd
#env
! test -d "$1" && {
echo creating directory "$1"
mkdir -p "$1"
}
echo changing current directory to "$1"
cd "$1"
pwd
}
}
write_my_pid()
{
echo Writing my pid $$ in imapsync_csv_wrapper.pid
echo $$ > imapsync_csv_wrapper.pid
}
kill_pid_in_files()
{
echo Will kill -TERM pid found in "$@"
for pidfile in "$@"; do
# FIXME add test -f $pidfile at least
if test -f $pidfile; then
pidlist="$pidlist `head -1 $pidfile`"
test -f "$pidfile" && echo Doing kill -TERM `head -1 "$pidfile"` "$pidfile"
test -f "$pidfile" && kill -TERM `head -1 "$pidfile"`
else
echo "No $pidfile here"
fi
done
}
abort_other_process()
{
echodebug 'Entering abort_other_process()'
$debug && ls -ltr
# No active imapsync_csv_wrapper => nothing to abort
if ! test -f imapsync_csv_wrapper.pid ; then
echo No imapsync_csv_wrapper.pid here. Nothing to abort.
echodebug 'Leaving abort_other_process()'
return 0
else
# a message to the active imapsync_csv_wrapper
main_pid_to_abort=`head -1 imapsync_csv_wrapper.pid`
touch abort_${main_pid_to_abort}.txt
echodebug 'sleep 3' && sleep 3
kill_pid_in_files imapsync.pid
echodebug 'sleep 3 again then nother try to kill' && sleep 3
kill_pid_in_files imapsync.pid
ls -ltr
echodebug 'Leaving abort_other_process()'
return 0
fi
}
quit()
{
echo "Leaving. I am $0 pid $$"
for pidfile in "$@"; do
test -f "$pidfile" && echo rm "$pidfile" && rm "$pidfile"
done
}
tests()
{
:
# All tests
run_tests \
tests_uri_unescape \
tests_value_of_key \
tests_remove_blanks_and_comments \
tests_run_on_each_line \
tests_hashsync \
tests_is_blank_or_comment \
tests_logfailures
}
header()
{
# HTTP header, may be empty
echo
}
getcsvdata()
{
read imapsync_csv_wrapper_from_ui
echodebug '######################################################################'
echodebug Here are the UI parameters, raw:
echodebug "var:"
echodebug "$imapsync_csv_wrapper_from_ui"
echodebug;echodebug
csv_data=`value_of_key csv_data "$imapsync_csv_wrapper_from_ui"`
echodebug '######################################################################'
echodebug Here csv_data:
echodebug "$csv_data"
csv_data_unescaped=`uri_unescape "$csv_data"`
echodebug '######################################################################'
echodebug Here csv_data, unescaped:
echodebug "$csv_data_unescaped"
csv_data_pure=`remove_blanks_and_comments "$csv_data_unescaped"`
echodebug '######################################################################'
echodebug Here csv_data no blanks nor comments:
echodebug "$csv_data_pure"
}
tests_all_verbose_if_failure()
{
# Run tests silent but if failure then rerun them verbose.
# return 0 if all tests passed
# return 1 if some tests failed
if ! tests > /dev/null 3>&1 ; then
tests
return 1
fi
return 0
}
abort_other_if_asked_to()
{
echodebug Looking for abort
abort=`value_of_key abort "$imapsync_csv_wrapper_from_ui"`
echodebug abort=$abort
if test 'on' = "$abort" ; then
abort_other_process
echo "Abort done. Leaving"
return 0
else
echodebug 'Not asked to abort other process'
echodebug 'Leaving abort_other_if_asked_to()'
return 1
fi
}
is_another_running()
{
# I should check that the pid is actually a running one
# but that's ok for now
if test -f imapsync_csv_wrapper.pid; then
echo Looks like another imapsync_csv_wrapper is running. Leaving
return 0
else
echodebug Looks like I am alone. Good. Let us go on.
return 1
fi
}
signal_handling()
{
# 2=INT 3=QUIT 15=TERM
trap "quit imapsync_csv_wrapper.pid abort_$$.txt" 15 2 3 0
$debug && trap
return 0
}
banner_round()
{
banner_line='
################################################################################'
banner_title=${1:-$banner_line}
echo3 "$banner_line$banner_title$banner_line"
}
justlogin()
{
banner_round '
######################## just login check round ################################'
date
test -f abort_$$.txt && { echo Abort demanded so not doing normal stuff ; return ; }
echo Now run imapsync --justlogin to check all credentials are ok
if run_on_each_line "$csv_data_unescaped" "" \
imapsync --no-modulesversion --justlogin --tmpdir .
then
echo success of the just login check round
return 0
else
echo failure of the just login check round
return 1
fi
}
justfoldersizes()
{
banner_round '
######################## just folders sizes counting round #####################'
date
test -f abort_$$.txt && { echo Abort demanded so not doing normal stuff ; return ; }
echo Now run imapsync --justlogin to check all credentials are ok
run_on_each_line "$csv_data_unescaped" "" \
imapsync --no-modulesversion --justfoldersizes --tmpdir . \
|| return 1
}
sync_all()
{
banner_round '
######################## now sync them all round ###############################'
date
test -f abort_$$.txt && { echo Abort demanded so not doing normal stuff ; return ; }
echo Now run imapsync --justlogin to check all credentials are ok
run_on_each_line "$csv_data_unescaped" "" \
imapsync --no-modulesversion --tmpdir . \
|| return 1
}
tests_initialisation()
{
#### Variables initialisation
tests_count=0
tests_failed_count=0
tests_failed_list=
}
main()
{
header
# All stderr to stdin, yeah I am like that
exec 2>&1
# Some tests
#run_tests tests_is_blank_or_comment
#run_tests tests_run_on_each_line
#run_tests tests_remove_blanks_and_comments
#tests_hashsync
#return
tests_all_verbose_if_failure || return 1
echodebug my pid is $$
#return
getcsvdata
hashsync=`hashsync $csv_data_pure`
change_working_directory_if_under_cgi /var/tmp/imapsync_cgi/$hashsync/
abort_other_if_asked_to && return 0
is_another_running && return 0
write_my_pid
signal_handling
SERVER_SOFTWARE_BAK="$SERVER_SOFTWARE"
unset SERVER_SOFTWARE
# Now the real stuff
justlogin || return 1
justfoldersizes
sync_all || return 1
$debug && ls -ltr
quit imapsync_csv_wrapper.pid abort_$$.txt
echo $0 ended at the end
}
tests_initialisation
main
return 0

1
X/imapsync_current.txt Symbolic link
View file

@ -0,0 +1 @@
/var/tmp/imapsync_current.txt

View file

@ -1,6 +1,11 @@
/* $Id: imapsync_form.css,v 1.8 2019/11/25 13:49:18 gilles Exp gilles $ */
/* $Id: imapsync_form.css,v 1.9 2020/06/15 11:55:50 gilles Exp gilles $ */
body {
color: black;
background-color: #eeffff;
}
#account1 {
background-color: DodgerBlue ;

View file

@ -1,5 +1,5 @@
// $Id: imapsync_form.js,v 1.11 2019/07/29 22:42:50 gilles Exp gilles $
// $Id: imapsync_form.js,v 1.20 2021/05/29 10:25:53 gilles Exp gilles $
/*jslint browser: true*/ /*global $*/
@ -19,7 +19,7 @@ $(document).ready(
"4": "Finished and response is ready"
} ;
var refresh_interval_ms = 5000 ;
var refresh_interval_ms = 6000 ;
var refresh_interval_s = refresh_interval_ms / 1000 ;
var test = {
counter_all : 0 ,
@ -51,8 +51,13 @@ $(document).ready(
}
$("#tests").append( message ) ;
} ;
var note = function note( message )
{
$("#tests").append( message ) ;
}
function last_eta( string )
var last_eta = function last_eta( string )
{
// return the last occurrence of the substring "ETA: ...\n"
// or "ETA: unknown" or ""
@ -78,7 +83,7 @@ $(document).ready(
}
}
function tests_last_eta()
var tests_last_eta = function tests_last_eta()
{
is( "", last_eta( ), "last_eta: no args => empty string" ) ;
@ -278,11 +283,13 @@ $(document).ready(
return ;
} ;
function refreshLog( xhr )
var refreshLog = function refreshLog( xhr )
{
var eta_obj ;
var eta_str ;
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
eta_obj = extract_eta( xhr ) ;
progress_bar_update( eta_obj ) ;
@ -308,7 +315,7 @@ $(document).ready(
function handleRun(xhr, timerRefreshLog)
var handleRun = function handleRun(xhr, timerRefreshLog)
{
$("#console").text(
@ -324,10 +331,13 @@ $(document).ready(
refreshLog( xhr ) ; // a last time
// back to enable state for next run
$("#bt-sync").prop("disabled", false) ;
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
}
}
function imapsync()
var imapsync = function imapsync()
{
var querystring = $("#form").serialize() ;
$("#abort").text("\n\n") ; // clean abort console
@ -351,6 +361,8 @@ $(document).ready(
{
querystring = querystring + "&office2=on" ;
}
// querystring = querystring + "&tmphash=" + tmphash( ) ;
var xhr ;
@ -373,7 +385,7 @@ $(document).ready(
}
function handleAbort( xhr )
var handleAbort = function handleAbort( xhr )
{
$( "#abort" ).text(
@ -388,7 +400,7 @@ $(document).ready(
}
}
function abort()
var abort = function abort()
{
var querystring = $("#form").serialize() + "&abort=on";
var xhr;
@ -402,7 +414,7 @@ $(document).ready(
xhr.send(querystring);
}
function store( id )
var store = function store( id )
{
var stored ;
//$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + "\n" ) ;
@ -420,7 +432,7 @@ $(document).ready(
return stored ;
}
function retrieve( id )
var retrieve = function retrieve( id )
{
var retrieved ;
//$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + " length is " + $( id ).length + "\n" ) ;
@ -438,7 +450,7 @@ $(document).ready(
return retrieved ;
}
function tests_store_retrieve()
var tests_store_retrieve = function tests_store_retrieve()
{
if ( $("#tests").length !== 0 )
{
@ -479,7 +491,7 @@ $(document).ready(
}
function store_form()
var store_form = function store_form()
{
if ( Storage !== "undefined")
{
@ -506,7 +518,7 @@ $(document).ready(
}
}
function show_extra_if_needed()
var show_extra_if_needed = function show_extra_if_needed()
{
if ( $("#subfolder1").length && $("#subfolder1").val().length > 0 )
{
@ -518,7 +530,7 @@ $(document).ready(
}
}
function retrieve_form()
var retrieve_form = function retrieve_form()
{
if ( Storage !== "undefined" )
{
@ -555,14 +567,14 @@ $(document).ready(
localStorage.account2_background_color ) ;
}
// Show the extra parameters if they are not empty because it would be dangerous
// to retrieve them without knowing
// Show the extra parameters if they are not empty because it would
// be dangerous to retrieve them without showing them
show_extra_if_needed() ;
}
}
function showpassword( id, button )
var showpassword = function showpassword( id, button )
{
var x = document.getElementById( id );
if ( button.checked )
@ -573,7 +585,67 @@ $(document).ready(
}
}
function init()
var tests_cryptojs = function tests_cryptojs()
{
if ( $("#tests").length !== 0 )
{
if (typeof CryptoJS === 'undefined')
{
is( true, typeof CryptoJS !== 'undefined', "CryptoJS is available" ) ;
note( "CryptoJS is not available on this site. Ask the admin to fix this.\n" ) ;
}
else if (typeof CryptoJS.SHA256 !== "function")
{
is( "function", typeof CryptoJS.SHA256, "CryptoJS.SHA256 is a function" ) ;
note( "CryptoJS.SHA256 function is not available on this site. Ask the admin to fix this.\n" ) ;
}
else
{
// safe to use the function
is( "function", typeof CryptoJS.SHA256, "CryptoJS.SHA256 is a function" ) ;
is( "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91", sha256("Message"), "sha256 Message" ) ;
is( "26429a356b1d25b7d57c0f9a6d5fed8a290cb42374185887dcd2874548df0779", sha256("caca"), "sha256 caca" ) ;
is( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", sha256(""), "sha256 ''" ) ;
is( tmphash(), tmphash(), "tmphash" ) ;
$("#user1").val("test1") ;
$("#password1").val("secret1") ;
$("#host1").val("test1.lamiral.info") ;
$("#user2").val("test2") ;
$("#password2").val("secret2") ;
$("#host2").val("test2.lamiral.info") ;
is( "20d2b4917cf69114876b4c8779af543e89c5871c6ada68107619722e55af1101", tmphash(), "tmphash like testslive" ) ;
$("#user1").val("") ;
$("#password1").val("") ;
$("#host1").val("") ;
$("#user2").val("") ;
$("#password2").val("") ;
$("#host2").val("") ;
}
}
}
var sha256 = function sha256( string )
{
var hash = CryptoJS.SHA256( string ) ;
var hash_hex = hash.toString( CryptoJS.enc.Hex ) ;
return( hash_hex ) ;
}
var tmphash = function tmphash()
{
var string = "" ;
string = string.concat(
$("#user1").val(), $("#password1").val(), $("#host1").val(),
$("#user2").val(), $("#password2").val(), $("#host2").val(),
)
return( sha256( string ) ) ;
}
var init = function init()
{
// in case of a manual refresh, start with
$("#bt-sync").prop("disabled", false);
@ -581,8 +653,6 @@ $(document).ready(
$("#link_to_bottom").hide();
$("#progress-bar-left").css( "width", 100 + "%" ).attr( "aria-valuenow", 100 ) ;
retrieve_form();
$("#showpassword1").click(
function ( event )
{
@ -605,6 +675,7 @@ $(document).ready(
$("#bt-sync").click(
function ()
{
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
$("#bt-sync").prop("disabled", true) ;
$("#bt-abort").prop("disabled", false) ;
$("#link_to_bottom").hide() ;
@ -617,9 +688,11 @@ $(document).ready(
$("#bt-abort").click(
function ()
{
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
$("#bt-sync").prop("disabled", true);
$("#bt-abort").prop("disabled", true);
abort();
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
}
);
@ -653,12 +726,29 @@ $(document).ready(
showpassword( "password2", $("#showpassword2")[0] ) ;
}
) ;
if ( "imapsync.lamiral.info" === location.hostname )
{
$( "#local_bandwidth" ).collapse( "show" ) ;
$( "#local_status_dbmon" ).collapse( "show" ) ;
$( "#local_status_hetrix" ).collapse( "show" ) ;
$( "#imapsync_advice_hours" ).collapse( "show" ) ;
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
}
else if ( "lamiral.info" === location.hostname )
{
$( "#local_bandwidth" ).collapse( "show" ) ;
$( "#local_status_dbmon" ).collapse( "show" ) ;
$( "#local_status_hetrix" ).collapse( "show" ) ;
$( "#imapsync_advice_hours" ).collapse( "show" ) ;
$( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
}
}
var tests_bilan = function tests_bilan()
var tests_bilan = function tests_bilan( nb_attended_test )
{
// attended number of tests
var nb_attended_test = 29 ;
// attended number of tests: nb_attended_test
$("#tests").append( "1.." + test.counter_all + "\n" ) ;
if ( test.counter_nok > 0 )
{
@ -681,22 +771,30 @@ $(document).ready(
}
} ;
function tests()
var tests = function tests( nb_attended_test )
{
if ( $("#tests").length !== 0 )
{
tests_store_retrieve( ) ;
tests_last_eta( ) ;
tests_decompose_eta_line( ) ;
// tests_cryptojs( ) ;
// The following test can be used to check that if a test fails
// then all the tests are shown to the user.
//is( 0, 1, "this test always fails" ) ;
tests_bilan( ) ;
//$("#tests").collapse("show") ;
tests_bilan( nb_attended_test ) ;
// If you want to always see the tests, uncomment the following
// line
// $("#tests").collapse("show") ;
}
}
init( ) ;
tests( ) ;
tests( 29 ) ;
retrieve_form( ) ;
}

View file

@ -1,159 +0,0 @@
// $Id: imapsync_form.js,v 1.3 2019/03/18 19:21:16 gilles Exp gilles $
/*jslint browser: true*/ /*global $*/
$(document).ready(function () {
"use strict";
// Bootstrap popover and tooltip
$("[data-toggle='tooltip']").tooltip();
var readyStateStr = {
"0": "Request not initialized",
"1": "Server connection established",
"2": "Response headers received",
"3": "Processing request",
"4": "Finished and response is ready"
};
function refreshLog(xhr) {
$("#output").html(xhr.responseText);
}
function handleRun(xhr, timerRefreshLog) {
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n");
if (xhr.readyState === 4) {
// var headers = xhr.getAllResponseHeaders();
// $("#console").append(headers);
// $("#console").append("See the completed log\n");
$("#link_to_bottom").show();
clearInterval(timerRefreshLog);
refreshLog(xhr); // a last time
$("#bt-sync").prop("disabled", false); // back to enable state for next run
}
}
function imapsync() {
var querystring = $("#form").serialize();
$("#abort").text("\n\n"); // clean abort console
$("#output").text("Here comes the log!\n\n");
if ("imap.gmail.com" === $("#host1").val()) {
querystring = querystring + "&gmail1=on";
}
if ("imap.gmail.com" === $("#host2").val()) {
querystring = querystring + "&gmail2=on";
}
var xhr;
xhr = new XMLHttpRequest();
var timerRefreshLog = setInterval(function () {
refreshLog(xhr);
}, 5000);
xhr.onreadystatechange = function () {
handleRun(xhr, timerRefreshLog);
};
xhr.open("POST", "/cgi-bin/imapsync", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(querystring);
}
function handleAbort(xhr) {
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
if (xhr.readyState === 4) {
$("#abort").append(xhr.responseText);
$("#bt-sync").prop("disabled", false);
$("#bt-abort").prop("disabled", false); // back for next abort
}
}
function abort() {
var querystring = $("#form").serialize() + "&abort=on";
var xhr;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
handleAbort(xhr);
};
xhr.open("POST", "/cgi-bin/imapsync", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(querystring);
}
function store_form() {
if (typeof(Storage) !== "undefined") {
// Code for localStorage.
localStorage.user1 = $("#user1").val();
localStorage.password1 = $("#password1").val();
localStorage.host1 = $("#host1").val();
localStorage.user2 = $("#user2").val();
localStorage.password2 = $("#password2").val();
localStorage.host2 = $("#host2").val();
} else {
// Sorry! No Web Storage support...
}
}
function retrieve_form() {
if (typeof(Storage) !== "undefined") {
// Code for localStorage.
$("#user1").val(localStorage.user1);
$("#password1").val(localStorage.password1);
$("#host1").val(localStorage.host1);
$("#user2").val(localStorage.user2);
$("#password2").val(localStorage.password2);
$("#host2").val(localStorage.host2);
} else {
// Sorry! No Web Storage support...
}
}
function showpassword() {
}
// in case of a manual refresh, start with
$("#bt-sync").prop("disabled", false);
$("#bt-abort").prop("disabled", false);
$("#link_to_bottom").hide();
retrieve_form();
// Well I should write function showpassword() body and use it
// I'm just dumb in js and jQuery
$("#showpassword1").click(function () {
var x = document.getElementById("password1");
if (x.type === "password") {
x.type = "text";
} else {
x.type = "password";
}
});
$("#showpassword2").click(function () {
var x = document.getElementById("password2");
if (x.type === "password") {
x.type = "text";
} else {
x.type = "password";
}
});
$("#bt-sync").click(function () {
$("#bt-sync").prop("disabled", true);
$("#bt-abort").prop("disabled", false);
$("#link_to_bottom").hide();
store_form();
imapsync();
});
$("#bt-abort").click(function () {
$("#bt-sync").prop("disabled", true);
$("#bt-abort").prop("disabled", true);
abort();
});
});

View file

@ -1,228 +0,0 @@
// $Id: imapsync_form.js,v 1.4 2019/04/28 03:02:37 gilles Exp $
/*jslint browser: true*/ /*global $*/
$(document).ready(function () {
"use strict";
// Bootstrap popover and tooltip
$("[data-toggle='tooltip']").tooltip();
var readyStateStr = {
"0": "Request not initialized",
"1": "Server connection established",
"2": "Response headers received",
"3": "Processing request",
"4": "Finished and response is ready"
};
function refreshLog(xhr) {
$("#output").html(xhr.responseText);
}
function handleRun(xhr, timerRefreshLog) {
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n");
if (xhr.readyState === 4) {
// var headers = xhr.getAllResponseHeaders();
// $("#console").append(headers);
// $("#console").append("See the completed log\n");
$("#link_to_bottom").show();
clearInterval(timerRefreshLog);
refreshLog(xhr); // a last time
$("#bt-sync").prop("disabled", false); // back to enable state for next run
}
}
function imapsync() {
var querystring = $("#form").serialize();
$("#abort").text("\n\n"); // clean abort console
$("#output").text("Here comes the log!\n\n");
if ("imap.gmail.com" === $("#host1").val()) {
querystring = querystring + "&gmail1=on";
}
if ("imap.gmail.com" === $("#host2").val()) {
querystring = querystring + "&gmail2=on";
}
var xhr;
xhr = new XMLHttpRequest();
var timerRefreshLog = setInterval(function () {
refreshLog(xhr);
}, 5000);
xhr.onreadystatechange = function () {
handleRun(xhr, timerRefreshLog);
};
xhr.open("POST", "/cgi-bin/imapsync", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(querystring);
}
function handleAbort(xhr) {
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
if (xhr.readyState === 4) {
$("#abort").append(xhr.responseText);
$("#bt-sync").prop("disabled", false);
$("#bt-abort").prop("disabled", false); // back for next abort
}
}
function abort() {
var querystring = $("#form").serialize() + "&abort=on";
var xhr;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
handleAbort(xhr);
};
xhr.open("POST", "/cgi-bin/imapsync", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(querystring);
}
function store_form() {
if (typeof(Storage) !== "undefined") {
// Code for localStorage.
localStorage.user1 = $("#user1").val();
localStorage.password1 = $("#password1").val();
localStorage.host1 = $("#host1").val();
localStorage.subfolder1 = $("#subfolder1").val();
localStorage.showpassword1 = $("#showpassword1")[0].checked ;
//
localStorage.account1_background_color = $("#account1").css("background-color") ;
localStorage.user2 = $("#user2").val();
localStorage.password2 = $("#password2").val();
localStorage.host2 = $("#host2").val();
localStorage.subfolder2 = $("#subfolder2").val();
localStorage.showpassword2 = $("#showpassword2")[0].checked ;
// alert( $("#dry")[0].checked ) ;
localStorage.dry = $("#dry")[0].checked ;
localStorage.justlogin = $("#justlogin")[0].checked ;
localStorage.justfolders = $("#justfolders")[0].checked ;
localStorage.justfoldersizes = $("#justfoldersizes")[0].checked ;
localStorage.account2_background_color = $("#account2").css("background-color") ;
} else {
// Sorry! No Web Storage support...
}
}
function retrieve_form() {
if (typeof(Storage) !== "undefined")
{
// Code for localStorage.
$("#user1").val(localStorage.user1);
$("#password1").val(localStorage.password1);
// $("#showpassword1")[0].checked = JSON.parse(localStorage.showpassword1);
$("#host1").val(localStorage.host1);
$("#subfolder1").val(localStorage.subfolder1);
$("#user2").val(localStorage.user2);
$("#password2").val(localStorage.password2);
// $("#showpassword2")[0].checked = JSON.parse(localStorage.showpassword2);
$("#host2").val(localStorage.host2);
$("#subfolder2").val(localStorage.subfolder2);
$("#dry")[0].checked = JSON.parse(localStorage.dry || false );
$("#justlogin")[0].checked = JSON.parse(localStorage.justlogin || false );
$("#justfolders")[0].checked = JSON.parse(localStorage.justfolders || false );
$("#justfoldersizes")[0].checked = JSON.parse(localStorage.justfoldersizes || false );
// In case
// localStorage.removeItem( "account1_background_color" ) ;
// localStorage.removeItem( "account2_background_color" ) ;
if ( localStorage.account1_background_color )
{
$("#account1").css("background-color", localStorage.account1_background_color ) ;
}
if ( localStorage.account2_background_color )
{
$("#account2").css("background-color", localStorage.account2_background_color ) ;
}
}
else
{
// Sorry! No Web Storage support...
}
}
function showpassword() {
}
// in case of a manual refresh, start with
$("#bt-sync").prop("disabled", false);
$("#bt-abort").prop("disabled", false);
$("#link_to_bottom").hide();
retrieve_form();
// Well I should write function showpassword() body and use it
// I'm just dumb in js and jQuery
$("#showpassword1").click(function () {
var x = document.getElementById("password1");
if (x.type === "password" && this.checked ) {
x.type = "text";
} else {
x.type = "password";
}
});
$("#showpassword2").click(function () {
var x = document.getElementById("password2");
if (x.type === "password" && this.checked ) {
x.type = "text";
} else {
x.type = "password";
}
});
$("#bt-sync").click(function () {
$("#bt-sync").prop("disabled", true);
$("#bt-abort").prop("disabled", false);
$("#link_to_bottom").hide();
store_form();
imapsync();
});
$("#bt-abort").click(function () {
$("#bt-sync").prop("disabled", true);
$("#bt-abort").prop("disabled", true);
abort();
});
jQuery.fn.swapWith = function(to) {
var temp = $(to).val();
$(to).val($(this).val());
$(this).val(temp);
};
$("#swap").click(function(){
$("#user1").swapWith("#user2");
$("#password1").swapWith("#password2");
$("#host1").swapWith("#host2");
$("#subfolder1").swapWith("#subfolder2");
var temp = $("#account1").css("background-color") ;
$("#account1").css("background-color", $("#account2").css("background-color") ) ;
$("#account2").css("background-color", temp ) ;
});
// End of
});

199
X/imapsync_form_extra.html Executable file → Normal file
View file

@ -1,32 +1,37 @@
<!DOCTYPE html>
<!-- $Id: imapsync_form_extra.html,v 1.4 2019/11/07 11:16:25 gilles Exp gilles $ -->
<!-- $Id: imapsync_form_extra.html,v 1.18 2021/05/30 05:45:15 gilles Exp gilles $ -->
<html lang="en" id="top">
<head>
<!--
<script
data-ad-client="ca-pub-3325993554161060"
async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
</script>
-->
<title>Imapsync Online Unlimited</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Imapsync online</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link rel="stylesheet" href="imapsync_form.css">
<link rel="stylesheet" href="../S/style.css" type="text/css" />
<link rel="license" href="https://imapsync.lamiral.info/NOLIMIT">
<link rel="license" href="https://imapsync.lamiral.info/NOLIMIT">
<noscript>
<noscript>
<link rel="stylesheet" href="noscript.css">
</noscript>
</noscript>
</head>
<body>
@ -52,70 +57,22 @@
<img alt="Imapsync home" title="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
</a>
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
<!-- <a href="#payment" class="btn btn-success" data-toggle="collapse">Pricing</a> -->
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
</div>
</div>
<h1 class="text-center">Imapsync online</h1>
<h1 class="text-center">Imapsync Online Unlimited</h1>
<p class="text-center"> <strong>Copy</strong>/synchronize a <strong>complete</strong> mailbox to another, without <strong>duplicates!</strong></p>
<p class="text-center larger"> <strong>Copy</strong>/synchronize a <strong>complete</strong> Mailbox to another, without <strong>duplicates!</strong></p>
<!-- Paypal part start
new: NDGMR6TLFZ926
old: H2YTURNFT4XT4
-->
<!-- A button above the pricing form, not very beautiful...
I should give it a try anyway because nearly no one buy this service...
<div class="text-center">
<a href="#payment" class="btn btn-warning btn-lg" data-toggle="collapse">Pricing</a>
</div>
-->
<!-- the "in" makes the form not collapsed by default
Remove the in in order to mask the pricing section
<div id="payment" class="well text-center collapse in" > -->
<div id="payment" class="well text-center collapse out" >
<p class="lead">Pay by usage type</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="H2YTURNFT4XT4" />
<input type="hidden" name="on0" value="imapsync choice" />
<fieldset>
<!--
<label data-toggle="tooltip" data-placement="top" title="Fair enough"
class="radio-inline"><input type="radio" name="os0" value="Tiny" > €1,00 </label>
-->
<label data-toggle="tooltip" data-placement="top" title="A big mailbox"
class="radio-inline"><input type="radio" name="os0" value="Small" > €6,00 </label>
<label data-toggle="tooltip" data-placement="top" title="Several mailboxes to migrate"
class="radio-inline"><input type="radio" name="os0" value="Normal" checked > €59,00 </label>
<!--
<label data-toggle="tooltip" data-placement="top" title="Tons of gigabytes to copy"
class="radio-inline"><input type="radio" name="os0" value="High" > €125,00 </label>
-->
<br>
<input type="hidden" name="currency_code" value="EUR" />
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - A safe, easy way to pay online!" />
</fieldset>
<p>
<strong>30-day money back guarantee!</strong> <br>
<em>No question nor condition to get a refund, really, just request it and you'll sure get a refund!</em>
</p>
</form>
</div>
<!-- Paypal part end -->
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
<div id="form_row" class="row">
<div id="account1" class="col-md-5" >
<fieldset>
<legend class="text-center h2">IMAP source mailbox</legend>
<legend class="text-center h2">IMAP source Mailbox</legend>
<label for="user1">Login</label>
<label for="user1">Login</label> (usually an email address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"> </i></span>
<input
@ -136,13 +93,13 @@ old: H2YTURNFT4XT4
placeholder="Enter password">
</div>
<label for="host1">Server</label>
<label for="host1">IMAP Server hostname</label> (or its IP address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
list="servers1" type="text" class="form-control input-lg" id="host1" name="host1" tabindex="3"
placeholder="Enter imap source server name or IP address">
placeholder="Enter IMAP source server name or IP address">
<datalist id="servers1">
<option value="imap.gmail.com">
<option value="outlook.office365.com">
@ -184,7 +141,7 @@ old: H2YTURNFT4XT4
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Shows what would be done without really doing it."
type="checkbox" id="dry" name="dry" >Dry run.
type="checkbox" id="dry" name="dry" >Just verbose, no real sync.
</label>
</div>
@ -192,7 +149,7 @@ old: H2YTURNFT4XT4
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Checks credentials without syncing anything."
type="checkbox" id="justlogin" name="justlogin" >Login only.
type="checkbox" id="justlogin" name="justlogin" >Just checks credentials.
</label>
</div>
@ -200,7 +157,7 @@ old: H2YTURNFT4XT4
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Shows folders sizes and exits."
type="checkbox" id="justfoldersizes" name="justfoldersizes" >Just folders sizes.
type="checkbox" id="justfoldersizes" name="justfoldersizes" >Just presents folders sizes.
</label>
</div>
@ -208,7 +165,7 @@ old: H2YTURNFT4XT4
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Just create the folder hierarchy, messages are not synced."
type="checkbox" id="justfolders" name="justfolders" >Folders only.
type="checkbox" id="justfolders" name="justfolders" >Just create folders.
</label>
</div>
@ -242,9 +199,9 @@ old: H2YTURNFT4XT4
<div id="account2" class="col-md-5" >
<fieldset>
<legend class="text-center h2">IMAP destination mailbox</legend>
<legend class="text-center h2">IMAP destination Mailbox</legend>
<label for="user2">Login</label>
<label for="user2">Login</label> (usually an email address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input
@ -264,13 +221,13 @@ old: H2YTURNFT4XT4
placeholder="Enter password">
</div>
<label for="host2">Server</label>
<label for="host2">IMAP Server hostname</label> (or its IP address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
list="servers2" type="text" class="form-control input-lg" id="host2" name="host2" tabindex="8"
placeholder="Enter imap destination server name or IP address">
placeholder="Enter IMAP destination server name or IP address">
<datalist id="servers2">
<option value="imap.gmail.com">
<option value="outlook.office365.com">
@ -304,22 +261,18 @@ old: H2YTURNFT4XT4
</div>
</fieldset>
</div>
</div>
<input type="hidden" name="automap" value="on">
<input type="hidden" name="addheader" value="on">
<!-- -#->
<input type="hidden" name="simulong" value="360">
<!-#- -->
<a id="buttons"></a>
<hr>
<!-- Classical button to go to the log only -->
<noscript>
<div class="row">
@ -356,10 +309,15 @@ old: H2YTURNFT4XT4
</div>
</div>
</form>
<div class="row scripton" id="consoles" >
<span id="imapsync_current" class="center-block text-center"></span>
<span id="imapsync_advice_hours" class="text-center collapse">
Best <a href="#local_bandwidth"><b>bandwidth available hours</b></a> are from <b>11h PM to 11h AM UTC</b> on Mondays to Fridays, <b>all hours</b> on Saturdays and <b>Sundays</b>.
</span>
<pre id="progress-txt">ETA: Estimation Time of Arrival</pre>
<div class="progress">
@ -390,7 +348,7 @@ old: H2YTURNFT4XT4
</pre>
</div>
</div>
</div>
<h2 class="text-center scripton">Log of imapsync run</h2>
@ -416,14 +374,68 @@ old: H2YTURNFT4XT4
</pre>
<a id="bottom"></a>
<div id="local_bandwidth" class="collapse">
<hr>
<p class="text-center">
<b>Local bandwidth statistics</b><br>
<a href="/vnstat/vnstati.html">
<img alt="Local bandwidth statistics" src="/vnstat/vnstat_vs.png" >
</a>
</p>
</div>
<div id="local_status_dbmon" class="collapse">
<hr>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last 24h</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_24h_1200x70">
</p>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last week</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_7d">
</p>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last two months</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_2months_1200x70"><br>
</p>
<!--
Uncomment the following when the data are available
-->
<!--
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last year</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_1year_1200x70"><br>
</p>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last 10 years</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_10years_1200x70-2"><br>
</p>
-->
</div>
<div id="local_status_hetrix" class="collapse in">
<hr>
<p class="text-center">
Local bandwidth statistics <br>
<a href="/vnstat/vnstati.html">
<img alt="Local bandwidth statistics" src="/vnstat/vnstat_vs.png" >
</a>
The service is down? For how long? How often? Take also a look at the
<a href="https://hetrixtools.com/report/uptime/7908dea8f3ff86eabdef6146307afd5f/414322.html">Imapsync Online Status</a>
monitor page powered by the <a href="https://hetrixtools.com/uptime-monitor/414322.html">HetrixTools</a> company.
</p>
</div>
<a id="bottom"></a>
<hr>
<p class="text-center">Feel free to contact
<strong><a href="https://imapsync.lamiral.info/#AUTHOR" target="_blank">Gilles LAMIRAL</a></strong>
@ -440,13 +452,12 @@ old: H2YTURNFT4XT4
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
<br>
<small> ($Id: imapsync_form_extra.html,v 1.4 2019/11/07 11:16:25 gilles Exp gilles $) </small><br>
<small> ($Id: imapsync_form_extra.html,v 1.18 2021/05/30 05:45:15 gilles Exp gilles $) </small><br>
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
</div>
</div>
</div>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
@ -461,11 +472,17 @@ crossorigin="anonymous"
>
</script>
<!--
<script src="crypto-js/core.js"></script>
<script src="crypto-js/sha256.js"></script>
-->
<script
src="imapsync_form_new.js"
src="imapsync_form.js"
>
</script>
<img src="https://static.scarf.sh/a.png?x-pxid=28b508c3-c51f-4109-9b88-29f3f6e4cf2f" alt="Scarf Tracker"/>
</body>
</html>

View file

@ -0,0 +1,547 @@
<!DOCTYPE html>
<!-- $Id: imapsync_form_extra_free.html,v 1.18 2021/05/30 05:45:00 gilles Exp gilles $ -->
<html lang="en" id="top">
<head>
<!--
<script
data-ad-client="ca-pub-3325993554161060"
async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
</script>
-->
<title>Mailbox Imapsync Online</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link rel="stylesheet" href="imapsync_form.css">
<link rel="stylesheet" href="../S/style.css" type="text/css" />
<link rel="license" href="https://imapsync.lamiral.info/NOLIMIT">
<noscript>
<link rel="stylesheet" href="noscript.css">
</noscript>
</head>
<body>
<div class="scripton">
<!-- will appear if some tests fail -->
<pre id="tests" class="collapse"></pre>
<!-- hidden stuff that must exit for the tests -->
<div class="hidden">
<input type="checkbox" id="test_checkbox">
<input type="text" id="test_text">
<input type="radio" id="test_radio1" name="test_radio" value="first" >
<input type="radio" id="test_radio2" name="test_radio" value="second" >
</div>
</div>
<div class="container-fluid" >
<div class="row">
<div class="text-center">
<a href="https://imapsync.lamiral.info/">
<img alt="Imapsync home" title="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
</a>
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
<a href="#payment" class="btn btn-success" data-toggle="collapse">Pricing</a>
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
</div>
</div>
<h1 class="text-center">Mailbox Imapsync Online</h1>
<p class="text-center larger"><strong>Copy/synchronize</strong> a <strong>Mailbox</strong> (below 3 GB) to another,
without <strong>duplicates!</strong><br>
<strong>Buying</strong> gives <strong>unlimited</strong> syncs of <strong>any size</strong>.</p>
<!-- Paypal part start
new: NDGMR6TLFZ926
old: H2YTURNFT4XT4
-->
<!-- A button above the pricing form, not very beautiful...
I should give it a try anyway because nearly no one buy this service...
<div class="text-center">
<a href="#payment" class="btn btn-warning btn-lg" data-toggle="collapse">Pricing</a>
</div>
-->
<!-- the "in" makes the form not collapsed by default
Remove the "in" in order to mask the pricing section
<div id="payment" class="well text-center collapse in" >
<div id="payment" class="well text-center collapse out" > -->
<div id="payment" class="well text-center collapse out" >
<p class="lead">Pay by usage type</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="H2YTURNFT4XT4" />
<input type="hidden" name="on0" value="imapsync choice" />
<fieldset>
<!--
<label data-toggle="tooltip" data-placement="top" title="Fair enough"
class="radio-inline"><input type="radio" name="os0" value="Tiny" > €1,00 </label>
<label data-toggle="tooltip" data-placement="top" title="A big mailbox"
class="radio-inline"><input type="radio" name="os0" value="Small" checked > €6,00 </label>
-->
<label data-toggle="tooltip" data-placement="top" title="Many mailboxes to migrate"
class="radio-inline"><input type="radio" name="os0" value="High" checked > €120,00 </label>
<label data-toggle="tooltip" data-placement="top" title="Some big mailboxes to migrate"
class="radio-inline"><input type="radio" name="os0" value="Normal" > €30,00 </label>
<br>
<input type="hidden" name="currency_code" value="EUR" />
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - A safe, easy way to pay online!" />
</fieldset>
<p>
<strong>30-day money back guarantee!</strong> <br>
<em><b>No question</b> nor condition to get a <b>refund</b>, really, <b>just request</b> it and you'll <b>sure</b> get a refund!</em>
</p>
<p>
<input type="hidden" value="VAT if professional in Europe" name="on1" />
If you're a <b>European professional</b> buyer, please enter your <b>VAT number</b>:
<input type="text" maxlength="17" size="17" name="os1" />
It's for the <b>invoice</b> and customs declaration.<br />
It's <b>ok</b> if you <b>don't</b> have a VAT number.<br />
</p>
</form>
</div>
<!-- Paypal part end -->
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
<div id="form_row" class="row">
<div id="account1" class="col-md-5" >
<fieldset>
<legend class="text-center h2">IMAP source Mailbox</legend>
<label for="user1">Login</label> (usually an email address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"> </i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
type="text" class="form-control input-lg" id="user1" name="user1" tabindex="1"
placeholder="Enter login name">
</div>
<label for="password1">Password</label>
<label class="checkbox-inline out">
<input type="checkbox" id="showpassword1"> show password
</label>
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
type="password" class="form-control input-lg" id="password1" name="password1" tabindex="2"
placeholder="Enter password">
</div>
<label for="host1">IMAP Server hostname</label> (or its IP address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
list="servers1" type="text" class="form-control input-lg" id="host1" name="host1" tabindex="3"
placeholder="Enter IMAP source server name or IP address">
<datalist id="servers1">
<option value="imap.gmail.com">
<option value="outlook.office365.com">
<option value="imap.mail.yahoo.com">
</datalist>
</div>
<div class="form-group collapse extra_param">
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Be careful with this option"
type="checkbox" id="delete1" name="delete1">Move sync. Deletes messages on source mailbox after a successful transfer.
</label>
</div>
<div class="form-group collapse extra_param" >
<label for="subfolder1">Sub-folder</label>
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-folder-open"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="A subfolder where all the source mailbox comes from."
type="text" class="form-control input-lg" id="subfolder1" name="subfolder1"
placeholder="Enter sub-folder name">
</div>
</div>
<div>
<br>
</div>
</fieldset>
</div>
<div id="parameters" class="col-md-2" >
<div>
<br>
</div>
<div>
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Shows what would be done without really doing it."
type="checkbox" id="dry" name="dry" >Just verbose, no real sync.
</label>
</div>
<div>
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Checks credentials without syncing anything."
type="checkbox" id="justlogin" name="justlogin" >Just checks credentials.
</label>
</div>
<div>
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Shows folders sizes and exits."
type="checkbox" id="justfoldersizes" name="justfoldersizes" >Just presents folders sizes.
</label>
</div>
<div>
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Just create the folder hierarchy, messages are not synced."
type="checkbox" id="justfolders" name="justfolders" >Just create folders.
</label>
</div>
<div>
<br>
</div>
<div id="button_extra_param" class="text-center scripton">
<button type="button" class="btn btn-default btn-block" data-toggle="collapse"
data-target=".extra_param">Show / Hide extra parameters</button>
</div>
<div>
<br>
</div>
<div id="button_swap" class="text-center scripton">
<button type="button" class="btn btn-default btn-block" id="swap">
Swap Source <span class="glyphicon glyphicon-transfer"></span> Destination
</button>
</div>
<div>
<br>
</div>
</div>
<div id="account2" class="col-md-5" >
<fieldset>
<legend class="text-center h2">IMAP destination Mailbox</legend>
<label for="user2">Login</label> (usually an email address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
type="text" class="form-control input-lg" id="user2" name="user2" tabindex="6"
placeholder="Enter login name">
</div>
<label for="password2">Password</label>
<label class="checkbox-inline out">
<input type="checkbox" id="showpassword2"> show password
</label>
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
type="password" class="form-control input-lg" id="password2" name="password2" tabindex="7"
placeholder="Enter password">
</div>
<label for="host2">IMAP Server hostname</label> (or its IP address)
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
list="servers2" type="text" class="form-control input-lg" id="host2" name="host2" tabindex="8"
placeholder="Enter IMAP destination server name or IP address">
<datalist id="servers2">
<option value="imap.gmail.com">
<option value="outlook.office365.com">
<option value="imap.mail.yahoo.com">
</datalist>
</div>
<!-- -->
<div class="form-group collapse extra_param">
<label class="checkbox-inline">
<input
data-toggle="tooltip" data-placement="bottom" title="Be careful with this option"
type="checkbox" id="delete2" name="delete2" tabindex="9">Strict sync. Deletes messages on destination mailbox that are not at the source mailbox.
</label>
</div>
<div class="form-group collapse extra_param" id="extra_subfolder2" >
<label for="subfolder2">Sub-folder</label>
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-folder-open"></i></span>
<input
data-toggle="tooltip" data-placement="bottom" title="A subfolder where all the source mailbox will go."
type="text" class="form-control input-lg" id="subfolder2" name="subfolder2"
placeholder="Enter sub-folder name">
</div>
</div>
<!-- -->
<div>
<br>
</div>
</fieldset>
</div>
</div>
<input type="hidden" name="automap" value="on">
<input type="hidden" name="addheader" value="on">
<input type="hidden" name="exitwhenover" value="3000000000">
<!-- -#->
<input type="hidden" name="simulong" value="360">
<!-#- -->
<a id="buttons"></a>
<hr>
<!-- Classical button to go to the log only -->
<noscript>
<div class="row">
<div class="col-sm-12 padd0" >
<button type="submit" class="btn btn-success btn-lg center-block btn-block">Go sync!</button>
</div>
</div>
</noscript>
<!-- Javascript buttons using xhr -->
<div class="row scripton">
<div class="col-sm-6 padd0" >
<button id="bt-sync" type="button"
class="btn btn-success btn-lg center-block btn-block"
tabindex="11"
data-toggle="tooltip" data-placement="top"
title="Launch the sync! You can abort the sync with the red Abort button nearby or by closing the tab/window."
>
Sync or resync!<br>
<span class="glyphicon glyphicon-envelope"></span>
<span class="glyphicon glyphicon-arrow-right"></span>
<span class="glyphicon glyphicon-envelope"></span>
</button>
</div>
<div class="col-sm-6 padd0" >
<button id="bt-abort" type="button"
class="btn btn-danger btn-lg center-block btn-block" tabindex="12"
data-toggle="tooltip" data-placement="top"
title="Abort the sync! You can restart the sync later, no duplicates should happen."
>
Abort!<br>
<span class="glyphicon glyphicon-scissors"></span>
</button>
</div>
</div>
</form>
<div class="row scripton" id="consoles" >
<span id="imapsync_current" class="center-block text-center"></span>
<span id="imapsync_advice_hours" class="text-center collapse">
Best <a href="#local_bandwidth"><b>bandwidth available hours</b></a> are from <b>11h PM to 11h AM UTC</b> on Mondays to Fridays, <b>all hours</b> on Saturdays and <b>Sundays</b>.
</span>
<pre id="progress-txt">ETA: Estimation Time of Arrival</pre>
<div class="progress">
<div id="progress-bar-done" class="progress-bar progress-bar-success" role="progressbar">
Progress bar
</div>
<div id="progress-bar-left" class="progress-bar progress-bar-info" role="progressbar">
Progress bar
</div>
</div>
<div class="col-sm-6 well">
<h2 class="text-center">Console of imapsync launch</h2>
<pre id="console">
</pre>
<a id="link_to_bottom" href="#bottom">Bottom of imapsync log</a>
</div>
<div class="col-sm-6 well">
<h2 class="text-center">Console of abort</h2>
<pre id="abort">
</pre>
</div>
</div>
</div>
<h2 class="text-center scripton">Log of imapsync run</h2>
<pre id="output" class="scripton">
</pre>
<div id="local_bandwidth" class="collapse">
<hr>
<p class="text-center">
<b>Local bandwidth statistics</b><br>
<a href="/vnstat/vnstati.html">
<img alt="Local bandwidth statistics" src="/vnstat/vnstat_vs.png" >
</a>
</p>
</div>
<div id="local_status_dbmon" class="collapse">
<hr>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last 24h</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_24h_1200x70">
</p>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last week</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_7d">
</p>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last two months</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_2months_1200x70"><br>
</p>
<!--
Uncomment the following when the data are available
-->
<!--
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last year</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_1year_1200x70"><br>
</p>
<p class="text-center">
Imapsync <b>Online Status</b> over the <b>last 10 years</b><br>
<img class="img-responsive center-block" alt="Imapsync Online Status" src="https://lstu.fr/imapsync_online_status_10years_1200x70-2"><br>
</p>
-->
</div>
<div id="local_status_hetrix" class="collapse in">
<hr>
<p class="text-center">
The service is down? For how long? How often? Take also a look at the
<a href="https://hetrixtools.com/report/uptime/7908dea8f3ff86eabdef6146307afd5f/414322.html">Imapsync Online Status</a>
monitor page powered by the <a href="https://hetrixtools.com/uptime-monitor/414322.html">HetrixTools</a> company.
</p>
</div>
<a id="bottom"></a>
<hr>
<p class="text-center">Feel free to contact
<strong><a href="https://imapsync.lamiral.info/#AUTHOR" target="_blank">Gilles LAMIRAL</a></strong>
</p>
<div class="container-fluid" >
<div class="row">
<div class="text-center">
<a href="https://imapsync.lamiral.info/">
<img alt="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
</a>
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
<br>
<small> ($Id: imapsync_form_extra_free.html,v 1.18 2021/05/30 05:45:00 gilles Exp gilles $) </small><br>
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
</div>
</div>
</div>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
crossorigin="anonymous"
>
</script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"
>
</script>
<!--
<script src="crypto-js/core.js"></script>
<script src="crypto-js/sha256.js"></script>
-->
<script
src="imapsync_form.js"
>
</script>
<img src="https://static.scarf.sh/a.png?x-pxid=28b508c3-c51f-4109-9b88-29f3f6e4cf2f" alt="Scarf Tracker"/>
</body>
</html>

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<!-- $Id: imapsync_form.html,v 1.69 2019/03/31 22:25:15 gilles Exp $ -->
<!-- $Id: imapsync_form_wrapper.html,v 1.1 2020/03/04 14:10:30 gilles Exp gilles $ -->
<html lang="en" id="top">
@ -20,9 +20,7 @@
<noscript>
<style>
.scripton {display:none;}
</style>
<link rel="stylesheet" href="noscript.css">
</noscript>
</head>
@ -30,6 +28,18 @@
<body>
<div class="scripton">
<!-- will appear if some tests fail -->
<pre id="tests" class="collapse"></pre>
<!-- hidden stuff that must exit for the tests -->
<div class="hidden">
<input type="checkbox" id="test_checkbox">
<input type="text" id="test_text">
<input type="radio" id="test_radio1" name="test_radio" value="first" >
<input type="radio" id="test_radio2" name="test_radio" value="second" >
</div>
</div>
<div class="container-fluid" >
<div class="row">
@ -59,11 +69,11 @@ old: H2YTURNFT4XT4
<a href="#payment" class="btn btn-warning btn-lg" data-toggle="collapse">Pricing</a>
</div>
-->
<!-- the "in" makes the form not collapsed by default
Remove the in in order to mask the pricing section
<div id="payment" class="well text-center collapse in" > -->
<div id="payment" class="well text-center collapse" >
<div id="payment" class="well text-center collapse out" >
<p class="lead">Pay by usage type</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick" />
@ -93,9 +103,9 @@ old: H2YTURNFT4XT4
</form>
</div>
<!-- Paypal part end -->
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
<form id="form" action="/cgi-bin/imapsync_shell_wrapper" method="post" autocomplete="on">
<div class="row">
<div id="account1" class="col-md-6" >
<fieldset>
@ -111,7 +121,7 @@ old: H2YTURNFT4XT4
</div>
<label for="password1">Password</label>
<label class="checkbox-inline">
<label class="checkbox-inline out">
<input type="checkbox" id="showpassword1"> show password
</label>
<div class="input-group form-group">
@ -163,7 +173,7 @@ old: H2YTURNFT4XT4
placeholder="Enter login name">
</div>
<label for="password2">Password</label>
<label class="checkbox-inline">
<label class="checkbox-inline out">
<input type="checkbox" id="showpassword2"> show password
</label>
<div class="input-group form-group">
@ -203,10 +213,10 @@ old: H2YTURNFT4XT4
</div>
<input type="hidden" name="automap" value="on">
<input type="hidden" name="addheader" value="on">
<!-- --#>
<!-- -#->
<input type="hidden" name="simulong" value="360">
<#!-- -->
<a name="buttons"></a>
<!-#- -->
<a id="buttons"></a>
<hr>
<!-- Classical button to go to the log only -->
@ -244,6 +254,18 @@ old: H2YTURNFT4XT4
<div class="row scripton" id="consoles">
<pre id="progress-txt">ETA: Estimation Time of Arrival</pre>
<div class="progress">
<div id="progress-bar-done" class="progress-bar progress-bar-success" role="progressbar">
Progress bar
</div>
<div id="progress-bar-left" class="progress-bar progress-bar-info" role="progressbar">
Progress bar
</div>
</div>
<div class="col-sm-6 well">
<h2 class="text-center">Console of imapsync run</h2>
<pre id="console">
@ -289,7 +311,7 @@ old: H2YTURNFT4XT4
</pre>
<a name="bottom"></a>
<a id="bottom"></a>
<hr>
<p class="text-center">
Local bandwidth statistics <br>
@ -313,7 +335,7 @@ old: H2YTURNFT4XT4
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
<br>
<small> ($Id: imapsync_form.html,v 1.69 2019/03/31 22:25:15 gilles Exp $) </small><br>
<small> ($Id: imapsync_form_wrapper.html,v 1.1 2020/03/04 14:10:30 gilles Exp gilles $) </small><br>
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
</div>
</div>
@ -336,7 +358,7 @@ crossorigin="anonymous"
<script
src="imapsync_form.js"
src="imapsync_form_wrapper.js"
>
</script>

704
X/imapsync_form_wrapper.js Normal file
View file

@ -0,0 +1,704 @@
// $Id: imapsync_form_wrapper.js,v 1.2 2020/03/04 14:09:21 gilles Exp gilles $
/*jslint browser: true*/ /*global $*/
$(document).ready(
function ()
{
"use strict";
// Bootstrap popover and tooltip
$("[data-toggle='tooltip']").tooltip();
var readyStateStr = {
"0": "Request not initialized",
"1": "Server connection established",
"2": "Response headers received",
"3": "Processing request",
"4": "Finished and response is ready"
} ;
var refresh_interval_ms = 5000 ;
var refresh_interval_s = refresh_interval_ms / 1000 ;
var test = {
counter_all : 0 ,
counter_ok : 0 ,
counter_nok : 0 ,
failed_tests : ""
} ;
var is = function is( expected, given, comment )
{
test.counter_all += 1 ;
var message = test.counter_all + " - ["
+ expected
+ "] === ["
+ given
+ "] "
+ comment
+ "\n" ;
if ( expected === given )
{
test.counter_ok += 1 ;
message = "ok " + message ;
}
else
{
test.counter_nok += 1 ;
test.failed_tests += "nb " + message + "\n" ;
message = "not ok " + message ;
}
$("#tests").append( message ) ;
} ;
function last_eta( string )
{
// return the last occurrence of the substring "ETA: ...\n"
// or "ETA: unknown" or ""
var eta ;
var last_found ;
if ( undefined === string )
{
return "" ;
}
var eta_re = /ETA:.*\n/g ;
eta = string.match( eta_re ) ;
if ( eta )
{
last_found = eta[eta.length -1 ] ;
return last_found ;
}
else
{
return "ETA: unknown" ;
}
}
function tests_last_eta()
{
is( "", last_eta( ), "last_eta: no args => empty string" ) ;
is(
"ETA: unknown",
last_eta( "" ),
"last_eta: empty => empty string" ) ;
is( "ETA: unknown",
last_eta( "ETA" ),
"last_eta: ETA => empty string" ) ;
is( "ETA: unknown", last_eta( "ETA: but no CR" ),
"last_eta: ETA: but no CR => empty string" ) ;
is(
"ETA: with CR\n",
last_eta( "Blabla ETA: with CR\n" ),
"last_eta: ETA: with CR => ETA: with CR"
) ;
is(
"ETA: 2 with CR\n",
last_eta( "Blabla ETA: 1 with CR\nBlabla ETA: 2 with CR\n" ),
"last_eta: several ETA: with CR => ETA: 2 with CR"
) ;
}
var tests_decompose_eta_line = function tests_decompose_eta_line()
{
var eta_obj ;
var eta_str = "ETA: Wed Jul 3 14:55:27 2019 1234 s 123/4567 msgs left\n" ;
eta_obj = decompose_eta_line( "" ) ;
is(
"",
eta_obj.str,
"decompose_eta_line: no match => undefined"
) ;
eta_obj = decompose_eta_line( eta_str ) ;
is(
eta_str,
eta_str,
"decompose_eta_line: str is str"
) ;
is(
eta_str,
eta_obj.str,
"decompose_eta_line: str back"
) ;
is(
"Wed Jul 3 14:55:27 2019",
eta_obj.date,
"decompose_eta_line: date"
) ;
is(
"1234",
eta_obj.seconds_left,
"decompose_eta_line: seconds_left"
) ;
is(
"123",
eta_obj.msgs_left,
"decompose_eta_line: msgs_left"
) ;
is(
"4567",
eta_obj.msgs_total,
"decompose_eta_line: msgs_total"
) ;
is(
"4444",
eta_obj.msgs_done(),
"decompose_eta_line: msgs_done"
) ;
is(
"97.31",
eta_obj.percent_done(),
"decompose_eta_line: percent_done"
) ;
is(
"2.69",
eta_obj.percent_left(),
"decompose_eta_line: percent_left"
) ;
} ;
var decompose_eta_line = function decompose_eta_line( eta_str )
{
var eta_obj ;
var eta_array ;
var regex_eta = /^ETA:\s+(.*?)\s+([0-9]+)\s+s\s+([0-9]+)\/([0-9]+)\s+msgs\s+left\n?$/ ;
eta_array = regex_eta.exec( eta_str ) ;
if ( null !== eta_array )
{
eta_obj = {
str : eta_str,
date : eta_array[1],
seconds_left : eta_array[2],
msgs_left : eta_array[3],
msgs_total : eta_array[4],
msgs_done : function() {
var diff = eta_obj.msgs_total - eta_obj.msgs_left ;
return( diff.toString() ) ;
},
percent_done : function() {
var percent ;
if ( 0 === eta_obj.msgs_total )
{
return "0" ;
}
else
{
percent = ( eta_obj.msgs_total - eta_obj.msgs_left ) / eta_obj.msgs_total * 100 ;
return( percent.toFixed(2) ) ;
}
},
percent_left : function() {
var percent ;
if ( 0 === eta_obj.msgs_total )
{
return "0" ;
}
else
{
percent = ( eta_obj.msgs_left / eta_obj.msgs_total * 100 ) ;
return( percent.toFixed(2) ) ;
}
}
} ;
}
else
{
eta_obj = {
str : "",
date : "?",
seconds_left : "?",
msgs_left : "?",
msgs_total : "?",
msgs_done : "?",
percent_done : function() { return "" ; },
percent_left : function() { return "" ; }
} ;
}
return eta_obj ;
} ;
var extract_eta = function extract_eta( xhr )
{
var eta_obj ;
var slice_length ;
var slice_log ;
var eta_str ;
if ( xhr.readyState === 4 )
{
slice_length = -24000 ;
}
else
{
slice_length = -240 ;
}
slice_log = xhr.responseText.slice( slice_length ) ;
eta_str = last_eta( slice_log ) ;
// $("#tests").append( "extract_eta eta_str: " + eta_str + "\n" ) ;
eta_obj = decompose_eta_line( eta_str ) ;
return eta_obj ;
} ;
var progress_bar_update = function progress_bar_update( eta_obj )
{
if ( eta_obj.str.length )
{
$("#progress-bar-done").css( "width", eta_obj.percent_done() + "%" ).attr( "aria-valuenow", eta_obj.percent_done() ) ;
$("#progress-bar-left").css( "width", eta_obj.percent_left() + "%" ).attr( "aria-valuenow", eta_obj.percent_left() ) ;
$("#progress-bar-done").text( eta_obj.percent_done() + "% " + "done" ) ;
$("#progress-bar-left").text( eta_obj.percent_left() + "% " + "left" ) ;
}
else
{
$("#progress-bar-done").text( "unknown % " + "done" ) ;
$("#progress-bar-left").text( "unknown % " + "left" ) ;
}
return ;
} ;
function refreshLog( xhr )
{
var eta_obj ;
var eta_str ;
eta_obj = extract_eta( xhr ) ;
progress_bar_update( eta_obj ) ;
if ( xhr.readyState === 4 )
{
// end of sync
$("#progress-txt").text(
"Ended. It remains "
+ eta_obj.msgs_left + " messages to be synced" ) ;
}
else
{
eta_str = eta_obj.str + " (refresh every " + refresh_interval_s + " s)" ;
eta_str = eta_str.replace(/(\r\n|\n|\r)/gm, "") ; // trim newline
//$("#tests").append( "refreshLog eta_str: " + eta_str + "\n" ) ;
$("#progress-txt").text( eta_str ) ;
}
$( "#output" ).text( xhr.responseText ) ;
}
function handleRun(xhr, timerRefreshLog)
{
$("#console").text(
"Status: " + xhr.status + " " + xhr.statusText + "\n"
+ "State: " + readyStateStr[xhr.readyState] + "\n" ) ;
if ( xhr.readyState === 4 ) {
// var headers = xhr.getAllResponseHeaders();
// $("#console").append(headers);
// $("#console").append("See the completed log\n");
$("#link_to_bottom").show() ;
clearInterval( timerRefreshLog ) ;
refreshLog( xhr ) ; // a last time
// back to enable state for next run
$("#bt-sync").prop("disabled", false) ;
}
}
function imapsync()
{
var querystring = $("#form").serialize() ;
$("#abort").text("\n\n") ; // clean abort console
$("#output").text("Here comes the log!\n\n") ;
if ( "imap.gmail.com" === $("#host1").val() )
{
querystring = querystring + "&gmail1=on" ;
}
if ( "imap.gmail.com" === $("#host2").val() )
{
querystring = querystring + "&gmail2=on" ;
}
// Same for "outlook.office365.com"
if ( "outlook.office365.com" === $("#host1").val() )
{
querystring = querystring + "&office1=on" ;
}
if ( "outlook.office365.com" === $("#host2").val() )
{
querystring = querystring + "&office2=on" ;
}
var xhr ;
xhr = new XMLHttpRequest() ;
var timerRefreshLog = setInterval(
function ()
{
refreshLog( xhr ) ;
}, refresh_interval_ms ) ;
xhr.onreadystatechange = function ()
{
handleRun( xhr, timerRefreshLog ) ;
} ;
xhr.open( "POST", "/cgi-bin/imapsync_shell_wrapper", true ) ;
xhr.setRequestHeader( "Content-type",
"application/x-www-form-urlencoded" ) ;
xhr.send( querystring ) ;
}
function handleAbort( xhr )
{
$( "#abort" ).text(
"Status: " + xhr.status + " " + xhr.statusText + "\n"
+ "State: " + readyStateStr[xhr.readyState] + "\n\n" ) ;
if ( xhr.readyState === 4 )
{
$("#abort").append(xhr.responseText);
$("#bt-sync").prop("disabled", false);
$("#bt-abort").prop("disabled", false); // back for next abort
}
}
function abort()
{
var querystring = $("#form").serialize() + "&abort=on";
var xhr;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function ()
{
handleAbort(xhr);
};
xhr.open("POST", "/cgi-bin/imapsync_shell_wrapper", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(querystring);
}
function store( id )
{
var stored ;
//$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + "\n" ) ;
if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
{
localStorage.setItem( id, $(id).val() ) ;
stored = $( id ).val() ;
}
else if ( "checkbox" === $( id ).attr( "type" ) )
{
//$( "#tests" ).append( "Eco: " + id + " checked is " + $( id )[0].checked + "\n" ) ;
localStorage.setItem( id, $( id )[0].checked ) ;
stored = $( id )[0].checked ;
}
return stored ;
}
function retrieve( id )
{
var retrieved ;
//$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + " length is " + $( id ).length + "\n" ) ;
if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
{
$( id ).val( localStorage.getItem( id ) ) ;
retrieved = $( id ).val() ;
}
else if ( "checkbox" === $( id ).attr( "type" ) )
{
//$( "#tests" ).append( "Eco: " + id + " getItem is " + localStorage.getItem( id ) + "\n" ) ;
$( id )[0].checked = JSON.parse( localStorage.getItem( id ) ) ;
retrieved = $( id )[0].checked ;
}
return retrieved ;
}
function tests_store_retrieve()
{
if ( $("#tests").length !== 0 )
{
is( 1, 1, "one equals one" ) ;
// isnot( 0, 1, "zero differs one" ) ;
// no exist
is( undefined, store( "#test_noexists" ),
"store: #test_noexists" ) ;
is( undefined, retrieve( "#test_noexists" ),
"retrieve: #test_noexists" ) ;
is( undefined, retrieve( "#test_noexists2" ),
"retrieve: #test_noexists2" ) ;
// input text
$("#test_text" ).val( "foo" ) ;
is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
is( "foo", store( "#test_text" ), "store: #test_text" ) ;
$("#test_text" ).val( "bar" ) ;
is( "bar", $("#test_text" ).val( ), "#test_text val = bar" ) ;
is( "foo", retrieve( "#test_text" ), "retrieve: #test_text = foo" ) ;
is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
// input check button
$( "#test_checkbox" ).prop( "checked", true );
is( true, store( "#test_checkbox" ), "store: #test_checkbox checked" ) ;
$( "#test_checkbox" ).prop( "checked", false );
is( true, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = true" ) ;
$( "#test_checkbox" ).prop( "checked", false );
is( false, store( "#test_checkbox" ), "store: #test_checkbox not checked" ) ;
$( "#test_checkbox" ).prop( "checked", true );
is( false, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = false" ) ;
}
}
function store_form()
{
if ( Storage !== "undefined")
{
// Code for localStorage.
store("#user1") ;
store("#password1") ;
store("#host1") ;
store("#subfolder1") ;
store("#showpassword1") ;
store("#user2") ;
store("#password2") ;
store("#host2") ;
store("#subfolder2") ;
store("#showpassword2") ;
store("#dry") ;
store("#justlogin") ;
store("#justfolders") ;
store("#justfoldersizes") ;
localStorage.account1_background_color = $("#account1").css("background-color") ;
localStorage.account2_background_color = $("#account2").css("background-color") ;
}
}
function show_extra_if_needed()
{
if ( $("#subfolder1").length && $("#subfolder1").val().length > 0 )
{
$(".extra_param").show() ;
}
if ( $("#subfolder2").length && $("#subfolder2").val().length > 0 )
{
$(".extra_param").show() ;
}
}
function retrieve_form()
{
if ( Storage !== "undefined" )
{
// Code for localStorage.
retrieve( "#user1" ) ;
retrieve( "#password1" ) ;
// retrieve("#showpassword1") ;
retrieve( "#host1" ) ;
retrieve( "#subfolder1" ) ;
retrieve( "#user2" ) ;
retrieve( "#password2" ) ;
// retrieve("#showpassword2") ;
retrieve( "#host2" ) ;
retrieve( "#subfolder2" ) ;
retrieve( "#dry" ) ;
retrieve( "#justlogin" ) ;
retrieve( "#justfolders" ) ;
retrieve( "#justfoldersizes" ) ;
// In case, how to restore the original color from css file.
// localStorage.removeItem( "account1_background_color" ) ;
// localStorage.removeItem( "account2_background_color" ) ;
if ( localStorage.account1_background_color )
{
$("#account1").css("background-color",
localStorage.account1_background_color ) ;
}
if ( localStorage.account2_background_color )
{
$("#account2").css("background-color",
localStorage.account2_background_color ) ;
}
// Show the extra parameters if they are not empty because it would be dangerous
// to retrieve them without knowing
show_extra_if_needed() ;
}
}
function showpassword( id, button )
{
var x = document.getElementById( id );
if ( button.checked )
{
x.type = "text";
} else {
x.type = "password";
}
}
function init()
{
// in case of a manual refresh, start with
$("#bt-sync").prop("disabled", false);
$("#bt-abort").prop("disabled", false);
$("#link_to_bottom").hide();
$("#progress-bar-left").css( "width", 100 + "%" ).attr( "aria-valuenow", 100 ) ;
retrieve_form();
$("#showpassword1").click(
function ( event )
{
var button = event.target ;
showpassword( "password1", button ) ;
}
);
$("#showpassword2").click(
function ( event )
{
//$("#tests").append( "\nthat1=" + JSON.stringify( event.target, undefined, 4 ) ) ;
var button = event.target ;
showpassword( "password2", button ) ;
}
);
$("#bt-sync").click(
function ()
{
$("#bt-sync").prop("disabled", true) ;
$("#bt-abort").prop("disabled", false) ;
$("#link_to_bottom").hide() ;
$("#progress-txt").text( "ETA: coming soon" ) ;
store_form() ;
imapsync() ;
}
);
$("#bt-abort").click(
function ()
{
$("#bt-sync").prop("disabled", true);
$("#bt-abort").prop("disabled", true);
abort();
}
);
var swap = function swap( p1, p2 )
{
var temp = $( p2 ).val( ) ;
$( p2 ).val( $( p1 ).val( ) ) ;
$( p1 ).val( temp ) ;
} ;
$("#swap").click(
function()
{
// swaping colors can't use swap()
var temp1 = $("#account1").css("background-color") ;
var temp2 = $("#account2").css("background-color") ;
$("#account1").css("background-color", temp2 );
$("#account2").css("background-color", temp1 );
swap( $("#user1"), $("#user2") ) ;
swap( $("#password1"), $("#password2") ) ;
swap( $("#host1"), $("#host2") ) ;
swap( $("#subfolder1"), $("#subfolder2") ) ;
var temp = $("#showpassword1")[0].checked ;
$("#showpassword1")[0].checked = $("#showpassword2")[0].checked ;
$("#showpassword2")[0].checked = temp ;
showpassword( "password1", $("#showpassword1")[0] ) ;
showpassword( "password2", $("#showpassword2")[0] ) ;
}
) ;
}
var tests_bilan = function tests_bilan()
{
// attended number of tests
var nb_attended_test = 29 ;
$("#tests").append( "1.." + test.counter_all + "\n" ) ;
if ( test.counter_nok > 0 )
{
$("#tests").append(
"\nFAILED tests \n"
+ test.failed_tests
) ;
$("#tests").collapse("show") ;
}
// Summary of tests: failed 0 tests, run xx tests,
// expected to run yy tests.
if ( test.counter_all !== nb_attended_test )
{
$("#tests").append( "# Looks like you planned "
+ nb_attended_test
+ " tests but ran "
+ test.counter_all + ".\n"
) ;
$("#tests").collapse("show") ;
}
} ;
function tests()
{
if ( $("#tests").length !== 0 )
{
tests_store_retrieve( ) ;
tests_last_eta( ) ;
tests_decompose_eta_line( ) ;
//is( 0, 1, "this test always fails" ) ;
tests_bilan( ) ;
//$("#tests").collapse("show") ;
}
}
init( ) ;
tests( ) ;
}
);

55
X/imapsync_shell_wrapper Executable file
View file

@ -0,0 +1,55 @@
#!/bin/sh
# $Id: imapsync_shell_wrapper,v 1.6 2020/03/26 22:24:10 gilles Exp gilles $
## A pure working wrapper is like this one for example:
## Uncomment the following lines to test it
#/usr/lib/cgi-bin/imapsync
#date
#id
#cal
#exit
## but the previous is a little useless and uneasy to add extra parameters
## We need a little extra work.
# Count characters in files, except the \r \n characters
count_chars_but_nl()
{
cat "$@" | tr -d '\r\n' | wc -c
}
# Run imapsync with parameters written in files given in arguments
imapsync_with_extra_param()
{
# Update the environment variable CONTENT_LENGTH
# This update is mandatory or the augmented parameters list will be truncated by imapsync.
CONTENT_LENGTH=`count_chars_but_nl "$@"`
cat "$@" | tr -d '\r\n' | /usr/lib/cgi-bin/imapsync
}
# The actual stuff
# Save the UI parameters in a file
cat > /tmp/imapsync_shell_wrapper_from_ui.txt
# Now run imapsync with the UI parameters and the extra parameters
imapsync_with_extra_param /tmp/imapsync_shell_wrapper_from_ui.txt /tmp/imapsync_shell_wrapper_extra.txt
echo imapsync first run exited with return code $?
echo
who
date
# A second run with other some extra_2 parameters
imapsync_with_extra_param /tmp/imapsync_shell_wrapper_from_ui.txt /tmp/imapsync_shell_wrapper_extra_2.txt
echo imapsync last run exited with return code $?
echo
cal
echo
echo Bye bye
# Got the picture?

View file

@ -1 +1 @@
imapsync_form_extra.html
imapsync_form_extra_free.html

10364
X/jquery-3.3.1.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

166
X/sandbox_csv.html Executable file
View file

@ -0,0 +1,166 @@
<!DOCTYPE html>
<html>
<head>
<title>Imapsync CSV online</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- -->
</head>
<body>
<h1>Imapsync online</h1>
<p>
This file is a sandbox to play with, to learn, understand what happens, what can be done etc.<br/>
<a href="#BOTTOM">Bottom of this page</a>
</p>
<form id="form" action="/cgi-bin/imapsync_csv_wrapper" method="post" autocomplete="on">
<textarea name="csv_data" rows="10" cols="120">
# This example is a real one, ie, truly working in the real world.
test1.lamiral.info;test1;secret1;test2.lamiral.info;test2;secret2;
# The reverse
test2.lamiral.info;test2;secret2;test1.lamiral.info;test1;secret1;
# The first again but with authentication failure
test1.lamiral.info;test1;secret1;test2.lamiral.info;test2;wrong;
</textarea>
<br/>
</form>
<button type="button"
onclick="imapsync( handleRun )"
>Run imapsync on all csv data
</button>
<button type="button"
onclick="abort( )"
>Abort imapsync
</button>
<h2>Console of imapsync runs</h2>
<pre id="console">
</pre>
<h2>Log of abort</h2>
<pre id="abort">
</pre>
<h2>Log of imapsync runs</h2>
<pre id="output" >
</pre>
<h2>Links</h2>
<div id="BOTTOM">
<p >
<a href="#TOP">Top of the page</a>
</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
var readyStateStr = {
0: "Request not initialized",
1: "Server connection established",
2: "Response headers received",
3: "Processing request",
4: "Finished and response is ready"
} ;
function imapsync( cFunction ) {
var xhr ;
xhr = new XMLHttpRequest( ) ;
var timerRefreshLog = setInterval( function() { refreshLog( xhr ) }, 3000 ) ;
xhr.onreadystatechange = function( ) {
cFunction( this, timerRefreshLog ) ;
} ;
var form_querystring = $("#form").serialize() ;
$("#form_querystring").text( form_querystring ) ;
xhr.open( "POST", "/cgi-bin/imapsync_csv_wrapper", true ) ;
xhr.setRequestHeader( "Content-type",
"application/x-www-form-urlencoded" ) ;
xhr.send( form_querystring ) ;
$("#output").text("Here comes the log!\n\n") ;
xhr.send( ) ;
}
function handleRun( xhr, timerRefreshLog ) {
$( "#console" ).text( "Status: " + xhr.status + " " + xhr.statusText + ".\n"
+ "State: " + readyStateStr[ xhr.readyState ] + "\n" ) ;
if ( xhr.status == 200 && xhr.readyState == 4 ) {
var headers = xhr.getAllResponseHeaders( ) ;
clearInterval( timerRefreshLog ) ;
refreshLog( xhr ) ; // a last time
}
}
function refreshLog( xhr ) {
$( "#output" ).text( xhr.responseText ) ;
}
function abort()
{
var querystring = $("#form").serialize() + "&abort=on";
var xhr;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function ()
{
handleAbort(xhr);
};
xhr.open("POST", "/cgi-bin/imapsync_csv_wrapper", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(querystring);
}
function handleAbort( xhr ) {
$( "#abort" ).text( "Status: " + xhr.status + " " + xhr.statusText + ".\n"
+ "State: " + readyStateStr[ xhr.readyState ] + "\n" ) ;
if ( xhr.status == 200 && xhr.readyState == 4 ) {
var headers = xhr.getAllResponseHeaders( ) ;
// $( "#abort" ).append( "\n" + headers + "\n" ) ;
$( "#abort" ).append( xhr.responseText ) ;
}
}
</script>
</body>
</html>

View file

@ -1,5 +1,5 @@
Dovecot Dovecot
OK_IMAP4_ready \\* OK IMAP4 ready.
MailEnable \\* OK IMAP4 ready.
Courier Courier-IMAP ready.
Exchange Microsoft Exchange
SmarterMail \\* OK IMAP4rev1 SmarterMail.$

View file

@ -24,15 +24,18 @@
^Host2 Biggest message:
^Host2 Time spent:
^Messages transferred
^Messages skipped
^Messages found duplicate on host1
^Messages found duplicate on host2
^Messages found crossduplicate on host2
^Messages found in host1 not in host2
^Messages found in host2 not in host1
^Messages skipped
^Folders synced
^Transfer time
^Total bytes transferred
^Message rate
^Average bandwidth rate
^Biggest message
^Biggest message transferred
^Detected.*errors
^Ended by a signal
^Exiting with return value
@ -43,3 +46,8 @@ failure: Error login
failure: can not open imap connection on
^\/usr\/local\/www\/apache24\/cgi-bin\/imapsync --
^\/usr\/lib\/cgi-bin\/imapsync --
success login on
^At least one account can not SEARCH ALL
{[456789]........} copied
^Memory\/biggest message ratio
^CPU time and %cpu

1
X/u.html Symbolic link
View file

@ -0,0 +1 @@
imapsync_form_extra.html