diff -Nru isync-1.1.0/aclocal.m4 isync-1.2.1-1.812.20170514/aclocal.m4 --- isync-1.1.0/aclocal.m4 2013-12-18 21:09:56.000000000 +0000 +++ isync-1.2.1-1.812.20170514/aclocal.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,1150 +0,0 @@ -# generated automatically by aclocal 1.14 -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.14' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.14], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.14])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([acinclude.m4]) diff -Nru isync-1.1.0/autodefs.h.in isync-1.2.1-1.812.20170514/autodefs.h.in --- isync-1.1.0/autodefs.h.in 2013-12-18 21:09:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/autodefs.h.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* autodefs.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the `getaddrinfo' function. */ -#undef HAVE_GETADDRINFO - -/* Define to 1 if you have the `getopt_long' function. */ -#undef HAVE_GETOPT_LONG - -/* Define to 1 if you have the `inet_ntop' function. */ -#undef HAVE_INET_NTOP - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* if your libc has IPv6 support */ -#undef HAVE_IPV6 - -/* if you have the OpenSSL libraries */ -#undef HAVE_LIBSSL - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `memrchr' function. */ -#undef HAVE_MEMRCHR - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_POLL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `vasprintf' function. */ -#undef HAVE_VASPRINTF - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION diff -Nru isync-1.1.0/autogen.sh isync-1.2.1-1.812.20170514/autogen.sh --- isync-1.1.0/autogen.sh 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/autogen.sh 2017-05-26 14:36:31.000000000 +0000 @@ -0,0 +1,4 @@ +#! /bin/sh +set -e -v +make -f Makefile.am log +autoreconf -f -i diff -Nru isync-1.1.0/ChangeLog isync-1.2.1-1.812.20170514/ChangeLog --- isync-1.1.0/ChangeLog 2013-12-18 21:10:10.000000000 +0000 +++ isync-1.2.1-1.812.20170514/ChangeLog 1970-01-01 00:00:00.000000000 +0000 @@ -1,4362 +0,0 @@ -2013-12-08 21:29 Oswald Buddenhagen - - * README, src/mbsyncrc.sample: - - pre-release doc updates - -2013-12-14 11:37 Oswald Buddenhagen - - * src/mbsync.1: - - elaborate on expunging and trashing - -2013-12-13 18:07 Oswald Buddenhagen - - * src/mbsync.1: - - clarify wording in MapInbox doc - -2013-12-15 11:46 Oswald Buddenhagen - - * src/drv_imap.c: - - avoid array underflow in IMAP LIST .lock workaround - - suggested by Mark Wielaard . - - fwiw, the workaround really is still necessary with panda imap ... - -2013-12-13 14:36 Oswald Buddenhagen - - * src/sync.c: - - MaxMessages: ignore entries with no master while calculating bulk fetch - -2013-12-11 15:29 Oswald Buddenhagen - - * src/sync.c: - - adjust comments to new reality - -2013-12-11 15:25 Oswald Buddenhagen - - * src/sync.c: - - ensure sequencing of message propagation and store closing - - by putting the message propagation last, d3f634702 uncovered a - long-standing problem: we might have closed the source store before all - messages were propagated from it. - -2013-12-11 15:13 Oswald Buddenhagen - - * src/sync.c: - - fix error paths wrt sync drivers, take 3 - - msgs_copied() was not checked at all, and msgs_flags_set() was doing it - wrong (sync_close() was not checked). - - instead of trying to fix/extend the msgs_flags_set() model (ref-counting - and cancelation checking in lower-level functions, and return values to - propagate the status), place the refs/derefs around higher-level scopes - and do the checking only there. this is effectively simpler, and does - away with some obscure macros. - -2013-12-11 13:30 Oswald Buddenhagen - - * src/drv_imap.c: - - don't use UID EXPUNGE unless trashing - - a simple CLOSE is way more efficient, so use it if no adverse effects - can come from it. - -2013-12-08 19:46 Oswald Buddenhagen - - * .gitignore, configure.ac, src/Makefile.am, src/common.h, - src/compat/isync.h, src/config.c, src/config.h, src/driver.c, - src/driver.h, src/drv_imap.c, src/drv_maildir.c, src/main.c, - src/mdconvert.c, src/socket.c, src/socket.h, src/sync.c, - src/sync.h, src/util.c: - - reshuffle sources a bit - - split header and move some code to more logical places. - -2013-12-08 15:37 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c: - - tag verbose output when channel links two verbose stores - - otherwise it's pure guesswork to assign the output to particular stores. - -2013-12-08 15:32 Oswald Buddenhagen - - * src/: drv_imap.c, socket.c: - - move verbose socket logging out of socket driver - - the way it's used, it's more of a high-level function. - -2013-12-08 14:49 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c: - - remove own_store() function from driver model - - the drivers which support it can abstract it inside open_store() just - fine. - -2013-12-08 14:11 Oswald Buddenhagen - - * src/drv_imap.c: - - make use of IMAP MOVE extension - - the Maildir driver is always exposing behavior equivalent to this - it's - more efficient. - -2013-12-08 09:48 Oswald Buddenhagen - - * src/drv_maildir.c: - - don't check for INBOX more than necessary - -2013-12-08 09:44 Oswald Buddenhagen - - * src/drv_maildir.c: - - fix listing of nested maildir mailboxes - -2013-12-08 08:49 Oswald Buddenhagen - - * src/: main.c, mbsync.1, mbsyncrc.sample: - - allow prefixes to Patterns - - this makes it possible to "rename" a "namespace" while syncing. - -2013-12-08 08:51 Oswald Buddenhagen - - * src/main.c: - - less spaghetti - -2013-12-07 16:24 Oswald Buddenhagen - - * src/main.c: - - factor out sync_listed_boxes() - -2013-12-07 15:41 Oswald Buddenhagen - - * src/: main.c, mbsync.1: - - refuse box list overrides if Channel has no Patterns - - as the named boxes are the same on both sides, they logically make - sense only when the channel is in that mode anyway, which is the case - when using patterns. - -2013-12-07 15:11 Oswald Buddenhagen - - * src/: isync.h, main.c, util.c: - - treat manually specified box list the same as one coming from Patterns - -2013-12-01 16:57 Oswald Buddenhagen - - * src/socket.c: - - make host resolution error messages more useful in non-ipv6 builds - -2013-12-01 16:45 Oswald Buddenhagen - - * src/drv_maildir.c: - - avoid useless delay after creating maildir box - - we would see the recent timestamp of the creation and conclude that - something is going on, so we'd wait. this is obviously nonsense. - as we know that a freshly created mailbox is empty, simply skip the - message scan alltogether. - -2013-11-02 20:42 Oswald Buddenhagen - - * src/: config.c, drv_maildir.c, isync.h, mbsync.1, - run-tests.pl, sync.c: - - reduce FSync option to a boolean - - there is no use for Thorough mode any more, so simplify the - configuration. - -2013-11-02 20:41 Oswald Buddenhagen - - * src/sync.c: - - don't fsync after logging every TUID - - as we now don't actually start propagating new messages until all TUIDs - have been generated, it's sufficient to sync just once. this makes it - a cheap operation, so we can do it at SYNC_NORMAL level already. - -2013-11-24 19:26 Oswald Buddenhagen - - * src/: config.c, isync.h, mbsync.1, run-tests.pl, sync.c: - - add ExpireUnread option - -2013-11-24 18:39 Oswald Buddenhagen - - * src/: config.c, mbsync.1: - - make it possible to specify CopyArrivalDate and MaxMessages globally - - sneaky change on the side: the wording of the man page is changed from - "outside any section" to "before any section" to get global options. - this is not entirely true ... the previously existing options behave as - before, while the two newcomers actually affect subsequent channels. - -2013-11-24 18:32 Oswald Buddenhagen - - * src/: config.c, isync.h, main.c, sync.c: - - replace global_* with a channel_conf_t instance - - this makes the (growing) list of getopt_helper()'s parameters - manageable. the few wasted bytes are worth it. - -2013-11-24 18:55 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, main.c: - - do not unnecessarily use bitfields - - they don't save much (if any) space in our usage, while they make the - machine code more bloated and slow. - -2013-11-24 17:26 Oswald Buddenhagen - - * src/sync.c: - - move handling of new messages after that of old ones - - i.e., move it back. whatever the original reason was, it's now gone. - - this order is way more natural, which allows us to remove the osrecadd - and S_DONE hacks. - -2013-11-04 08:54 Oswald Buddenhagen - - * src/run-tests.pl: - - verify idempotence of all sync operations - -2013-11-30 12:03 Oswald Buddenhagen - - * src/: run-tests.pl, sync.c: - - make MaxMessages work for new mails as well - - this helps enormously on the first sync of a 100k message box with a - limit of 1k messages. it also happens to make the syncing idempotent. - - in a few conditionals we now explicitly test for max_messages being - enabled, not smaxxuid != 0, as after the initial fetch with no important - messages smaxxuid is zero, but we still have to skip over 99k messages - in the above case. - -2013-11-23 14:55 Oswald Buddenhagen - - * src/sync.c: - - delay propagation of new messages - - previous sequence: - examine & propagate new => examine old => propagate old - new sequence: - examine new => examine old => propagate new => propagate old - - this alone does not buy us much ... - -2013-11-02 18:33 Oswald Buddenhagen - - * src/sync.c: - - make message propagation recording less magic - - assign the sync record to the source message asap, and later on rely - on a more explicit condition than not doing so. - -2013-11-02 19:47 Oswald Buddenhagen - - * src/sync.c: - - log maxuid bumping less aggressively - - we can bump the internal variable whereever convenient, but we cannot - log it until we know that all messages were copied, as otherwise we - could miss some new messages after an interruption. with the new - approach, interruption would merely cause some additonal traffic. - -2013-11-17 16:36 Oswald Buddenhagen - - * src/sync.c: - - document message expiration transactions - -2013-11-24 14:58 Oswald Buddenhagen - - * src/sync.c: - - propagate deletions with other flag changes - - less code duplication, more logical order of issued driver commands - (especially after the next commit), and the "side effect" of letting the - message expiration code see those deletions if they are asynchronous. - -2013-11-17 10:23 Oswald Buddenhagen - - * src/sync.c: - - don't delay loading master even if messages were expired - - the delay optimized the corner case of previously important but now - expired messages on the slave disappearing, either through an external - expunge or after a journal replay. no point in pessimizing the common - case. - -2013-11-17 08:06 Oswald Buddenhagen - - * src/: run-tests.pl, sync.c: - - remove cleanup of expired entries during setup of master load - - the removed code would only ever trigger if a) we were after a journal - replay or b) something external expunged the expired messages - both are - corner cases not worth the extra code. - however, this means that the syncing code further down now needs to take - care of these zombies. - in the end, the normal cleanup will take care of all expired entries, - new and old. - -2013-11-24 18:50 Oswald Buddenhagen - - * src/sync.c: - - micro-optimization/-clarification: swap condition order - -2013-11-23 11:01 Oswald Buddenhagen - - * src/sync.c: - - make message counting in expiration code less confusing - -2013-11-10 18:57 Oswald Buddenhagen - - * src/sync.c: - - count unread messages like flagged messages when expiring - - that is, don't count them towards the total only below the cut-off - point. making them extend the working set even though they are inside it - is counterintuitive. - -2013-11-09 10:25 Oswald Buddenhagen - - * src/sync.c: - - use post-sync "seen" flag to determine expirability - - otherwise it wouldn't be idempotent. - -2013-11-08 11:05 Oswald Buddenhagen - - * src/: compat/isync.1, sync.c: - - don't protect recent messages from MaxMessages - - while maildir has a clearly defined meaning of "recent" and for example - mutt handles it graciously, IMAP's definition is fubared to the point - that some servers (for example gmail) simply refuse to support it. - for symmetry reasons it is best to pretend that it doesn't exist at all. - it doesn't seem too useful anyway (the user can simply mark the messages - as read to allow pruning). - and last but not least, the man page of mbsync says nothing about - "recent", only "unread". unlike the isync man page, though. - -2013-11-23 11:22 Oswald Buddenhagen - - * src/sync.c: - - always get slave flags when we are expiring - - even if we are not propagating new messages, the appearance of new - messages on the slave can lead to expiring older messages. for that, we - need to know their importance, and thus flags. - - the alternative would be not doing an expiration run when not fetching - new messages, but that would mean more conditionals all over the place. - as the decision is somewhat arbitrary, just do the simpler thing. - -2013-11-16 16:59 Oswald Buddenhagen - - * src/sync.c: - - do not trash expired messages - - we are not actually deleting them, so there is no point in saving them - in the trash. - -2013-11-16 12:25 Oswald Buddenhagen - - * src/: run-tests.pl, sync.c: - - make sync state header format less obscure - - the header is not space-critical, so use proper name-value pairs. - this has the additional advantage that subsequent format changes can be - done much easier. - -2013-11-16 12:21 Oswald Buddenhagen - - * src/run-tests.pl: - - make state loading in showstate() similar to ckstate() - -2013-11-09 12:06 Oswald Buddenhagen - - * src/run-tests.pl: - - take configs out of target state defs - - cleaner and less duplication - -2013-11-16 12:41 Oswald Buddenhagen - - * src/run-tests.pl: - - more precise failure reporting - -2013-11-03 19:17 Oswald Buddenhagen - - * src/run-tests.pl: - - make it possible to run only selected tests - -2013-11-09 10:42 Oswald Buddenhagen - - * src/sync.c: - - set srec->msg[] when finding messages by tuid - - otherwise we would propagate phantom deletions. - - this affected only sync runs after an interruption while storing - messages, so it went (mostly?) unnoticed. - -2013-11-09 10:41 Oswald Buddenhagen - - * src/sync.c: - - remove pointless assignment - - we already know that tmsg->srec is null at this point. - -2013-11-02 22:32 Oswald Buddenhagen - - * src/sync.c: - - assert no stray TUIDs - -2013-11-30 14:07 Oswald Buddenhagen - - * src/drv_imap.c: - - initialize struct tm - - strptime() does not initialize at least tm_isdst, which leads to an - uninited value reference in mktime(). - -2013-11-09 13:35 Oswald Buddenhagen - - * src/: drv_imap.c, main.c: - - make use of strptime() portable - - it does not (officially) support the %z conversion, so re-implement that - part by hand. - -2013-11-09 12:53 Oswald Buddenhagen - - * src/drv_imap.c: - - fix compilation with older gcc versions - - the warning suppression pragma within function scope is apparently a new - thing. - as i don't want to disable the check for the entire function (even if - this currently would make no difference), just use a wrapper function - to suppress the format string check. - -2013-11-09 12:50 Oswald Buddenhagen - - * configure.ac: - - fix strftime() %z conversion specifier check - - only glibc does something sane with gmtime()+strftime(). on bsd (incl. - mac os), strftime() can be used only with localtime(). - -2013-11-06 07:40 Oswald Buddenhagen - - * .gitignore: - - ignore automake's "compile" script - -2013-11-06 07:37 Oswald Buddenhagen - - * autogen.sh: - - use autoreconf instead of calling separate tools - - this has been the correct way since a long time. - - Pointed-out-by: Felipe Contreras - -2013-11-02 19:06 Oswald Buddenhagen - - * src/: isync.h, main.c, run-tests.pl, sync.c: - - add/fix comments and improve debug messages - -2013-11-02 19:02 Oswald Buddenhagen - - * src/sync.c: - - simplify condition - - ... and document the cases. - -2013-11-02 18:39 Oswald Buddenhagen - - * src/sync.c: - - micro-optimization/-clarification - -2013-10-26 09:44 Oswald Buddenhagen - - * src/sync.c: - - move initializations for clarity - -2013-05-20 16:54 Oswald Buddenhagen - - * src/sync.c: - - MaxMessages: make condition exactly symmetrical to condition below - -2013-05-20 16:53 Oswald Buddenhagen - - * src/sync.c: - - rewrite condition for readability and consistency - -2013-11-02 14:04 Oswald Buddenhagen - - * src/sync.c: - - remove assumption about value of M constant - -2013-11-02 11:57 Oswald Buddenhagen - - * src/sync.c: - - fix enum abuse - - amends 9c86ec344. - - S_FIND was for the sync record status field. it has no business in the - sync vars status fields. its value coincided with ST_SELECTED, which - luckily only means that we always tried to match up TUIDs even if there - was nothing to do. - - the need for TUID matching arises in two mostly independent - circumstances, so add two separate flags ST_FIND_{OLD,NEW}. - -2013-11-03 19:20 Oswald Buddenhagen - - * src/run-tests.pl: - - create unseen messages in /new/ - - seen messages still go to /cur/. - this is consistent with the actual maildir driver. - -2013-11-03 11:59 Oswald Buddenhagen - - * src/run-tests.pl: - - be a bit more verbose - -2013-11-03 11:59 Oswald Buddenhagen - - * src/run-tests.pl: - - properly handle unexpected exit while replaying journal - -2013-11-03 11:49 Oswald Buddenhagen - - * src/run-tests.pl: - - ensure that the journal replay pass really does nothing - -2013-11-02 15:43 Oswald Buddenhagen - - * src/run-tests.pl: - - sort messages by serial number instead of UID in box dumper - - the input data is sorted that way, so it's easier to compare. - -2013-11-02 14:42 Oswald Buddenhagen - - * src/run-tests.pl: - - fix error message in sync state dumper - -2013-09-25 15:13 Oswald Buddenhagen - - * src/drv_imap.c: - - deal with messages disappearing between being listed and fetched - -2013-09-25 18:56 Oswald Buddenhagen - - * src/: config.c, mbsync.1: - - support backslash-escaping in the config file - - note that no attempt is made at making this work in the compat wrapper. - -2013-09-25 18:55 Oswald Buddenhagen - - * src/drv_imap.c: - - support backslashes and quotes in quoted IMAP strings - - the RFCs require it - well hidden in the BNF at the bottom. - - patch somewhat inspired by "guns" . - -2013-09-25 16:53 Oswald Buddenhagen - - * src/drv_imap.c: - - make next_arg() more readable & efficient - -2013-09-01 15:35 Oswald Buddenhagen - - * configure.ac, src/isync.h, src/socket.c: - - IPv6 support - - inspired by a patch by "Todd T. Fries" . - -2013-09-01 14:32 Oswald Buddenhagen - - * src/: isync.h, socket.c: - - support multi-homed servers - -2013-08-03 13:10 Oswald Buddenhagen - - * src/: config.c, drv_imap.c, isync.h, main.c, mbsync.1, - sync.c, util.c: - - support multi-character path separators - - this applies to both the IMAP PathDelimiter (which is needed by Lotus - Domino), as well as the Flatten-ed separators. - -2013-07-27 16:46 Oswald Buddenhagen - - * src/drv_imap.c: - - CHECK before FETCH after STORE - - m$ exchange does not seem to update the index in time otherwise. - -2013-07-28 13:55 Oswald Buddenhagen - - * configure.ac, src/config.c, src/drv_imap.c, - src/drv_maildir.c, src/isync.h, src/mbsync.1, src/sync.c: - - added sync support for the arrival date of messages - - initial patch by Marc Hoersken - -2013-07-27 18:17 Oswald Buddenhagen - - * src/sync.c: - - warn if we cannot find some messages by TUID - -2013-07-27 16:44 Oswald Buddenhagen - - * src/: drv_maildir.c, sync.c: - - make better use of ATTR_UNUSED - -2013-07-27 13:35 Oswald Buddenhagen - - * src/drv_imap.c: - - be somewhat stricter about the LIST response syntax - - the first token *must* be a list. - -2013-07-27 13:32 Oswald Buddenhagen - - * src/drv_imap.c: - - allow the mailbox names in LIST responses to be literals - - Lotus Domino seems to send them like that. - -2013-07-27 12:31 Oswald Buddenhagen - - * src/drv_imap.c: - - make parse_list() callback based - - this allows us to parse IMAP literals ({}) in every list. - -2013-07-27 08:37 Oswald Buddenhagen - - * src/: drv_imap.c, mbsync.1, mbsyncrc.sample: - - add PassCmd option to query IMAP password dynamically - - inspired by patches by - Aurélien Francillon , - Martin Stenberg and - sbfnk@users.sf.net. - -2013-05-09 16:51 Oswald Buddenhagen - - * src/sync.c: - - don't unnecessarily use continue - -2013-05-11 08:12 Oswald Buddenhagen - - * src/: config.c, sync.c: - - use INT_MAX instead of zero for "no size limit" - - this simplifies the actual conditions - -2013-04-20 14:57 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, mbsync.1, socket.c, sync.c: - - update copyrights - -2013-04-13 17:05 Oswald Buddenhagen - - * src/mbsync.1: - - man page fixups - -2013-04-13 17:05 Oswald Buddenhagen - - * src/: main.c, mbsync.1: - - don't let wildcards match INBOX, unless it lives under Path - - it's counter-intuitive to have '*' match the (always present) INBOX - when the rest of the mailboxes lives in a different namespace. - -2013-04-13 17:25 Oswald Buddenhagen - - * src/drv_maildir.c: - - always list INBOX when asked for it - - it's there even if it's not there. says IMAP. no need to contradict. - -2013-04-01 10:20 Oswald Buddenhagen - - * src/drv_maildir.c: - - split maildir_list_part() - - the boolean argument switched two entirely separate functions. - -2013-04-01 10:30 Oswald Buddenhagen - - * src/drv_maildir.c: - - remove some temporaries in maildir_list_part() - -2013-04-13 08:47 Oswald Buddenhagen - - * src/socket.c: - - fix CRAM-MD5 authentication - - the decoded challenge may be padded, so we really need to use strlen() - rather than just the decoded length. - -2013-04-13 08:50 Oswald Buddenhagen - - * src/socket.c: - - more consistency in char signedness - -2013-04-07 15:20 Felipe Contreras - - * src/drv_maildir.c: - - maildir: fix trash path double-free - - It should be freed at the very end. - - Signed-off-by: Felipe Contreras - -2013-04-07 14:53 Felipe Contreras - - * configure.ac: - - Fix build with recent autoconf and modernize configure.ac - - configure.ac:2: warning: macro 'AM_CONFIG_HEADERS' not found in library - configure.ac:7: error: 'AM_PROG_CC_STDC': this macro is obsolete. - You should simply use the 'AC_PROG_CC' macro instead. - Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', - but upon 'ac_cv_prog_cc_stdc'. - configure.ac:3: warning: AM_INIT_AUTOMAKE: two- and three-arguments - - Signed-off-by: Felipe Contreras - -2013-04-07 10:42 Felipe Contreras - - * configure.ac: - - Rename configure.in to the modern equivalent - - Fixes: - - aclocal: warning: autoconf input should be named 'configure.ac', not 'configure.in' - - Signed-off-by: Felipe Contreras - -2013-04-07 14:54 Oswald Buddenhagen - - * src/mbsync.1: - - discourage use of MapInbox - -2013-03-30 09:10 Oswald Buddenhagen - - * src/drv_imap.c: - - don't try to fetch status of minus one message - - this would happen if we were trying to find newly pushed messages, but - none actually arrived. - as imap's ranges are not ordered, this would actually fetch one message. - -2013-03-30 15:27 Oswald Buddenhagen - - * src/: run-tests.pl, sync.c: - - don't record newuid in the sync state - - this value is only ever used to find just pushed messages by TUID, so we - can simply use the UIDNEXT value from before we started pushing - and of - course, we need to record that in the journal. it makes no sense to log - the new value after completing a search, as there won't be a next search - before we push the next messages. - -2013-03-30 08:38 Oswald Buddenhagen - - * src/sync.c: - - rename sync_vars_t::uidnext => newuid & fix comment - - the purpose of this variable is to hold the UIDNEXT value from before - we started pushing new messages, i.e., the minimal uid we can expect - them to have. - -2013-03-30 13:14 Oswald Buddenhagen - - * src/: config.c, mbsync.1, util.c: - - make paths relative to CWD, after all - - the test suite actually relies on it. it would be possible to adjust it, - but there is not much reason to make paths relative to HOME (as we - support convenient tilde expansion). so use the least invasive approach, - which is simply the old behavior. adjust the documentation accordingly. - - This reverts commit da5ce5d8f42a15a2842d6d14043452f1a7892a0a. - -2013-03-29 17:22 Oswald Buddenhagen - - * src/socket.c: - - improve socket error reporting - - always use getsockopt() to query the meaning of POLLERR, rather than - reporting "Unidentified socket error". - this is unlikely to have any effect when using select(), as that one - pretty much never signals exceptional conditions. - -2013-03-29 16:51 Oswald Buddenhagen - - * src/socket.c: - - factor out socket_connect_failed() - -2013-03-29 17:11 Oswald Buddenhagen - - * src/socket.c: - - improve socket connect() error reporting with poll() - - turns out that poll() may (and on linux does) signal POLLERR on - connection failure. this is unlike select(), which is specified to - signal write readiness in every case. - consequently, check whether we are connecting before checking for - POLLERR. - -2013-03-29 15:00 Oswald Buddenhagen - - * src/: isync.h, main.c: - - introduce -DC option to only install a crash handler - -2013-03-24 13:46 Oswald Buddenhagen - - * configure.in: - - don't claim that we are looking for exactly bdb 4.2 - -2013-03-24 12:09 Oswald Buddenhagen - - * src/mbsync.1: - - match flag names in man page - - "Full" is an alias for "All", but let's stick to one. - -2013-03-24 10:10 Oswald Buddenhagen - - * src/: config.c, util.c: - - make path expansion match docu: paths are relative to ~ - - the current behavior of being relative to the current directory sort of - makes no sense, and contradicts the docu. - -2013-03-24 10:10 Oswald Buddenhagen - - * src/compat/: isync.1, main.c: - - disable SSLv2 by default in the wrapper as well - -2013-03-23 14:07 Oswald Buddenhagen - - * src/drv_maildir.c: - - downcast time_t to long for printing - - time_t may be long long. to keep the sprintf format strings simple, just - downcast - this is not going to be a problem for the next 30 years, and - until then long will be 64-bit everywhere anyway. - - suggested 3.5 years ago by Antoine Reilles . - -2013-03-23 08:59 Oswald Buddenhagen - - * src/drv_imap.c: - - fix cram-md5 authentication - - we need to send a newline after the response for imap to grok it. - -2013-03-23 09:34 Oswald Buddenhagen - - * src/drv_imap.c: - - fix crashes in imap_open_store() error paths - - it's not a good idea to invoke imap_open_store_bail() twice, either ... - -2013-03-17 13:32 Oswald Buddenhagen - - * src/socket.c: - - fix crash in ssl connection error path - - not a good idea to invoke the callback twice ... - -2013-03-17 11:41 Oswald Buddenhagen - - * src/: isync.h, mbsync.1, socket.c: - - rewrite SSL certificate verification. again. - - leave all the hard work to OpenSSL. this has several consequences: - - certificate chain validation actually works instead of throwing - around error 20 - - the interactive approval is gone. i don't expect it to be useful - anyway, as mbsync is mostly a batch tool - - the code is much shorter - -2013-02-21 07:02 Oswald Buddenhagen - - * README: - - language fix - -2013-02-21 07:01 Oswald Buddenhagen - - * README: - - make build instructions more explicit - -2013-02-03 16:34 Oswald Buddenhagen - - * src/socket.c: - - fix CVE-2013-0289: add SSL subject verification - - we did not check a valid certificate's subject at all so far. - this is no problem if the certificate file contains only exactly the - wanted host's certificate - before revision 04fdf7d1 (dec 2000, < v0.4), - this was even enforced (more or less - if the peer cert had been - signed directly by a root cert, it would be accepted as well). - however, when the file contains root certificates (like the system-wide - certificate file typically does), any host with a valid certificate - could pretend to be the wanted host. - -2013-02-03 16:47 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, mbsync.1, socket.c: - - add support for (disabling) TLS v1.1 and v1.2 - -2012-10-16 07:27 Oswald Buddenhagen - - * src/drv_imap.c: - - more error checking of IMAP responses - - REFMAIL: CA+Tk8fyu-6bwXq=ee2BgcKK_13m9S0RS+-0DhM=_jFqSKCH8aw@mail.gmail.com - -2012-09-22 15:48 Oswald Buddenhagen - - * src/: drv_imap.c, socket.c, util.c: - - flush stdout more - - to make sure it is timely written and not interleaved with stderr even - when when redirected. - -2012-09-22 15:35 Oswald Buddenhagen - - * src/sync.c: - - fix TrashRemoteNew copy direction - -2012-09-16 11:03 Oswald Buddenhagen - - * src/main.c: - - consider hierarchy delimiter flattening when deciding what to list - - flattened sub-folders of INBOX actually end up in Path, so list that - instead. - - REFMAIL: 6c0ecbff0d025387020281c5d2f5e6e8@smallsys.org - -2012-09-16 10:34 Oswald Buddenhagen - - * src/main.c: - - try harder to list all necessary boxes - - the pattern "INB*" may or may not refer to something in the INBOX. even - just "*" may. so list both the INBOX and the Path in case of - uncertainty. - -2012-09-15 13:15 Oswald Buddenhagen - - * src/: config.c, drv_maildir.c, isync.h, mbsync.1, - run-tests.pl, sync.c: - - add option to control amount of fsync()ing - -2012-09-15 12:38 Oswald Buddenhagen - - * src/sync.c: - - avoid that a system crash can cause messages to be propagated twice - - fdatasync() the journal after creating the pair record and recording - the TUID, but before the message propagation actually starts. - - all other writes to the journal are not flushed, as they will at worst - cause some unnecessary network traffic without visible effect. - -2012-09-15 12:15 Oswald Buddenhagen - - * src/drv_maildir.c: - - avoid that a system crash can lose mails - - this fixes two possible failure scenarios: - - if the journal is committed but the mails are not, the missing files - would be erroneously interpreted as deletions which would be - propagated - - less seriously, if the mail files' meta data was committed but the - file contents were not, we would end up with empty files, which would - have to be re-fetched "behind mbsync's back" (just deleting the files - would not work - see above) - -2012-09-15 11:25 Oswald Buddenhagen - - * src/sync.c: - - avoid that a system crash can clobber the sync state file - - make sure that the new state is committed to disk before overwriting the - old version - by default meta data is committed first, so we may end up - with no valid state at all otherwise. - -2012-09-15 09:57 Oswald Buddenhagen - - * src/compat/config.c: - - quote mailbox names written to config file - -2012-09-15 09:49 Oswald Buddenhagen - - * src/config.c: - - make more config file errors fatal - - we really shouldn't just synchronize despite config parsing errors. - -2012-09-15 09:46 Oswald Buddenhagen - - * src/: config.c, drv_imap.c, drv_maildir.c, isync.h: - - store config error status in conffile_t object - - this makes passing it around more straight-forward - -2012-09-15 09:24 Oswald Buddenhagen - - * src/: config.c, drv_imap.c, isync.h, util.c: - - make config parser a bit more careful about quotes - - the parsing is more shell-like now: - - quoted and unquoted parts can be mixed in one argument - - the hashmark can be meaningfully quoted - -2012-09-09 10:18 Oswald Buddenhagen - - * src/drv_maildir.c: - - call fdatasync() after updating .uidvalidity files - - they must be flushed before the file system meta data, as otherwise we - may end up with duplicate UIDs after a system crash. - -2012-09-02 15:35 Ben Kibbey - - * src/socket.c: - - Fix certificate verification. - - The connection state wasn't getting updated. - -2012-08-26 13:17 Oswald Buddenhagen - - * README, src/compat/isync.1, src/mbsync.1: - - pre-release doc updates - -2011-04-10 17:25 Oswald Buddenhagen - - * src/: compat/main.c, config.c, drv_imap.c, drv_maildir.c, - isync.h, main.c, sync.c, util.c: - - update copyrights - - make the wrapper's help string also mention copyrights pertaining only - to the actual syncer, as this is the only string many people will ever - see. - -2011-04-10 17:34 Oswald Buddenhagen - - * src/: compat/config.c, compat/convert.c, compat/isync.1, - compat/isync.h, compat/main.c, compat/util.c, config.c, - drv_imap.c, drv_maildir.c, isync.h, main.c, mbsync.1, - mdconvert.1, mdconvert.c, run-tests.pl, socket.c, sync.c, - util.c: - - replace FSF address with something more ... contemporary - -2012-08-26 14:29 Oswald Buddenhagen - - * src/: Makefile.am, compat/Makefile.am: - - install the config examples to docdir - -2012-08-26 14:16 Oswald Buddenhagen - - * Makefile.am: - - update debian packaging - -2012-08-26 13:02 Oswald Buddenhagen - - * Makefile.am, isync.spec.in: - - fix rpm packaging - -2012-08-26 11:36 Oswald Buddenhagen - - * src/: isync.h, sync.c, util.c: - - use a hash table for message => sync record lookup - - this removes the pathological O( * ) case at the cost of being a bit more cpu-intensive (but - O()) for old messages. - -2012-08-25 18:30 Oswald Buddenhagen - - * src/: drv_imap.c, mbsync.1: - - make use of UID EXPUNGE - -2012-08-18 11:58 Oswald Buddenhagen - - * src/: config.c, isync.h, main.c, mbsync.1, sync.c: - - introduce ability to flatten the hierarchy of Stores - -2012-08-11 16:34 Oswald Buddenhagen - - * configure.in, src/drv_imap.c, src/drv_maildir.c, src/isync.h, - src/main.c, src/mbsync.1, src/util.c: - - add support for hierarchical mailboxes - -2012-08-11 15:11 Oswald Buddenhagen - - * src/drv_maildir.c: - - calculate trash box path already in maildir_open_store() - - this gives us some cleaner code paths later on, as we can treat the - trash box like a regular mailbox. - -2012-08-11 15:05 Oswald Buddenhagen - - * src/drv_maildir.c: - - ensure that mailbox creation in maildir_store() is limited to trashing - - other mailboxes would have been maildir_select()ed already. - -2011-06-13 10:13 Oswald Buddenhagen - - * src/drv_imap.c: - - refactor: imap_select2_p2 => imap_refcounted_done_box - - soon, we'll use it for something different, too - -2012-08-25 13:34 Oswald Buddenhagen - - * src/sync.c: - - don't crash when select() on master fails synchronously - - svars->drv[S] would not be initialized yet, so cancel_sync() would - crash. - -2012-08-18 10:48 Oswald Buddenhagen - - * src/: isync.h, main.c, sync.c: - - fix error handling of invalid SyncState * - - when we find that the store is incompatible with in-store sync state, - we want to fail the whole channel. however, we must not claim that the - store died, otherwise it won't be disposed of properly. - -2011-06-02 17:21 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c: - - reject qualified mailboxes with the magic name INBOX - - otherwise we couldn't tell them apart from the real INBOX after - stripping away the Path. - -2011-07-25 07:25 Oswald Buddenhagen - - * src/: drv_maildir.c, mdconvert.c: - - suppress bdb complaints about unknown file format - - pass DB_TRUNCATE when creating databases. otherwise bdb will complain - about the empty file we pass it (we have to create it upfront to - implement our locking). - -2011-06-02 10:43 Oswald Buddenhagen - - * src/: drv_imap.c, mbsync.1: - - Revert "fix UIDNEXT handling" - - in fact, UIDNEXT (and UIDVALIDITY) null is *not* allowed (see RFC3501 - section 9). them popping up nonetheless was a dovecot bug (which would - also confuse dovecot itself). - having it in as a workaround was no good either, as quite some other - code in mbsync assumes that UIDs are not null. - - This reverts commit e1fa867 and most of 39006d7. - - -REFMAIL: 4CA62BA1.4020104@lemma.co.uk - -2012-08-25 13:29 Oswald Buddenhagen - - * src/: drv_maildir.c, isync.h, main.c, run-tests.pl: - - deal with concurrent maildir modifications during listing - - files may be renamed (due to new -> cur transition or flag changes), - which may lead to two effects if ignored: - - we see both the old and the new name, so we report a spurious - duplicate UID - - we see neither name, so we report a spurious deletion - - as countermeasure, record and compare directory modification times. upon - mismatch, we just start over - as usual. - -2011-05-03 07:42 Oswald Buddenhagen - - * src/drv_maildir.c: - - make maildir uidvalidity change fatal - - it's best to give the user a chance to fix it rather than completely - messing up the syncstate by re-enumerating the UIDs. - -2011-05-22 15:53 Oswald Buddenhagen - - * src/drv_maildir.c: - - cleanup maildir error paths - - don't try to unlock and close databases and files - this will happen a - moment later anyway, through cancelation or re-selection. - ironically, this plugs a memory leak, because an open main database is - used as a signal to close a temporary db in maildir_scan(). - -2011-05-22 15:23 Oswald Buddenhagen - - * src/drv_maildir.c: - - fix potential double free - - the store may be discarded before we reach maildir_select() again, which - will leave us with a dangling pointer. - -2011-05-22 15:22 Oswald Buddenhagen - - * src/drv_maildir.c: - - plug memory leak in maildir_store_msg() upon failure to acquire UID - -2011-04-10 11:06 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, run-tests.pl, - sync.c: - - employ alternative scheme to finding messages by TUID - - instead of SEARCHing every single message (which is slow and happens to - be unreliabe with M$ Exchange 2010), just FETCH the new messages from - the mailbox - the ones we just appended will be amongst them. - -2011-04-03 09:29 Oswald Buddenhagen - - * src/sync.c: - - clearer debug msg - -2011-04-11 08:46 Oswald Buddenhagen - - * src/: isync.h, mdconvert.c: - - use ATTR_PRINTFALIKE - -2012-09-01 15:21 Oswald Buddenhagen - - * src/: socket.c, sync.c, util.c: - - fix line wrapping before info messages - - unless an info message is explictly marked as a continuation, it must - terminate any pending line (typically the progress information) first. - - debug output is not affected, as it is mutually exclusive with info - output, and no debug lines are left unterminated outside clear scopes. - -2011-06-02 08:14 Oswald Buddenhagen - - * src/: isync.h, main.c, util.c: - - remove Ontty flag - - i can't figure out why i added it in the first place. it doesn't seem to - make any sense ... - -2011-04-11 08:45 Oswald Buddenhagen - - * src/: isync.h, sync.c, util.c: - - centralize flushing of unfinished debug lines - -2011-04-10 13:32 Oswald Buddenhagen - - * src/: compat/config.c, compat/convert.c, compat/isync.h, - compat/main.c, compat/util.c, config.c, drv_imap.c, - drv_maildir.c, isync.h, mdconvert.c, socket.c, sync.c, - util.c: - - unify error reporting - - - introduce sys_error() and use it instead of perror() and - error(strerror()) in all expected error conditions - - perror() is used only for "something's really wrong with the system" - kind of errors - - file names, etc. are quoted if they are not validated yet, so e.g. an - empty string becomes immediately obvious - - improve and unify language - - add missing newlines - -2011-03-27 18:39 Oswald Buddenhagen - - * src/drv_maildir.c: - - don't complain about disappearing temp files - - some other process might be cleaning up concurrently ... - -2011-03-27 15:50 Oswald Buddenhagen - - * src/isync.h: - - enlarge receive buffer considerably - - the tiny buffer makes no sense in the face of huge payloads and now - additionally masses of replies from pipelined commands. - -2011-03-13 14:03 Oswald Buddenhagen - - * configure.in, src/drv_imap.c, src/mdconvert.c: - - compile with -ansi -pedantic on gcc - - greatly helps portability ... - -2012-09-01 19:14 Oswald Buddenhagen - - * configure.in, src/compat/isync.h, src/compat/main.c, - src/isync.h: - - define _GNU_SOURCE on the command line - - that way it is already set in configure and can thus be used by tests. - -2011-03-20 17:23 Oswald Buddenhagen - - * src/drv_imap.c: - - centralize imap_cmd_refcounted_state refcount decrementing - - no else branches remain, so the if() can be put into - imap_refcounted_done() - -2011-03-12 15:16 Oswald Buddenhagen - - * src/drv_imap.c: - - get rid of redundant literal_pending state flag - -2012-08-25 16:26 Oswald Buddenhagen - - * configure.in, src/drv_imap.c, src/isync.h, src/mbsync.1, - src/socket.c: - - fully asynchronous IMAP operation - - - asynchronous sockets using an event loop - - connect & starttls have completion callback parameters - - callbacks for notification about filled input buffer and emptied - output buffer - - unsent imap command queue - - used when - - socket output buffer is non-empty - - number of commands in flight exceeds limit - - last sent command requires round-trip - - command has a dependency on completion of previous command - - trashnc is tri-state so only a single "scout" trash APPEND/COPY is - sent at first. a possibly resulting CREATE is injected in front of - the remaining trash commands, so they can succeed (or be cancel()d - if it fails). - - queue's presence necessitates imap_cancel implementation - -2011-03-13 13:29 Oswald Buddenhagen - - * configure.in, src/isync.h, src/main.c, src/util.c: - - add simple mainloop implementation - - not used so far - -2011-03-19 18:40 Oswald Buddenhagen - - * src/socket.c: - - move responsibility for closing sockets on error to user - - the only user being imap and the first thing in imap_cancel_store() - being a call to socket_close(), this code was pretty pointless anyway. - -2011-03-27 14:50 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, socket.c: - - make socket read/write error reporting callback-based - - the functions still have synchronous return codes as well - this enables - early error returns without having to resort to refcounting. - -2011-04-03 16:47 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, socket.c: - - decouple the filling of the read buffer from consuming it - - this prepares the code for being called from a callback. - - notably, this makes the imap list parser have a "soft stack", so the - recursion can be suspended at any time. - -2011-03-27 10:34 Oswald Buddenhagen - - * src/drv_imap.c: - - centralize imap_cmd disposal - -2011-03-13 13:12 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, socket.c: - - make socket_write() capable of taking ownership of the buffer - - that way the user code doesn't have to free it any more. - -2011-03-13 12:40 Oswald Buddenhagen - - * src/: drv_imap.c, socket.c: - - change socket_write() return code semantics - - instead of returning a write()-like result, return only a binary status - code - write errors are handled internally anyway, so user code doesn't - have to check the write length. - -2011-03-27 14:58 Oswald Buddenhagen - - * src/: drv_imap.c, mbsync.1: - - make IMAP pipeline depth configurable - - currently, this affects only "clustered" message listings and - flag stores. - -2011-03-19 21:12 Oswald Buddenhagen - - * src/drv_imap.c: - - cancel submitted commands when canceling store - - we already have some minimal asynchronicity, so there might be commands - in flight when a fatal error comes in. - -2011-01-23 13:06 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, socket.c: - - Socket_t + buffer_t => conn_t - - remove the layering, in favor of a "buffered connection" abstraction. - -2011-04-10 11:28 Oswald Buddenhagen - - * src/socket.c: - - security fix: failure to load the certificate file is *not* OK ... - -2011-01-23 12:43 Oswald Buddenhagen - - * src/: Makefile.am, drv_imap.c, isync.h, socket.c: - - move socket code to a separate file - - this makes the layering more obvious - -2011-03-13 11:06 Oswald Buddenhagen - - * src/drv_imap.c: - - move greeting response handling into get_cmd_result() - - the primary purpose of this is getting rid of the "free-standing" - buffer_gets() call. - -2011-04-03 16:21 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, sync.c: - - docs - - - insert "separator comments" between driver entry points - - document driver API - - document sync_vars_t parts that are stored in the sync state header - -2011-04-03 16:15 Oswald Buddenhagen - - * src/drv_imap.c: - - make imap_exec() result reporting callback-based - - this makes the IMAP command submission interface asynchronous. - - the functions still have synchronous return codes as well - this enables - clean error return paths. only when we invoke callbacks we resort to - refcounting. - - as a "side effect", properly sequence commands after CREATE resulting - from [TRYCREATE]. - -2011-07-24 18:27 Oswald Buddenhagen - - * src/sync.c: - - rely on the maildir's existence with "SyncState *" - - now that we open the box first, we know that it will exist at this - point. - -2011-07-24 18:26 Oswald Buddenhagen - - * src/drv_maildir.c: - - validate maildirs more strictly - - now that "SyncState *" won't create fake mailboxes any more, we can make - a full validity check again. - -2011-07-23 14:06 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, sync.c: - - split out drv->load() from drv->select() - -2011-07-23 14:13 Oswald Buddenhagen - - * src/drv_maildir.c: - - make creation of trash folder independent from -C option - - the trash is not a box which is synced, but a "byproduct" of - manipulating synced boxes, so it makes no sense to bind it to the same - option. - -2012-07-29 23:07 Oswald Buddenhagen - - * src/drv_imap.c: - - minor cleanup: use ctx->gen instead of gctx for consistency - -2012-07-29 21:15 Oswald Buddenhagen - - * src/sync.c: - - make callbacks return early when canceling - - even after driver->cancel() the store may complete commands successfully. - return early in this case, so we don't attempt to continue syncing. - -2012-07-29 21:14 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, sync.c: - - fix error paths wrt sync drivers, take 2 - - synchronous error codes which are passed through callbacks aren't a - particularly good idea, after all: latest when the callback does stuff - which does not concern the caller, the return code becomes ambiguous. - instead, protect the sync_vars object with a refcount when invoking - driver functions from loops, as the callbacks they call could invalidate - the object and we would have no way of knowing that the loop should be - aborted prematurely. the upcoming async imap driver will also need a - refcount to protect the cancelation marker of the imap socket dispatcher - loop. - -2011-04-03 14:29 Oswald Buddenhagen - - * src/sync.c: - - don't call cancel() repeatedly on a store - - erroring command replies will trickle in even after canceling - -2012-07-15 10:55 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c, sync.c: - - replace DRV_STORE_BAD with a separate bad_callback() - - that way we don't have to piggy-back (possibly asynchronous) fatal - errors to particular commands. - - internally, the drivers still use synchronous return values as well, - so they don't try to access the invalidated store after calling back. - -2012-07-22 15:46 Oswald Buddenhagen - - * src/sync.c: - - don't access free'd memory in cancel_sync() - - as it happens, the 1st round *may* trash svars - if we get the - cancelation request after the slave store has already died. - -2012-07-22 15:32 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, sync.c: - - make drv->cancel()'s callback have no status code - - this function is not going to actually execute any commands, so it - makes no sense for the callback to have a status code. - -2012-06-17 12:52 Oswald Buddenhagen - - * src/sync.c: - - don't decode aux pointer on DRV_CANCELED - - the aux data was already free()d by the error callback by the time we - get this status code. - -2011-03-20 12:45 Oswald Buddenhagen - - * src/drv_imap.c: - - always use return value from get_cmd_result() - - once we have callback-based error reporting, this will ensure that we - don't operate on invalidated data structures. - -2010-12-05 15:49 Oswald Buddenhagen - - * src/drv_imap.c: - - make response code parse failure of untagged OK/NO/BYE/BAD non-fatal - - as such, it does not disrupt the data stream - -2012-07-15 10:50 Oswald Buddenhagen - - * src/main.c: - - de-duplicate code a bit - -2010-12-15 18:01 Oswald Buddenhagen - - * src/drv_imap.c: - - remove redundant use_ssl variables - - just use the presence of an SSL object as an indicator. if something - goes wrong during the ssl handshake or certificate validation, the - socket must be immediately closed anyway. - -2010-11-20 22:48 Oswald Buddenhagen - - * src/isync.h: - - DRV_SERVER_BAD is and will probably stay unused => trash - -2010-11-20 09:17 Oswald Buddenhagen - - * src/drv_imap.c: - - after [TRYCREATE], just resend the same command instead of cloning it - -2011-03-20 15:27 Oswald Buddenhagen - - * src/drv_imap.c: - - use return values from correct set in get_cmd_result() - - DRV_OK == RESP_OK, so this worked by accident - -2010-11-15 09:38 Oswald Buddenhagen - - * src/drv_imap.c: - - do away with the dreaded rcaps hack - - don't pretend that the server has no literal+ for the time of the - first relevant command's synchronous execution. instead, enable the - lower layer to do the processing by telling it for which commands - trashnc ("trash's existence not confirmed") is relevant. - -2010-11-15 09:30 Oswald Buddenhagen - - * src/drv_imap.c: - - purge imap_store_t::currentnc vestiges - - we always actually open the mailbox before appending to it, so we - obviously know that it exists - that's why the code was already - commented out. changing this assumption would significantly complicate - matters for little gain, so let's just assume it won't happen. - - consequently, also don't set param.create when appending to regular - mailboxes. - -2011-06-13 10:02 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, main.c: - - move setting of ctx->listed outside the drivers - - it's essentially an external state flag - -2011-04-10 07:58 Oswald Buddenhagen - - * src/sync.c: - - de-duplicate error paths - - makes the code more compact. yay for gotos. - -2011-07-23 10:49 Oswald Buddenhagen - - * src/drv_maildir.c: - - check return value from close() after write() - - otherwise we may lose data when quota is exceeded - or nfs is in a bad mood. - -2012-07-07 15:19 Oswald Buddenhagen - - * src/: compat/convert.c, drv_imap.c, drv_maildir.c, sync.c: - - fix a bunch of warnings - -2011-03-27 10:06 Oswald Buddenhagen - - * src/: compat/main.c, drv_imap.c, main.c: - - avoid preprocessor warnings on missing features: #if => #ifdef - -2011-03-12 15:20 Oswald Buddenhagen - - * src/drv_imap.c: - - less bizarre code - - we know that there is only one command in progress, so there - is no need to employ tricks to access the last command. - -2011-01-23 12:35 Oswald Buddenhagen - - * src/drv_imap.c: - - make cram() sane - - - don't silently fail in release mode (expression with side effects - inside assert()) - - save some redundand strlen()s by not throwing away known lengths - - reorganize the code for legibility - -2010-11-20 22:04 Oswald Buddenhagen - - * src/sync.c: - - don't compare find_old_done with find_new_total - - this didn't have any effect as no async drivers currently exist. - -2010-12-19 22:33 Oswald Buddenhagen - - * src/main.c: - - don't hang if store cannot be opened asynchronously - -2011-03-06 22:04 Oswald Buddenhagen - - * src/drv_imap.c: - - don't leak SSL objects - -2011-03-27 09:01 Oswald Buddenhagen - - * src/sync.c: - - add CR after TUID during LF => CRLF conversion - -2011-03-27 08:52 Oswald Buddenhagen - - * src/sync.c: - - fix (another) out-of-bounds access in CRLF conversion - - if the header contained no CRs but the body (or the post-TUID part of - the header) did, the TUID insertion would add an excess CR, thus - overflowing the buffer by one byte. - -2010-11-14 16:23 Oswald Buddenhagen - - * src/mbsync.1: - - document some breakage - -2010-11-14 15:44 Oswald Buddenhagen - - * src/: compat/convert.c, drv_imap.c, drv_maildir.c: - - turns out, free(NULL) is just fine ... - -2010-10-03 12:31 Oswald Buddenhagen - - * src/drv_imap.c: - - fix UIDNEXT handling - - UIDNEXT *can* be legally zero, so deal with it. - - -REFMAIL: 4CA62BA1.4020104@lemma.co.uk - -2010-10-03 09:53 Oswald Buddenhagen - - * src/drv_imap.c: - - don't hang after failed start_tls() - - we'd send a LOGOUT command in plain text while the server was already - expecting an encrypted command, which would typically lead to waiting - for more data and thus an indefinite hang. - so close the socket immediately instead of letting the normal shutdown - path take care of it. - inspired by a patch by Steven Flintham. - - -REFMAIL: 4C9AB98E.3000400@lemma.co.uk - -2010-09-26 13:26 Oswald Buddenhagen - - * src/drv_imap.c: - - remove useless message - - don't complain about missing greeting response - we already complained - about an unexpected EOF anyway. - -2010-04-05 11:15 Oswald Buddenhagen - - * src/drv_imap.c: - - assert valid file handles - - i've seen error logs of the type - SSL_write: Bad file descriptor - and i simply can't nail it, so go for some more drastic measures. - -2010-04-05 11:08 Oswald Buddenhagen - - * src/drv_imap.c: - - formatting - -2010-04-05 11:08 Oswald Buddenhagen - - * src/drv_imap.c: - - beautify error messages - - don't print the error number - we print the error string anyway, so it - adds no value. - add some whitespace to the messages as well. - -2010-04-05 11:06 Oswald Buddenhagen - - * src/drv_imap.c: - - fix uninitialized variable read - - this is basically a security fix for nonsensical configurations: - if the specified CertificateFile did not contain any certificates, - we *might* have accepted an arbitrary server certificate. - -2010-02-28 21:23 Oswald Buddenhagen - - * src/: compat/isync.1, mbsync.1: - - remove mail addresses from man pages - - apparently, some people don't see the "maintained by" bits, so make them - look harder for explicit contact information (to be found in AUTHORS). - -2010-02-07 20:20 Oswald Buddenhagen - - * src/drv_imap.c: - - fix compile with SSL on Mac OS X - - patch by Remko Tronçon - BUG: 2126899 - -2010-02-07 16:36 Oswald Buddenhagen - - * src/compat/: isync.1, main.c: - - add -P option to isync wrapper - - not really a backwards compat option, but whatever ... - - based on a patch submitted long ago by "nobody". - BUG: 1433532 - -2010-02-07 21:13 Oswald Buddenhagen - - * isync.spec.in: - - fix rpm spec file - - -REFMAIL: 20090122213325.GA11572@crow.ths.tcoek12.org - -2010-02-07 21:12 Oswald Buddenhagen - - * Makefile.am: - - (new?) automake already sets docdir correctly for us - -2010-02-07 11:24 Oswald Buddenhagen - - * .gitignore, Makefile.am, src/.gitignore, - src/compat/.gitignore: - - cvsignore => gitignore - -2010-02-07 11:23 Oswald Buddenhagen - - * Makefile.am, autogen.sh: - - adjust ChangeLog generation to git - - now that log generation is cheap, don't store it in the SCM any more. - -2010-02-06 18:38 Oswald Buddenhagen - - * Makefile.am: - - fix "make distcheck" - - this makes the deb-clean target shadow build safe - -2010-02-06 09:40 Oswald Buddenhagen - - * src/: compat/main.c, drv_imap.c, isync.h, main.c: - - add extra verbose mode which dumps the message contents - - i needed that to debug the line ending issues. maybe it will find other - uses as well ... - -2010-02-06 09:34 Oswald Buddenhagen - - * src/: drv_maildir.c, isync.h, sync.c: - - fix line ending conversion logic - - imap may very well store messages with LF line endings. only RFC2822 - requires CRLF. - consequently, preserve the line endings as much as possible unless the - mailbox format does not support it (this would be the case for unix mbox - - i actually have no idea about maildir). - -2010-02-06 09:32 Oswald Buddenhagen - - * src/sync.c: - - some more error reporting relating malformed messages - -2008-08-31 20:14 Oswald Buddenhagen - - * src/drv_imap.c: - - refactoring. main part is killing struct imap_cmd_cb as such. - issue_imap_cmd is split into new_imap_cmd and submit_imap_cmd, so the - command can be parametrized after it was instanciated. - -2008-08-23 07:54 Oswald Buddenhagen - - * src/: drv_imap.c, sync.c: - - deal with UIDVALIDITY of 0 properly. - -REF: 20080822094543.GA3528@ugly.local - -2008-04-13 09:56 Oswald Buddenhagen - - * src/drv_imap.c: - - give the implicitly created imap account config the name of the store. - -2008-04-13 09:51 Oswald Buddenhagen - - * src/drv_imap.c: - - make ssl certificate handling much more useful: - - system-wide ca certs are auto-loaded - - private certs are accepted even if they are self-signed - -2008-04-12 08:58 Oswald Buddenhagen - - * src/drv_imap.c: - - - accept unset CertificateFile - - print the certificate's fingerprint - - make the certificate acceptance prompt much less scary - -2008-04-12 08:13 Oswald Buddenhagen - - * src/drv_imap.c: - - ignore system flag extensions (\X-...) - -2008-03-16 09:09 Oswald Buddenhagen - - * README: - - minor updates - -2008-02-23 14:18 Oswald Buddenhagen - - * src/compat/config.c: - - compat wrapper: don't crash if neither host nor tunnel are specified. - fixes: - CCMAIL: 449006@bugs.debian.org - -2008-02-23 09:37 Oswald Buddenhagen - - * src/compat/config.c: - - quote user name in generated config. - fixes: - CCMAIL: 456775@bugs.debian.org - -2008-02-23 09:18 Oswald Buddenhagen - - * src/main.c: - - don't overlook 2nd and later single-letter options in last argument. - reported by fedora - -REF: <1197916586.13945.120.camel@localhost.localdomain> - -2008-02-23 09:01 Oswald Buddenhagen - - * src/: compat/convert.c, drv_maildir.c, mdconvert.c: - - put pointers to bdb open() into parentheses, so they won't be - macro-expanded as libc open. - patch by fedora - -REF: <1197916586.13945.120.camel@localhost.localdomain> - -2008-02-23 08:53 Oswald Buddenhagen - - * AUTHORS: - - reshuffle for "contact priority's" sake - -2007-09-22 08:45 Oswald Buddenhagen - - * src/drv_imap.c: - - don't use #ifdef inside htons() arguments - it can be a macro. - -REF: - CCMAIL: Scott Gifford - -2007-04-04 17:03 Oswald Buddenhagen - - * Makefile.am: - - forward port (finally ...): add target for creating signed package - -2007-04-04 16:19 Oswald Buddenhagen - - * src/main.c: - - #ifdef __linux__ for the crash handler. it compiles on other platforms, - but the functionality is bound to linux' /proc structure. - -2007-02-10 15:37 Oswald Buddenhagen - - * src/drv_imap.c: - - fix crash due to uninited var when parsing IMAPServer. Thanks to - CCMAIL: Antoine Reilles - REF: <20070118182534.GA22288@arcelot.loria.fr> - -2006-12-09 10:39 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, sync.c: - - fix error paths wrt sync drivers - -2006-12-09 10:38 Oswald Buddenhagen - - * src/run-tests.pl: - - handle abnormal program exit during regtest - -2006-12-04 17:47 Oswald Buddenhagen - - * src/main.c: - - initialize mvars->t[1] to 1. helps enormously ... :} - -2006-11-18 13:17 Oswald Buddenhagen - - * src/drv_maildir.c: - - reverse-map to INBOX when encountered during listing. - usually this will be a no-op (when putting INBOX in Path, people - generally call it INBOX), but better safe than sorry. - -2006-11-09 17:57 Oswald Buddenhagen - - * src/compat/main.c: - - make compat wrapper default to current user for imap login - -2006-11-01 06:19 Oswald Buddenhagen - - * src/compat/config.c: - - put INBOX in Maildir - -2006-10-24 17:37 Oswald Buddenhagen - - * src/drv_maildir.c: - - don't crash on truncating database. seems to affect only some bdb - versions (e.g., 4.2). - -2006-08-10 07:01 Oswald Buddenhagen - - * src/sync.c: - - fix bug in newline conversion causing buffer overflows. - this leads to segfaults and has some security impact. - -2006-08-10 06:33 Oswald Buddenhagen - - * src/drv_imap.c: - - memmove for overlapping mem copies. - -2006-07-31 05:30 Oswald Buddenhagen - - * src/drv_maildir.c: - - glibc seems to be *really* fucked up. - -2006-07-29 11:52 Oswald Buddenhagen - - * src/: drv_maildir.c, mdconvert.c: - - work around glibc bug: printf("%.*s", INT_MAX, s) tries to allocate 2G. - -2006-06-05 11:59 Oswald Buddenhagen - - * src/compat/config.c: - - enable the old account naming scheme to deal with duplicated ip - addresses. - this is not incompatible - previously, it would just create garbage. - -2006-06-05 11:55 Oswald Buddenhagen - - * src/compat/: config.c, isync.h: - - create more descriptive account names, so password prompts look sane. - the channel names follow the old scheme, though - they are used to - compose sync state file names, and i don't feel like writing a migrator - for this. - -2006-05-28 16:03 Oswald Buddenhagen - - * src/drv_imap.c: - - don't crash in imap driver when Host is not specified. - -2006-05-28 16:02 Oswald Buddenhagen - - * src/mbsync.1: - - be *slightly* more explicit about which options Tunnel makes - superfluous. - -2006-05-28 15:43 Oswald Buddenhagen - - * src/: drv_imap.c, mbsync.1: - - un-document "Host imaps:[...]" syntax and introduce new option UseIMAPS - instead. - apply ted's patch to support UseIMAPS in conjunction with Tunnel. - document that SSLv2 is No Good (TM). - -2006-05-28 13:38 Oswald Buddenhagen - - * src/drv_imap.c: - - move assigning default port to the place of use - -2006-05-27 12:44 Oswald Buddenhagen - - * src/drv_maildir.c: - - add comment - -2006-05-27 12:43 Oswald Buddenhagen - - * src/sync.c: - - seen messages are eligible for expiration even if they are recent in the - mailbox. - -2006-03-21 20:05 Oswald Buddenhagen - - * src/main.c: - - no/empty mailbox name means INBOX - -2006-03-21 20:03 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c, sync.c, - util.c: - - make the driver model, sync_chans() and sync_boxes() fully async. - async drivers to follow ... - -2006-03-21 17:50 Oswald Buddenhagen - - * src/sync.c: - - unscrew lf=>crlf conversion and tuid insertion - -2006-03-21 17:40 Oswald Buddenhagen - - * src/sync.c: - - ok, mismerging and not running the reg-tests is lame. unscrew expunging - again. - -2006-03-21 16:03 Oswald Buddenhagen - - * src/sync.c: - - don't enter trash loop if not trashing at all. also, move expunge - message where it belongs. not adding info("trashing"), as it will be - replaced in a moment anyway. - -2006-03-21 15:53 Oswald Buddenhagen - - * src/: main.c, sync.c: - - async merge: aggregate most variables of main() & sync_boxes() in - main_vars_t resp. sync_vars_t. - also some minor var renames, whitespace, comments. - -2006-03-21 10:38 Oswald Buddenhagen - - * src/main.c: - - split box list preparation from "consumption". - -2006-03-21 10:30 Oswald Buddenhagen - - * src/: isync.h, main.c, sync.c: - - info() about opening of stores - -2006-03-20 20:39 Oswald Buddenhagen - - * src/drv_imap.c: - - do not repeatedly get namespace from server. - -2006-03-20 20:34 Oswald Buddenhagen - - * src/drv_imap.c: - - handle socket() failure and correctly report gethostbyname() failure. - -2006-03-20 20:16 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c, sync.c, - util.c: - - update copyrights - -2006-03-20 19:38 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c: - - move whole responsibility for recycling open stores/server connections - to the drivers. - -2006-03-20 19:27 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, main.c: - - keep the result of driver->list() and a flag whether it is valid in the store. - -2006-03-20 18:36 Oswald Buddenhagen - - * src/: config.c, isync.h: - - aggregate all (two ...) drivers in an array instead of naming them in - each (one ...) location explicitly. - -2006-03-20 17:21 Oswald Buddenhagen - - * src/drv_imap.c: - - whitespace and code verbosity - -2006-03-20 15:01 Oswald Buddenhagen - - * src/drv_imap.c: - - merge imap_t into imap_store_t - there is really no point in having them - separated. - -2006-03-19 11:29 Oswald Buddenhagen - - * src/: config.c, drv_imap.c, drv_maildir.c, isync.h, main.c, - sync.c, util.c: - - "fprintf( stderr," => "error(". new functions debugn() and infon() - for messages with missing newline; warn() and error() act upon this. - -2006-03-19 10:44 Oswald Buddenhagen - - * src/drv_imap.c: - - make config parsing more robust against bogus input and report errors - more clearly. - -2006-02-12 11:42 Oswald Buddenhagen - - * src/sync.c: - - factor out box selection from sync_boxes to avoid code dupe - -2006-02-11 20:28 Oswald Buddenhagen - - * src/sync.c: - - lock the sync state open the journal before opening the master. this is - a bit ugly for the "SyncState *" case, as we have to create a directory - without making it a maildir right away. however, this makes the code - quite a bit simpler to understand and simpler to parallelize. - -2006-02-11 20:14 Oswald Buddenhagen - - * src/drv_maildir.c: - - don't barf at directories with none of {tmp,new,cur}/ and turn them - into maildirs instead. see next commit. - -2006-02-11 20:02 Oswald Buddenhagen - - * src/sync.c: - - don't commit state file when a fatal error occurs - -2006-02-11 19:52 Oswald Buddenhagen - - * src/sync.c: - - unbelieveable, but close() can actually fail - -2006-02-11 19:48 Oswald Buddenhagen - - * src/run-tests.pl: - - add copyright + license - -2006-02-09 17:44 Oswald Buddenhagen - - * acinclude.m4, get-cert, src/compat/config.c, - src/compat/convert.c, src/compat/isync.1, src/compat/isync.h, - src/compat/main.c, src/compat/util.c, src/config.c, - src/drv_imap.c, src/drv_maildir.c, src/isync.h, src/main.c, - src/mbsync.1, src/mdconvert.1, src/mdconvert.c, src/sync.c, - src/util.c: - - update fsf's postal address. i think it's sort of useless nowadays - anyway, but heck ... - -2006-02-05 17:42 Oswald Buddenhagen - - * src/mbsync.1: - - typos - -2006-02-05 17:39 Oswald Buddenhagen - - * configure.in: - - bump version. no, i'm not releasing yet ... :) - -2006-02-05 17:38 Oswald Buddenhagen - - * src/Makefile.am: - - include run-tests.pl in distribution - -2006-02-03 23:43 Oswald Buddenhagen - - * src/sync.c: - - and now don't clobber the mails ... - -2006-02-03 21:33 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, sync.c, util.c: - - wrap message storing into transactions. nice side effect: drivers don't - need to deal with line end conversion any move. - -2006-02-02 17:03 Oswald Buddenhagen - - * src/: isync.h, sync.c: - - major overhaul of flag change propagation and MaxMessages handling: - - wrap message (un)expirations into transactions - - no redundand flag propagations in conjunction with expirations - - better prepared for the upcoming async operation - -2006-02-02 13:48 Oswald Buddenhagen - - * src/main.c: - - crash handler that launches gdb. activated when started with -D option. - simplifies debugging crashes during the reg-tests. - -2006-02-02 11:23 Oswald Buddenhagen - - * src/sync.c: - - less cluttered debug output - -2006-02-02 11:12 Oswald Buddenhagen - - * src/sync.c: - - cosmetics: move around variable declarations and remove obsolete comment - -2006-02-02 11:07 Oswald Buddenhagen - - * src/sync.c: - - versioned journal. the commands and their meanings change all the time, - so better handle that case. - ps: yes, i think not upgrading mbsync between interrupting and resuming - a run is a reasonable requirement. - -2006-02-02 10:44 Oswald Buddenhagen - - * src/sync.c: - - make the sync entry search in the journal replay wrap around at the end - of the list. the "always forward" assumption is violated in some cases. - -2006-02-02 10:25 Oswald Buddenhagen - - * src/run-tests.pl: - - much improved journal replay testing. - some clenup. - -2006-02-02 10:04 Oswald Buddenhagen - - * src/: run-tests.pl, sync.c: - - orphan/kill all affected entries after expunge - -2006-01-31 13:57 Oswald Buddenhagen - - * Makefile.am: - - deal with branches in "make log" - -2006-01-30 13:49 Oswald Buddenhagen - - * src/: isync.h, sync.c: - - M_EXPIRED -> M_EXPIRE - -2006-01-30 13:11 Oswald Buddenhagen - - * src/sync.c: - - sanitize S_DEL - -2006-01-30 13:01 Oswald Buddenhagen - - * src/sync.c: - - remove superfluous temporary rflags from sync_boxes - -2006-01-30 11:12 Oswald Buddenhagen - - * src/: isync.h, sync.c: - - now that messages know their sync records, M_SYNCES is superfluous. - -2006-01-30 10:26 Oswald Buddenhagen - - * src/: isync.h, sync.c: - - establish bi-directional mapping between mails and sync records. use it - to merge the --renew case into the --new case. - -2006-01-30 09:33 Oswald Buddenhagen - - * src/sync.c: - - declaring ex[M] instead of ex[2] is, indeed, no good. long live watchpoints. - -2006-01-29 18:40 Oswald Buddenhagen - - * src/compat/main.c: - - whoops - 'isync -w' would write .mbsyncrc to a wrong directory - -2006-01-29 15:52 Oswald Buddenhagen - - * src/sync.c: - - move fetching new messages in front of syncing old entries. this alone - does not buy us a whole lot ... - -2006-01-29 15:48 Oswald Buddenhagen - - * src/run-tests.pl: - - test for journalling and journal replay. - -2006-01-29 15:46 Oswald Buddenhagen - - * src/: isync.h, main.c, sync.c: - - undocumented flag -J to skip committing the new sync state. - -2006-01-29 14:46 Oswald Buddenhagen - - * src/: drv_imap.c, isync.h, main.c, sync.c, util.c: - - merge Quiet, Verbose & Debug into DFlags - -2006-01-29 11:49 Oswald Buddenhagen - - * src/: isync.h, sync.c: - - M_NOT_SYNCED => M_SYNCED. now that sync records know their messages, it - is simpler to track the positive case. - -2006-01-29 11:35 Oswald Buddenhagen - - * src/sync.c: - - move driver options composition below journal replay - it might make - additional actions necessary (it doesn't, yet). - -2006-01-29 11:22 Oswald Buddenhagen - - * src/: drv_imap.c, drv_maildir.c, isync.h, sync.c: - - split driver->prepare into ->prepare_opts and ->prepare_paths - -2006-01-25 06:35 Oswald Buddenhagen - - * src/drv_imap.c: - - #include limits.h (for INT_MAX) - REF: - -2006-01-13 16:10 Oswald Buddenhagen - - * src/sync.c: - - less confusing uid ranges in debug - -2006-01-12 06:36 Oswald Buddenhagen - - * configure.in, src/drv_imap.c: - - solaris 10 fix: use sys/filio.h for FIONREAD. untested. - REF: <20060111215014.GA601@49.180.97-84.rev.gaoland.net> - -2006-01-08 19:25 Oswald Buddenhagen - - * src/run-tests.pl: - - adjust to: omit flags other than "deleted" when expunging target. - -2006-01-03 09:28 Oswald Buddenhagen - - * src/run-tests.pl: - - collect stderr as well. - -2005-12-29 13:08 Oswald Buddenhagen - - * src/sync.c: - - don't record we synced flags if we didn't. - -2005-12-28 20:45 Oswald Buddenhagen - - * src/util.c: - - have to flush debug as well ... - -2005-12-28 20:05 Oswald Buddenhagen - - * src/sync.c: - - of course F_DELETED will have been added to expired slave messages, so - don't complain about it. - -2005-12-28 19:17 Oswald Buddenhagen - - * src/sync.c: - - put message references into the sync records. match up the uids after - opening the boxes instead of "sort-of-on-demand" - this is much simpler. - match from messages to sync records, not the other way round - makes the - debug output shorter, as the separate dump_box() is gone now. - -2005-12-28 19:10 Oswald Buddenhagen - - * src/sync.c: - - "reformat" S_EXP_S setting logic for understandability. - -2005-12-28 11:07 Oswald Buddenhagen - - * src/main.c: - - whoops - -2005-12-28 10:02 Oswald Buddenhagen - - * src/: config.c, isync.h, main.c, sync.c: - - - instead of having {m,s}foo, we have foo[2] now, so we can do - everything with loops instead of symmetric function calls - - added some const - -2005-12-27 17:44 Oswald Buddenhagen - - * src/run-tests.pl: - - show debug output on error. - -2005-12-27 17:31 Oswald Buddenhagen - - * src/run-tests.pl: - - make the error case output more useful by dumping the entire data set. - -2005-12-26 16:02 Oswald Buddenhagen - - * src/run-tests.pl: - - fix error message - -2005-12-26 16:02 Oswald Buddenhagen - - * src/run-tests.pl: - - add expiration tests - -2005-12-26 16:01 Oswald Buddenhagen - - * src/run-tests.pl: - - add MaxSize tests - -2005-12-26 16:00 Oswald Buddenhagen - - * src/run-tests.pl: - - when dumping mailboxes, sort by uid 1st. - -2005-12-26 15:58 Oswald Buddenhagen - - * src/run-tests.pl: - - detect excess messages after sync - -2005-12-26 15:57 Oswald Buddenhagen - - * src/run-tests.pl: - - sync state reader: - - grok negative uids - - more robust - -2005-12-26 15:54 Oswald Buddenhagen - - * src/run-tests.pl: - - don't eat array lead-in on empty arrays - -2005-12-26 15:02 Oswald Buddenhagen - - * src/sync.c: - - why would somebody manipulate an expired message? right, he wouldn't: - he would either expunge the mailbox or configure his MUA to hide trashed - messages. consequently don't sync expired message flags, let alone - interpret them in a special way. - one special feature remains, though: if a non-expunged expired message - is flagged on the master, it will be unexpired on the slave. i'm not - sure whether i should remove or document this feature. - -2005-12-26 14:55 Oswald Buddenhagen - - * src/sync.c: - - message tweaks - -2005-12-23 10:22 Oswald Buddenhagen - - * src/run-tests.pl: - - more logical order - -2005-12-22 18:06 Oswald Buddenhagen - - * src/: .cvsignore, run-tests.pl: - - add some regression testing. - -2005-12-22 14:59 Oswald Buddenhagen - - * src/sync.c: - - fix sync entries not being purged due to c&p error. - -2005-12-21 13:04 Oswald Buddenhagen - - * src/drv_maildir.c: - - less confusing error message on invalid mailbox. - -2005-12-18 14:10 Oswald Buddenhagen - - * src/config.c: - - it's beyond me what this memset was supposed to do ... - -2005-12-18 13:41 Oswald Buddenhagen - - * src/: config.c, main.c: - - trailing whitespace - -2005-12-17 13:47 Oswald Buddenhagen - - * src/drv_imap.c: - - revert 1.8 - what was i smoking?! the CREATE argument is already quoted; - we just extracted it from the previous command. - -2005-09-29 21:07 Oswald Buddenhagen - - * src/drv_maildir.c: - - make flag changes unset "new" status - unless a ghost is acting in the - background, a flag change indicates that the message was at least - noticed. - -2005-09-29 21:05 Oswald Buddenhagen - - * src/sync.c: - - don't call the driver's set_flags() if the flags did not change at all. - -2005-09-21 16:14 Oswald Buddenhagen - - * src/drv_imap.c: - - 64-bit cleanness - -2005-03-28 10:43 Oswald Buddenhagen - - * src/drv_imap.c: - - quote CREATE argument - -2005-03-28 10:26 Oswald Buddenhagen - - * configure.in: - - bump version - -2005-03-28 10:26 Oswald Buddenhagen - - * src/drv_maildir.c: - - fix inverted condition leading to endless loop when message is changed - while isync is running. - -2004-11-13 09:19 Oswald Buddenhagen - - * src/sync.c: - - cope with out-of-disk-space halfways gracefully (that is, don't clobber - the sync state including the journal, but exit immediately). - -2004-10-17 16:31 Oswald Buddenhagen - - * AUTHORS: - - sf.net -> sourceforge.net. otherwise the list-post is different from the - actual address, which makes mutt add two to addresses on list-reply ... - -2004-10-17 15:34 Oswald Buddenhagen - - * src/drv_imap.c: - - ignore user-defined flags (for now). - also, split off the backslash from the "core" flag names. - -2004-10-17 09:00 Oswald Buddenhagen - - * src/drv_imap.c: - - fix segfault due to wrong pointer being passed to parse_response_code. - inspired by Raimar Döffinger - -2004-10-17 08:30 Oswald Buddenhagen - - * src/drv_imap.c: - - remove spurious crlf during cram auth. not sure that this instance of - socket_write should be (re)moved, but as long as the .cont callback is - used only for this ... - investigation & patch by Mike Delaney. - -2004-09-24 08:45 Oswald Buddenhagen - - * Makefile.am: - - install supplementary doc files. - REF: 38C5E3CF30C73C4984F41AE8786C852AB739@khyron.ads.cs.umass.edu - -2004-09-20 11:31 Oswald Buddenhagen - - * src/drv_maildir.c: - - use legacy flock() only on linux. at least on OS X flock aliases to - fcntl. - -2004-09-20 11:28 Oswald Buddenhagen - - * src/: compat/main.c, drv_imap.c, isync.h, util.c: - - stdarg.h at the right places - -2004-09-15 09:33 Oswald Buddenhagen - - * README: - - update c-client compatibility - -2004-09-15 09:06 Oswald Buddenhagen - - * src/drv_maildir.c: - - when storing \seen messages, don't set the \recent flag on them. could - well be that this is incorrect, but some mailers need it that way. - when trashing messages, preserve their \recent status as well. - -2004-09-15 08:44 Oswald Buddenhagen - - * configure.in: - - whoops, wrong define - -2004-09-08 16:40 Oswald Buddenhagen - - * configure.in: - - don't encode maturity in version number - -2004-09-08 16:38 Oswald Buddenhagen - - * Makefile.am: - - optimize rpms for i686 - -2004-09-08 16:28 Oswald Buddenhagen - - * configure.in: - - sanitize the OpenSSL detection - -2004-09-08 16:14 Oswald Buddenhagen - - * src/drv_imap.c: - - stddef.h for offsetof - -2004-09-08 14:52 Oswald Buddenhagen - - * src/drv_maildir.c: - - first check _both_ bounds, then compare ... - -2004-09-07 11:59 Oswald Buddenhagen - - * src/sync.c: - - print name of mailbox being opened. - -2004-08-13 11:03 Oswald Buddenhagen - - * src/drv_imap.c: - - fix -C for imap mailboxes: - - SELECT does not return [TRYCREATE] - - fix bit field truncation - -2004-06-17 13:44 Oswald Buddenhagen - - * configure.in: - - A{C,S}_HELP_STRING aliasing tricks. - -2004-05-23 16:39 Oswald Buddenhagen - - * src/drv_maildir.c: - - store new UIDVALIDITY immediately after initializing it - -2004-04-27 20:23 Oswald Buddenhagen - - * src/compat/main.c: - - old -l is new -l -C - -2004-04-26 14:48 Oswald Buddenhagen - - * src/compat/: config.c, isync.h, main.c: - - full support for absolute paths in Mailboxes - -2004-04-26 14:09 Oswald Buddenhagen - - * src/compat/config.c: - - strip $HOME and ~ from Mailbox paths - -2004-03-29 22:32 Oswald Buddenhagen - - * src/: compat/util.c, util.c: - - fix return values of asprintf replacement. - -2004-03-29 06:52 Oswald Buddenhagen - - * src/compat/: config.c, isync.1, isync.h, main.c: - - unscrew --delete by merging it into the config file. merge --expunge as - well for symmetry. - -2004-03-27 16:07 Oswald Buddenhagen - - * .cvsignore, Makefile.am, README, configure.in, isync.spec.in, - src/.cvsignore, src/Makefile.am, src/compat/.cvsignore, - src/compat/Makefile.am, src/compat/config.c, - src/compat/convert.c, src/compat/isync.1, src/compat/isync.h, - src/compat/isyncrc.sample, src/compat/main.c, - src/compat/util.c, src/config.c, src/cram.c, src/dotlock.c, - src/dotlock.h, src/drv_imap.c, src/drv_maildir.c, src/imap.c, - src/isync.h, src/list.c, src/maildir.c, src/main.c, - src/mbsync.1, src/mbsyncrc.sample, src/mdconvert.1, - src/mdconvert.c, src/sync.c, src/util.c: - - The Big Rewrite. too many change to list them all. - - as opposed to earlier threats, BerkDB was not entirely dropped; i - suppose the isync 0.7 -> 0.8 change had a reason, so i added an - alternative UID storage scheme. - note that BDB 4.0 is not sufficient, as the db->open function changed in - an incompatible way ... - - i updated the debian packaging except for a changelog entry. - note that i removed the upgrade blurb, as upstream now has a smooth - upgrade path down to at least isync 0.4. - -2004-03-26 16:34 Oswald Buddenhagen - - * get-cert: - - excessively secure temp file creation. - more user friendliness. - -2004-02-07 15:36 Oswald Buddenhagen - - * src/dotlock.c: - - portability: don't rely on struct flock layout - -2004-02-01 16:44 Oswald Buddenhagen - - * .cvsignore: - - shht - -2004-02-01 16:27 Oswald Buddenhagen - - * src/: main.c, sync.c: - - once again: (slightly) better output. - make maildir flag setting failure non-fatal. maildir sucks ... - -2004-01-31 01:01 Oswald Buddenhagen - - * src/: imap.c, isync.h: - - more sophisticated CAPABILITY handling. also, don't issue the command if - the initial response already had it in the status code. - -2004-01-30 23:39 Oswald Buddenhagen - - * src/imap.c: - - don't ask for NAMESPACE if Folder was specified - -2004-01-30 23:35 Oswald Buddenhagen - - * src/: imap.c, isync.h: - - following the "screw murphy" principle and commiting untested patch: - obey LOGINDISABLED - -2004-01-27 21:01 Oswald Buddenhagen - - * src/imap.c: - - PREAUTH cannot come out of the blue - -2004-01-27 20:58 Oswald Buddenhagen - - * src/imap.c: - - cleanup around parse_fetch - -2004-01-27 20:50 Oswald Buddenhagen - - * src/: imap.c, isync.h, main.c: - - make Tag int, move it to imap.c - -2004-01-27 00:11 Nicolas Boullis - - * acinclude.m4, configure.in: - - Add a --disable-maintainer-mode option to configure. - -2004-01-20 01:55 Oswald Buddenhagen - - * src/imap.c: - - don't use STARTTLS for PREAUTH connections. uw-imap doesn't seem to like - it, and it does not make too much sense anyway - i think - state converse - opinions now. - -2004-01-20 01:27 Oswald Buddenhagen - - * Makefile.am: - - exclude ChangeLog (do'h), NEWS and TODO when creating ChangeLog. exclude - debian/ as well, based on the fact that it already has a detailed log - - is that ok with everybody? - -2004-01-18 02:22 Oswald Buddenhagen - - * isync.1, src/imap.c, src/isync.h, src/maildir.c, src/main.c, - src/sync.c: - - another message output cleanup, still not perfect (info messages will be - interleaved with progress dots). - support specifying -q twice to suppress warnings as well. - -2004-01-17 11:38 Oswald Buddenhagen - - * isync.1: - - document mua interaction - -2004-01-16 10:11 Oswald Buddenhagen - - * AUTHORS: - - credit where credit is due. are the comments satisfactory for everybody? - -2004-01-15 03:51 Theodore Ts'o - - * get-cert: - - Script that can be used to extract the server's certificate from an IMAP - server. - -2004-01-15 02:23 Oswald Buddenhagen - - * configure.in: - - remove useless define and more verbose error message. - -2004-01-13 03:56 Theodore Ts'o - - * configure.in: - - Use a more sophisticated test for the existence of libdb that works for - berk_db 4.0. - -2004-01-12 01:49 Oswald Buddenhagen - - * configure.in: - - bah, forgot to remove debian/Makefile.in from AC_OUTPUT. :} - kde's overly sophisticated build system does that automatically ... - -2004-01-12 01:24 Theodore Ts'o - - * src/: imap.c, isync.h, main.c: - - Optimized isync by not fetching the sizes of messages if they are - unneeded (i.e., if MaxSize is not specified in the config file). - - Patch and idea originally from Nicolas Boullis , - modified/polished by Theodore Ts'o per comments by Oswald Buddenhagen. - -2004-01-12 00:52 Oswald Buddenhagen - - * configure.in, src/isync.h, src/maildir.c, src/sync.c: - - sync uid database after every message. this is accompanied by a dbm -> - db4 migration. patch by theodore, with some final polishing by me. - -2004-01-12 00:38 Oswald Buddenhagen - - * Makefile.am: - - use ../CVSROOT/accounts for UID mapping in ChangeLog. - -2004-01-12 00:36 Oswald Buddenhagen - - * AUTHORS: - - be more explicit about contact address - -2004-01-11 12:38 Oswald Buddenhagen - - * .cvsignore: - - new stuff - -2004-01-11 12:35 Oswald Buddenhagen - - * Makefile.am: - - getting rid of Makefile.am in debian/ - it seems to be non-standard and - is a pita to maintain anyway. instead, make distdir and distclean depend - on a partial debian-clean. - -2004-01-11 11:53 Oswald Buddenhagen - - * autogen.sh: - - don't call configure - -2004-01-09 20:43 Oswald Buddenhagen - - * src/main.c: - - ignore anything that does not look remotely like a maildir when - collecting mailboxes for OneToOne. - -2003-12-07 15:37 Oswald Buddenhagen - - * isyncrc.sample: - - add sample CertificateFile - -2003-12-07 15:36 Oswald Buddenhagen - - * src/imap.c: - - add trailing space to password prompt - -2003-12-07 15:34 Oswald Buddenhagen - - * src/main.c: - - make imaps: on the command line adjust the port and ssl options as well - -2003-12-07 15:09 Oswald Buddenhagen - - * configure.in: - - bump version - -2003-12-02 02:53 Oswald Buddenhagen - - * src/imap.c: - - echo the mailbox the password is for - -2003-11-11 03:02 Oswald Buddenhagen - - * AUTHORS: - - be more explicit about maintainership, as people don't seem to get it. - -2003-09-02 12:06 Oswald Buddenhagen - - * isync.1: - - minor additions - -2003-07-02 17:18 Oswald Buddenhagen - - * src/imap.c: - - fix crash when syncing multiple mailboxes over a Tunnel - -2003-05-14 13:42 Oswald Buddenhagen - - * isync.1: - - minor - -2003-05-07 00:06 Oswald Buddenhagen - - * .cvsignore, Makefile.am, autogen.sh, configure.in, - src/config.c, src/cram.c, src/dotlock.c, src/imap.c, - src/isync.h, src/list.c, src/maildir.c, src/main.c, - src/sync.c: - - - make it work without SSL - - switch from -Ds in Makefile to config.h - - small header cleaup - -2003-05-07 00:04 Oswald Buddenhagen - - * isync.spec.in: - - make it actually work - -2003-05-06 02:17 Oswald Buddenhagen - - * Makefile.am: - - minors - -2003-05-06 02:15 Oswald Buddenhagen - - * README: - - i'm bored :) - -2003-05-05 17:58 Oswald Buddenhagen - - * src/: config.c, isync.h, main.c: - - don't free any config strings - who cares for a few bytes? - this fixes some crashes at exit. - -2003-05-05 17:17 Oswald Buddenhagen - - * Makefile.am: - - switch ChangeLog generation to cvs2cl - -2003-05-05 13:43 Oswald Buddenhagen - - * isync.1: - - minor fixes - -2003-05-05 13:41 Oswald Buddenhagen - - * configure.in: - - cleanup - -2003-05-05 13:24 Oswald Buddenhagen - - * src/main.c: - - accumulate status over multiple mailboxes, i.e., don't abort after first - failure - -2003-05-05 12:54 Oswald Buddenhagen - - * src/imap.c: - - fix imaps: - -2003-02-27 18:43 Oswald Buddenhagen - - * src/sync.c: - - ignore \Recent, as it is voided by the syncronization run itself. - -2002-12-28 15:31 Oswald Buddenhagen - - * src/: config.c, cram.c, imap.c, isync.h, list.c, maildir.c, - main.c, sync.c: - - - update copyrights. 2003 didn't begin yet, but who cares? :) - -2002-12-28 04:14 Oswald Buddenhagen - - * isync.1: - - - fixed typo - - updated maintainer and location - -2002-12-28 04:12 Oswald Buddenhagen - - * src/: maildir.c, sync.c: - - - update isyncmaxuid properly - -2002-12-28 04:04 Oswald Buddenhagen - - * src/config.c: - - - fixed two crashes - -2002-12-28 04:02 Oswald Buddenhagen - - * src/imap.c: - - - handle bogus search responses more gracefully - -2002-12-28 04:00 Oswald Buddenhagen - - * src/imap.c: - - - workaround imap server bug: lock files are no mailboxes - -2002-12-28 03:58 Oswald Buddenhagen - - * src/: imap.c, sync.c: - - - improve console output - -2002-12-28 03:11 Oswald Buddenhagen - - * .cvsignore: - - - ssht! - -2002-12-28 03:05 Oswald Buddenhagen - - * .cvsignore, AUTHORS, Makefile.am, README, autogen.sh, - configure.in, isync.spec.in, src/.cvsignore, src/Makefile.am, - src/config.c, src/cram.c, src/dotlock.c, src/dotlock.h, - src/imap.c, src/isync.h, src/list.c, src/maildir.c, - src/main.c, src/sync.c: - - - took over maintenance - - moved to sourceforge - - reorganized cvs structure - -2002-10-30 02:31 Michael Elkins - - * config.c, cram.c, dotlock.c, dotlock.h, imap.c, isync.1, - isync.h, list.c, maildir.c, main.c, sync.c: - - Updated the copyright notice to allow an exception for linking with OpenSSL, - which has a non-GPL compatible license. - -2002-10-30 02:23 Michael Elkins - - * .cvsignore, config.c, imap.c, isync.1, isync.h, maildir.c, - main.c, sync.c: - - Bunch 'o patches from Oswald Buddenhagen: - - i implemented some cool stuff (tm). - first, the long missing "create server-side missing mailboxes". -C now - creates both local and remote boxes; -L and -R create only local/remote. - second, i implemented a 1:1 remote:local folder mapping (-1) with an - optional INBOX exception (inbox/-I). the remote folder is specified with - the folder keyword (or -F switch) and takes precedence over the - namespace setting. the local directory with the mailboxes can now be - specified on the command line, too (-M). - - another patch: - - made the -1 switch settable permanently (OneToOne). after all, you - usually define your mailbox layout once forever. removed -A, as it is - semantically -a modified by -1. - - cleaned up message output a bit. still, the quiet variable should be - used throughout the program. at best, create some generic output - function, which obeys a global verbosity level variable. - - optimized + cleaned up configuration parser slightly - - minor cleanups - - add an (almost) unique id to every uploaded message and search for it - right after. i thought about using the message-id, but a) it is not - guaranteed to be unique in a mailbox (imagine you edit a mail and store - the dupe in the same box) and b) some mails (e.g., postponed) don't even - have one. a downside of the current implementation is, that this - id-header remains in the mailbox, but given that it wastes only 27 bytes - per mail and removing it would mean several roundtrips more, this seems - acceptable. - i changed the line-counting loop to use a mmapped file instead of - reading it in chunks, as it makes things simpler and is probably even - faster for big mails. - the amount of goto statements in my code may be scary, but c is simply - lacking a multi-level break statement. :) - - this is the "shut up" patch. :) it makes the -q option consequent, so to - say. - additionally it adds an -l option which gathers all defined/found - mailboxes and just outputs the list. don't ask what i need it for. ;) - -2002-10-30 02:01 Michael Elkins - - * maildir.c: - - fixed missing closedir() call (Joey Hess) - -2002-06-27 03:55 Michael Elkins - - * imap.c: - - explicitly set global.pass to NULL when getpass() returns an empty string. - -2002-06-27 03:51 Michael Elkins - - * imap.c: - - Oswald Buddenhagen - * fix imap_open() brokeness with PREAUTH (missed hunk from previous patch) - -2002-06-22 17:06 Michael Elkins - - * dotlock.c, imap.c: - - fixed errors introduced by ME when hand-applying Oswald Nuddenhagen's - patch. - -2002-06-22 01:21 Michael Elkins - - * autogen.sh, dotlock.c, imap.c, isync.h, main.c: - - Patch from Oswald Buddenhagen - - move prompt for password to imap_open() - - don't ask for global password in PREAUTH state - - use socketpair() to create one full-duplex fd in tunnel mode - instead of two half-duplex pipes - - don't set lck.l_pid in fcntl() call (its read-only) - - use F_SETLK instead of F_SETLKW to avoid infinite waiting - - use "$@" in autogen.sh to get proper word expansion - -2002-06-21 00:26 Michael Elkins - - * configure.in, isync.h: - - Fixed to compile under FreeBSD 4.6-RELEASE. Must include ndbm.h rather than - db.h. - -2002-06-20 23:33 Michael Elkins - - * Makefile.am, dotlock.c, dotlock.h, maildir.c: - - remove debian/files - - move dotlocking code to dotlock.c. - - dotlocking code fixed to ignore whether or not the lockfile exists on - open(). we only care about whether fcntl() was able to lock it. - -2002-06-19 02:31 Michael Elkins - - * sync.c: - - Don't bother uploaded messages marked deleted when we are going to expunge. - -2002-06-19 01:11 Michael Elkins - - * AUTHORS, imap.c, maildir.c: - - fixed unused var warning in imap_open() - - locking cleanups from Oswald Buddenhagen - * don't need to stat the lockfile since it will always be size 0 - * only remove lockfile when we actually succeeded in locking - -2002-06-19 00:44 Michael Elkins - - * Makefile.am: - - Debian package cleanups from Oswald Buddenhagen - -2002-06-18 06:37 Michael Elkins - - * README, isync.1, isync.h, maildir.c, main.c, sync.c: - - updated URL for project - - fixed segmentation fault caused by double free() when an error occurred - during the IMAP transmission. - - fixed bug where isync could not handle a 0 value UIDVALIDITY - -2002-04-19 19:43 Michael Elkins - - * config.c, configure.in, imap.c, isync.1, isync.h, - isyncrc.sample, main.c: - - PREAUTH support from Oswald Buddenhagen - - Added Tunnel directive to allow the user to specify a shell command to run - to set up an IMAP connection in place of a TCP socket (eg., to run over - an SSH session). - -2002-01-28 19:39 Michael Elkins - - * isync.spec.in: - - post 0.8 release commit - -2002-01-28 19:34 Michael Elkins - - * configure.in: - - check for dbm_open() in libc and libdb - -2002-01-17 19:33 Michael Elkins - - * sync.c: - - don't bother renaming the message file if we are about to unlink() it - -2002-01-16 22:23 Michael Elkins - - * AUTHORS, Makefile.am, sync.c: - - remove tilde backup files for distclean - - fixed indentation - - added full name to AUTHORS - - reformated NEWS blurb for 0.8 - -2002-01-16 22:13 Michael Elkins - - * maildir.c, sync.c: - - sync_mailbox() did not update the msg struct when flags were changed, - causing the expunge command to fail - - remove bogus strfcpy() line - -2002-01-16 21:51 Michael Elkins - - * Makefile.am, configure.in: - - added debian build files dist target so that people can use them to build - their own .deb packages without having to use CVS - -2002-01-16 21:43 Michael Elkins - - * isync.1, maildir.c, sync.c: - - added debian build files - - fixed indentation - - added bug note to manpage about db file format not being architecture - independent - -2002-01-16 21:22 Michael Elkins - - * maildir.c, sync.c: - - remove the uid from the db when a message is deleted from the maildir - - optimize db fetch/store to not copy the base filename - -2002-01-16 19:47 Michael Elkins - - * config.c, configure.in, cram.c, imap.c, isync.1, isync.h, - list.c, maildir.c, main.c, sync.c: - - updated year in copyright notice - - the uid for each message in the maildir is now stored in a dbm database - rather than the filename. this change was necessary because isync became - confused if you copied a message to another folder, in which case the uid - was invalid. - - as a result of the above change, isync now acquires a mutex on the mailbox - to protect the dbm database from concurrent access. - - main() was reworked to continue gracefully when an error is encountered, and - to always call maildir_close() so that the lock can be disabled, and the - database closed. - -2001-11-20 18:28 Michael Elkins - - * Makefile.am, isync.spec.in: - - post 0.7-release commit - -2001-11-20 18:06 Michael Elkins - - * Makefile.am, isync.1, isync.h, maildir.c, main.c: - - added --create/-C command line option to force creation of the local - maildir-style mailbox if nonexistent - - debug.h was not included in isync_SOURCES in Makefile.am - -2001-11-19 19:41 Michael Elkins - - * Makefile.am, config.c, configure.in, isync.h, list.c, main.c: - - added memory debugging code - - fixed memory leak in free_list() - - free memory associated with global settings on exit - -2001-11-16 21:23 Michael Elkins - - * cram.c, imap.c, isync.h, sync.c: - - remove c++ style comments - - use %lu and cast off_t to unsigned long in printf() - -2001-11-15 23:59 Michael Elkins - - * config.c, isync.1, isync.h, main.c, sync.c: - - Added MaxMessages patch from Eivind Eklund . - - config_defaults() can just use memcpy() instead of assigning each struct - member individually. - - config_defaults() can be declared static - -2001-11-14 17:40 Michael Elkins - - * config.c, configure.in: - - move strndup() code into config.c for less complexity - - change AC_REPLACE_FUNC(strndup) to AC_CHECK_FUNCS(strndup) - - sed expression checking for gcc-3.0 should be quoted beccause it - fails under Solaris 2.7 - -2001-11-13 00:36 Michael Elkins - - * config.c, sync.c: - - strndup() could return a non-NULL terminated string - - size_t should be printed with %lu - - when expending tildes (~), an extra slash was inserted after the user's home - directory - -2001-11-12 23:03 Michael Elkins - - * isync.h, maildir.c, main.c: - - merge maildir_sync() and maildir_close(). the maxuid in a maildir still - needs to be updated in --fast mode, and the sync code already checks to see - if any changes were made to the mailbox. - -2001-11-09 00:35 Michael Elkins - - * README: - - add FreeBSD to the list of tested platforms - -2001-11-09 00:23 Michael Elkins - - * config.c, configure.in, imap.c, maildir.c: - - update version to 0.7 - - detect short write in write_strip() - - fix compilation warnings with gcc-2.95.4 - -2001-10-31 19:50 Michael Elkins - - * configure.in, imap.c, isync.h, main.c, sync.c: - - set compiler warnings for gcc-3.0 as well - - display message with count of uploaded messages - - --quiet now supresses warnings in sync_mailbox() - - fixed compiler warnings with -Wshadow - -2001-10-31 06:06 Michael Elkins - - * isync.1: - - post 0.6 commit - -2001-10-30 22:57 Michael Elkins - - * README, configure.in: - - add strndup replacement function for systems which lack it - -2001-10-03 17:10 Michael Elkins - - * Makefile.am, maildir.c: - - fixed broken code in maildir_clean_tmp() - -2001-10-03 16:48 Michael Elkins - - * maildir.c: - - added code to clean the tmp directory in a maildir to comply with - maildir(5) - -2001-10-03 06:32 Michael Elkins - - * config.c: - - forgot to add code to parse the `Delete' option - -2001-10-03 06:18 Michael Elkins - - * main.c: - - forgot conditional #if HAVE_LIBSSL around setting of .use_imaps in main() - from command line arguments - -2001-10-03 06:15 Michael Elkins - - * main.c: - - update Copyright printed by --help - - add compile time option list to --help output - -2001-10-03 05:42 Michael Elkins - - * config.c, isync.1, isync.h, isyncrc.sample, main.c, sync.c: - - added `Delete' configuration option to force -d option - - sync_mailbox() didn't consider MaxSize == 0 to mean "unlimited". - - load_config() needs to print a newline in its error messages since - next_arg() kills the newline of the line that was read out of the config - file. - -2001-10-03 00:01 Michael Elkins - - * imap.c, sync.c: - - fixed maildir message filenames to comply with the maildir(5) specification. - - fixed write_strip() and imap_fetch_message() to check the return code of - write() and fsync() to comply with maildir(5) spec. - -2001-10-02 23:43 Michael Elkins - - * main.c: - - the `Expunge' config directive didn't work since only the -e command line - argument was consulted. - -2001-10-02 22:46 Michael Elkins - - * config.c, imap.c, isync.h: - - we should issue a CAPABILITY even if we aren't going to use ssl/tls so that - cram-md5 auth still works. - -2001-07-18 18:56 Michael Elkins - - * config.c: - - find_box() should attempt to expand all filenames if none of the other - methods found a match. - -2001-07-18 18:49 Michael Elkins - - * config.c, isync.h, maildir.c: - - fixed to not expand filenames until they are used inside of maildir_open(), - so that aliases are not required for simple filenames. - [re: http://bugs.debian.org/102255] - -2001-06-22 23:30 Michael Elkins - - * main.c: - - --host option didn't check for imaps: prefix - -2001-06-21 20:45 Michael Elkins - - * main.c: - - fixed core when specifying multiple mailboxes on the command line - -2001-06-18 21:38 Michael Elkins - - * configure.in, imap.c, isync.1: - - handle untagged responses in imap_fetch_message() so that it doesn't bomb - out if new mail arrives while in the process of downloading - - noted in BUGS section of man page that if new mail arrives after the initial - message list has been retrieved from the IMAP server, that new mail will not - be fetched until the next invocation of isync. - -2001-06-18 17:49 Michael Elkins - - * config.c, imap.c, isync.h, main.c: - - isync should continue to process additional mailboxes even if there is an - error with a previous mailbox. - - added -a (--all) flag to synchronize all mailboxes defined in ~/.isyncrc - -2001-02-28 01:02 Michael Elkins - - * config.c, imap.c: - - fixed compiler warnings under Solaris 2.7 - -2001-02-19 18:44 Michael Elkins - - * cram.c, imap.c, maildir.c: - - rfc2595 compliance patch from Daniel Resare - - CAPABILITY should be reissued after starting TLS since the - previous call was not protected - -2001-02-14 20:46 Michael Elkins - - * config.c, imap.c, isync.1, main.c, sync.c: - - patch from Daniel Resare : - 1 giving a path to a nonexistant rc-file with the -c argument dumps core - - The patch adds a check to ensure that the given rc-file is accessible - - 2 the error messages given from failed openssl calls are bogus - - The handles the error from SSL_connect () correctly. The bug is - understndable since the error handling in openssl is quite obfuscated. - Good news is that the documentation manapges has been greatly updated in - the latest version (0.9.6). See in particular err(3), ERR_get_error(3) - and SSL_get_error(3). - - Please note that possible SSL_ERROR_SSL type errors from SSL_read() and - SSL_write() is not handled. This should also be fixed. - - 3 connecting using the STARTTLS command with an imap server that is - configured only to accept the TLSv1 protocol gives an error because isync - sends an SSLv2 Hello message for backwards compability. (This is the case - with the uw-imap 2000 that ships with redhat-7.0) - I've read RFC2595 several times to see if it says something about - compability SSL2/SSL3 hello messages but can't find anything. IMHO the - correct thing to do is change the default to not use SSL2/3 compability - hello when using the STARTTLS command but use it if the imaps port is - used. The patch implements this change - - 4 repeated calls to SSL_CTX_set_options overwrites the old settings (the - values needs to be ORed together) - - fixed in the patch - - patch from me@mutt.org: - \Recent messages were put in the cur/ directory instead of new/ - - give error message when the LOGIN command fails - -2001-02-01 23:35 Michael Elkins - - * imap.c: - - patch from Daniel Resare - - don't initialize ssl support if none of use_sslv* is enabled - -2001-01-26 20:21 Michael Elkins - - * imap.c, isync.h: - - include for off_t - - patch from "lorenzo martignoni" - - fixed uploading of message to IMAP server - -2001-01-24 07:09 Michael Elkins - - * config.c, cram.c, imap.c, isync.1, list.c, maildir.c, main.c, - sync.c: - - fixed cram compilation error under bsd - - updated man page - -2001-01-16 19:45 Michael Elkins - - * config.c, imap.c, isync.1, isync.h, main.c: - - added support for tilde (~) expansion in the `Mailbox' and `CertificateFile' - configuration directives - - added `Maildir' configuration command to specify the default location of the - user's mailboxes. If a relative path is used in a `Mailbox' command, this - path is used as a prefix. - -2001-01-11 10:21 Michael Elkins - - * configure.in, imap.c, isync.h: - - set imap->prefix to be the namespace prefix - - update version to 0.5 - - fixed compilation warnings in imap.c - -2001-01-11 10:13 Michael Elkins - - * Makefile.am, config.c, imap.c, isync.1, isync.h, - isyncrc.sample, main.c, sync.c: - - broke config code into config.c - - added support for uploading local messages with no UID to the IMAP server - - added Expunge configuration option - - added CopyDeletedTo configuration option - -2001-01-09 20:09 Michael Elkins - - * maildir.c, sync.c: - - always put changed messages in the cur/ subdirectory since they are no - longer new. - - don't set \Seen implicitly for messages in the cur/ folder. Require the S - flag on the message since Mutt will move Old (unread, but not recent) - messges into cur/. - -2001-01-08 09:45 Michael Elkins - - * Makefile.am, main.c: - - patch from Hugo Haas - -c was not specified in the getopt*() calls - - set global password to the one the user inputs and use that as the - default for remaining mailboxes - -2001-01-05 21:20 Michael Elkins - - * configure.in: - - added --with-ssl-dir to specify an alternate installation of OpenSSL - -2000-12-31 22:39 Michael Elkins - - * isync.spec.in: - - pre 0.4 commit. - - updated rpm spec file - -2000-12-31 22:37 Michael Elkins - - * sync.c: - - display how many messages were fetched from the server - -2000-12-31 22:17 Michael Elkins - - * imap.c: - - fixed compilation error with no libssl support ("lorenzo martignoni" - ) - -2000-12-28 18:44 Michael Elkins - - * main.c: - - fixed config parser to accept arbitrary whitespace - -2000-12-27 21:16 Michael Elkins - - * imap.c: - - use imap_close to terminate a connection in imap_open() - -2000-12-27 21:14 Michael Elkins - - * imap.c, isync.1, isync.h, maildir.c, main.c: - - allow leading whitespace in config files - - now possible to sync multiple mailboxes by specifying multiple aliases on - the command line. IMAP connections are reused if possible. - - don't initialize ssl unless we are going to use it. - -2000-12-23 21:57 Michael Elkins - - * imap.c, isync.h: - - don't use NAMESPACE unless the server supports it - -2000-12-23 00:02 Michael Elkins - - * Makefile.am, README, cram.c, imap.c, isync.h: - - added CRAM-MD5 authentication support. - - parse server capability string to determine if STARTTLS is available - -2000-12-22 21:22 Michael Elkins - - * README, imap.c, isync.1, isync.h, main.c: - - isync-brokenservers.diff (Jeremy Katz ) - adds support for disabling NAMESPACE, and disable various flavors of TLS/SSL - for use with some broken IMAP servers. - -2000-12-22 19:30 Michael Elkins - - * imap.c, sync.c: - - prompt user if they wish to continue if the server's X.509 certificate can't - be verified. - - sync_mailbox should consider uid == 0 to be "unknown" - -2000-12-22 15:48 Michael Elkins - - * main.c, sync.c: - - fixed sync_mailbox() to correctly write new messages to the local maildir - box (Thomas Roessler ) - -2000-12-22 15:24 Michael Elkins - - * main.c: - - set default MaxSize to 0 (unlimited) - - invert test for password being set after getpass() call (Magnus Jonsson - ) - -2000-12-22 07:14 Michael Elkins - - * configure.in, imap.c, isync.1, isync.h, isyncrc.sample, - maildir.c, main.c, sync.c: - - added MaxSize configuration variable - - fixed --fast to work robustly without relying on the \Recent flag in - messages - -2000-12-21 23:10 Michael Elkins - - * imap.c, isync.h, maildir.c, sync.c: - - RFC822.PEEK is obsolete in RFC2060. Use BODY.PEEK[] instead, which does - the same thing - - keep track of the uidvalidity so isync can detect if the mailbox on the - server has changed since the last sync. - -2000-12-21 20:56 Michael Elkins - - * Makefile.am, isync.spec.in: - - added support for building RPMS - -2000-12-21 19:49 Michael Elkins - - * Makefile.am, isync.1: - - added target for creating html version of the man page - - documented the imaps: prefix to the Host command - -2000-12-21 19:11 Michael Elkins - - * imap.c, sync.c: - - can't assume flag order when fetching a message. just search for the - first `{' to find the message size. - -2000-12-21 18:16 Michael Elkins - - * isync.1, sync.c: - - added BUGS section to manpage detailing the fact that we break the - maildir(5) spec by parsing the filename - - change message delivery to use the method described in maildir(5) - -2000-12-21 17:51 Michael Elkins - - * configure.in, main.c, sync.c: - - use getpass() to get the user's password - - unlink the temp file if we are unable to fetch a new message from the - server. - - update version to 0.3 - -2000-12-21 11:14 Michael Elkins - - * isync.1: - - fixed typo in man page for --verbose option - -2000-12-21 10:24 Michael Elkins - - * Makefile.am, README, imap.c, isync.h, list.c: - - added generic IMAP list parser and rewrote imap_exec() to handle - arbitrary data instead of hardcoded - -2000-12-21 06:51 Michael Elkins - - * Makefile.am, README, configure.in, main.c: - - fixes to compile cleanly under Solaris 2.7 - -2000-12-21 06:27 Michael Elkins - - * configure.in, imap.c, isync.1, isync.h, main.c: - - added OpenSSL support - -2000-12-21 00:35 Michael Elkins - - * configure.in, main.c: - - config options were not case insensitive - -2000-12-21 00:30 Michael Elkins - - * imap.c, isync.h, maildir.c, main.c, sync.c: - - don't fetch deleted messages when expunging - - display number of messages that are to be deleted - - flags for \Recent messages were not properly fetched - - local messages with updated flags were not corrected renamed - -2000-12-20 22:28 Michael Elkins - - * Makefile.am: - - updated ChangeLog - - added log: rule in Makefile.am - -2000-12-20 22:10 Michael Elkins - - * autogen.sh: - - added autogen.sh to regenerate the build environment - -2000-12-20 22:00 Michael Elkins - - * COPYING: - - added missing files - -2000-12-20 21:41 Michael Elkins - - * AUTHORS, Makefile.am, README, configure.in, imap.c, isync.1, - isync.h, isyncrc.sample, maildir.c, main.c, sync.c: - - initial import - diff -Nru isync-1.1.0/compile isync-1.2.1-1.812.20170514/compile --- isync-1.1.0/compile 2013-12-18 21:09:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/compile 1970-01-01 00:00:00.000000000 +0000 @@ -1,347 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand '-c -o'. - -scriptversion=2012-10-14.11; # UTC - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' - -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent tools from complaining about whitespace usage. -IFS=" "" $nl" - -file_conv= - -# func_file_conv build_file lazy -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. If the determined conversion -# type is listed in (the comma separated) LAZY, no conversion will -# take place. -func_file_conv () -{ - file=$1 - case $file in - / | /[!/]*) # absolute file, and not a UNC file - if test -z "$file_conv"; then - # lazily determine how to convert abs files - case `uname -s` in - MINGW*) - file_conv=mingw - ;; - CYGWIN*) - file_conv=cygwin - ;; - *) - file_conv=wine - ;; - esac - fi - case $file_conv/,$2, in - *,$file_conv,*) - ;; - mingw/*) - file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` - ;; - cygwin/*) - file=`cygpath -m "$file" || echo "$file"` - ;; - wine/*) - file=`winepath -w "$file" || echo "$file"` - ;; - esac - ;; - esac -} - -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ - func_file_conv "$1" - if test -z "$lib_path"; then - lib_path=$file - else - lib_path="$lib_path;$file" - fi - linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ - lib=$1 - found=no - save_IFS=$IFS - IFS=';' - for dir in $lib_path $LIB - do - IFS=$save_IFS - if $shared && test -f "$dir/$lib.dll.lib"; then - found=yes - lib=$dir/$lib.dll.lib - break - fi - if test -f "$dir/$lib.lib"; then - found=yes - lib=$dir/$lib.lib - break - fi - if test -f "$dir/lib$lib.a"; then - found=yes - lib=$dir/lib$lib.a - break - fi - done - IFS=$save_IFS - - if test "$found" != yes; then - lib=$lib.lib - fi -} - -# func_cl_wrapper cl arg... -# Adjust compile command to suit cl -func_cl_wrapper () -{ - # Assume a capable shell - lib_path= - shared=: - linker_opts= - for arg - do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - eat=1 - case $2 in - *.o | *.[oO][bB][jJ]) - func_file_conv "$2" - set x "$@" -Fo"$file" - shift - ;; - *) - func_file_conv "$2" - set x "$@" -Fe"$file" - shift - ;; - esac - ;; - -I) - eat=1 - func_file_conv "$2" mingw - set x "$@" -I"$file" - shift - ;; - -I*) - func_file_conv "${1#-I}" mingw - set x "$@" -I"$file" - shift - ;; - -l) - eat=1 - func_cl_dashl "$2" - set x "$@" "$lib" - shift - ;; - -l*) - func_cl_dashl "${1#-l}" - set x "$@" "$lib" - shift - ;; - -L) - eat=1 - func_cl_dashL "$2" - ;; - -L*) - func_cl_dashL "${1#-L}" - ;; - -static) - shared=false - ;; - -Wl,*) - arg=${1#-Wl,} - save_ifs="$IFS"; IFS=',' - for flag in $arg; do - IFS="$save_ifs" - linker_opts="$linker_opts $flag" - done - IFS="$save_ifs" - ;; - -Xlinker) - eat=1 - linker_opts="$linker_opts $2" - ;; - -*) - set x "$@" "$1" - shift - ;; - *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) - func_file_conv "$1" - set x "$@" -Tp"$file" - shift - ;; - *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) - func_file_conv "$1" mingw - set x "$@" "$file" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift - done - if test -n "$linker_opts"; then - linker_opts="-link$linker_opts" - fi - exec "$@" $linker_opts - exit 1 -} - -eat= - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand '-c -o'. -Remove '-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file 'INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) - func_cl_wrapper "$@" # Doesn't return... - ;; -esac - -ofile= -cfile= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - # So we strip '-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no '-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # '.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use '[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff -Nru isync-1.1.0/configure isync-1.2.1-1.812.20170514/configure --- isync-1.1.0/configure 2013-12-18 21:09:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/configure 1970-01-01 00:00:00.000000000 +0000 @@ -1,6165 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for isync 1.1.0. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='isync' -PACKAGE_TARNAME='isync' -PACKAGE_VERSION='1.1.0' -PACKAGE_STRING='isync 1.1.0' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -with_compat_FALSE -with_compat_TRUE -SSL_LIBS -PKGCONFIG -SOCK_LIBS -EGREP -GREP -CPP -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_maintainer_mode -enable_dependency_tracking -with_ssl -enable_compat -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures isync 1.1.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/isync] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of isync 1.1.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --disable-maintainer-mode disable make rules and dependencies not useful - (and sometimes confusing) to the casual installer - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --disable-compat don't include isync compatibility wrapper [no] - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-ssl=PATH where to look for SSL [detect] - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -isync configure 1.1.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by isync $as_me 1.1.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_config_headers="$ac_config_headers autodefs.h" - -am__api_version='1.14' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='isync' - VERSION='1.1.0' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=yes -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -$as_echo "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -if test "$GCC" = yes; then - CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -ansi -pedantic -Wno-overlength-strings" -fi - -CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strftime supports %z" >&5 -$as_echo_n "checking whether strftime supports %z... " >&6; } -if ${ob_cv_strftime_z+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ob_cv_strftime_z="yes (assumed)" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include - -int main(void) -{ - time_t t = 0; - char buf[32]; - strftime(buf, sizeof(buf), "%z", localtime(&t)); - return !(buf[0] == '+' || buf[0] == '-'); -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ob_cv_strftime_z=yes -else - ob_cv_strftime_z=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ob_cv_strftime_z" >&5 -$as_echo "$ob_cv_strftime_z" >&6; } -if test "x$ob_cv_strftime_z" = x"no"; then - as_fn_error $? "libc lacks necessary feature" "$LINENO" 5 -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in sys/poll.h sys/select.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -for ac_func in vasprintf memrchr -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 -$as_echo_n "checking for socket in -lsocket... " >&6; } -if ${ac_cv_lib_socket_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char socket (); -int -main () -{ -return socket (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_socket=yes -else - ac_cv_lib_socket_socket=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 -$as_echo "$ac_cv_lib_socket_socket" >&6; } -if test "x$ac_cv_lib_socket_socket" = xyes; then : - SOCK_LIBS="-lsocket" -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnsl" >&5 -$as_echo_n "checking for inet_ntoa in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_inet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char inet_ntoa (); -int -main () -{ -return inet_ntoa (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nsl_inet_ntoa=yes -else - ac_cv_lib_nsl_inet_ntoa=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_ntoa" >&5 -$as_echo "$ac_cv_lib_nsl_inet_ntoa" >&6; } -if test "x$ac_cv_lib_nsl_inet_ntoa" = xyes; then : - SOCK_LIBS="$SOCK_LIBS -lnsl" -fi - - - -have_ipv6=true -sav_LDFLAGS=$LDFLAGS -LDFLAGS="$LDFLAGS $SOCK_LIBS" -for ac_func in getaddrinfo inet_ntop -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - have_ipv6=false -fi -done - -LDFLAGS=$sav_LDFLAGS -if $have_ipv6; then - -$as_echo "#define HAVE_IPV6 1" >>confdefs.h - -fi - -have_ssl_paths= - -# Check whether --with-ssl was given. -if test "${with_ssl+set}" = set; then : - withval=$with_ssl; ob_cv_with_ssl=$withval -fi - -if test "x$ob_cv_with_ssl" != xno; then - case $ob_cv_with_ssl in - ""|yes) - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKGCONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKGCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/bin:/usr/local/bin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_PKGCONFIG" && ac_cv_path_PKGCONFIG="no" - ;; -esac -fi -PKGCONFIG=$ac_cv_path_PKGCONFIG -if test -n "$PKGCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 -$as_echo "$PKGCONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "$PKGCONFIG" != "no" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL presence with pkg-config" >&5 -$as_echo_n "checking OpenSSL presence with pkg-config... " >&6; } - if $PKGCONFIG --exists openssl; then - SSL_LIBS=`$PKGCONFIG --libs-only-l openssl` - SSL_LDFLAGS=`$PKGCONFIG --libs-only-L openssl` - SSL_CPPFLAGS=`$PKGCONFIG --cflags-only-I openssl` - have_ssl_paths=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 -$as_echo "not found" >&6; } - fi - fi - ;; - *) - SSL_LDFLAGS=-L$ob_cv_with_ssl/lib$libsuff - SSL_CPPFLAGS=-I$ob_cv_with_ssl/include - ;; - esac - if test -z "$have_ssl_paths"; then - sav_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $SSL_LDFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - LIBDL=-ldl -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_lock in -lcrypto" >&5 -$as_echo_n "checking for CRYPTO_lock in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_CRYPTO_lock+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcrypto $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char CRYPTO_lock (); -int -main () -{ -return CRYPTO_lock (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_CRYPTO_lock=yes -else - ac_cv_lib_crypto_CRYPTO_lock=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_lock" >&5 -$as_echo "$ac_cv_lib_crypto_CRYPTO_lock" >&6; } -if test "x$ac_cv_lib_crypto_CRYPTO_lock" = xyes; then : - LIBCRYPTO=-lcrypto -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_connect in -lssl" >&5 -$as_echo_n "checking for SSL_connect in -lssl... " >&6; } -if ${ac_cv_lib_ssl_SSL_connect+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char SSL_connect (); -int -main () -{ -return SSL_connect (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ssl_SSL_connect=yes -else - ac_cv_lib_ssl_SSL_connect=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_connect" >&5 -$as_echo "$ac_cv_lib_ssl_SSL_connect" >&6; } -if test "x$ac_cv_lib_ssl_SSL_connect" = xyes; then : - SSL_LIBS="-lssl $LIBCRYPTO $LIBDL" have_ssl_paths=yes -fi - - LDFLAGS=$sav_LDFLAGS - fi - - sav_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : - -else - have_ssl_paths= -fi - - - CPPFLAGS=$sav_CPPFLAGS - - if test -z "$have_ssl_paths"; then - if test -n "$ob_cv_with_ssl"; then - as_fn_error $? "OpenSSL libs and/or includes were not found where specified" "$LINENO" 5 - fi - else - -$as_echo "#define HAVE_LIBSSL 1" >>confdefs.h - - CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS" - LDFLAGS="$LDFLAGS $SSL_LDFLAGS" - fi -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkley DB >= 4.2" >&5 -$as_echo_n "checking for Berkley DB >= 4.2... " >&6; } -if ${ac_cv_berkdb4+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_berkdb4=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -DB *db; - db->truncate(db, 0, 0, 0); - db->open(db, 0, "foo", "foo", DB_HASH, DB_CREATE, 0) - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_berkdb4=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_berkdb4" >&5 -$as_echo "$ac_cv_berkdb4" >&6; } -if test "x$ac_cv_berkdb4" = xno; then - as_fn_error $? "Berkley DB >= 4.2 not found." "$LINENO" 5 -fi - -# Check whether --enable-compat was given. -if test "${enable_compat+set}" = set; then : - enableval=$enable_compat; ob_cv_enable_compat=$enableval -fi - -if test "x$ob_cv_enable_compat" != xno; then - for ac_func in getopt_long -do : - ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long" -if test "x$ac_cv_func_getopt_long" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETOPT_LONG 1 -_ACEOF - -fi -done - -fi - if test "x$ob_cv_enable_compat" != xno; then - with_compat_TRUE= - with_compat_FALSE='#' -else - with_compat_TRUE='#' - with_compat_FALSE= -fi - - -ac_config_files="$ac_config_files Makefile src/Makefile src/compat/Makefile isync.spec" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${with_compat_TRUE}" && test -z "${with_compat_FALSE}"; then - as_fn_error $? "conditional \"with_compat\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by isync $as_me 1.1.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -isync config.status 1.1.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "autodefs.h") CONFIG_HEADERS="$CONFIG_HEADERS autodefs.h" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; - "src/compat/Makefile") CONFIG_FILES="$CONFIG_FILES src/compat/Makefile" ;; - "isync.spec") CONFIG_FILES="$CONFIG_FILES isync.spec" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -if test -n "$have_ssl_paths"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: -Using SSL -" >&5 -$as_echo " -Using SSL -" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: -Not using SSL -" >&5 -$as_echo " -Not using SSL -" >&6; } -fi diff -Nru isync-1.1.0/configure.ac isync-1.2.1-1.812.20170514/configure.ac --- isync-1.1.0/configure.ac 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/configure.ac 2017-05-26 14:36:31.000000000 +0000 @@ -1,12 +1,12 @@ -AC_INIT([isync], [1.1.0]) +AC_INIT([isync], [1.3.0]) AC_CONFIG_HEADERS([autodefs.h]) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE -AC_PROG_CC +AC_PROG_CC_C99 if test "$GCC" = yes; then - CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -ansi -pedantic -Wno-overlength-strings" + CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -std=c99 -pedantic -Wno-overlength-strings" fi CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" @@ -29,17 +29,17 @@ fi AC_CHECK_HEADERS(sys/poll.h sys/select.h) -AC_CHECK_FUNCS(vasprintf memrchr) +AC_CHECK_FUNCS(vasprintf strnlen memrchr timegm) AC_CHECK_LIB(socket, socket, [SOCK_LIBS="-lsocket"]) AC_CHECK_LIB(nsl, inet_ntoa, [SOCK_LIBS="$SOCK_LIBS -lnsl"]) AC_SUBST(SOCK_LIBS) have_ipv6=true -sav_LDFLAGS=$LDFLAGS -LDFLAGS="$LDFLAGS $SOCK_LIBS" +sav_LIBS=$LIBS +LIBS="$LIBS $SOCK_LIBS" AC_CHECK_FUNCS(getaddrinfo inet_ntop, , [have_ipv6=false]) -LDFLAGS=$sav_LDFLAGS +LIBS=$sav_LIBS if $have_ipv6; then AC_DEFINE(HAVE_IPV6, 1, [if your libc has IPv6 support]) fi @@ -100,15 +100,74 @@ fi AC_SUBST(SSL_LIBS) -AC_CACHE_CHECK([for Berkley DB >= 4.2], ac_cv_berkdb4, +have_sasl_paths= +AC_ARG_WITH(sasl, + AS_HELP_STRING([--with-sasl[=PATH]], [where to look for SASL [detect]]), + [ob_cv_with_sasl=$withval]) +if test "x$ob_cv_with_sasl" != xno; then + case $ob_cv_with_sasl in + ""|yes) + dnl FIXME: Try various possible paths here... + ;; + *) + SASL_LDFLAGS=-L$ob_cv_with_sasl/lib$libsuff + SASL_CPPFLAGS=-I$ob_cv_with_sasl/include + ;; + esac + if test -z "$have_sasl_paths"; then + sav_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $SASL_LDFLAGS" + AC_CHECK_LIB(sasl2, sasl_client_init, + [SASL_LIBS="-lsasl2" have_sasl_paths=yes]) + LDFLAGS=$sav_LDFLAGS + fi + + sav_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $SASL_CPPFLAGS" + AC_CHECK_HEADER(sasl/sasl.h, , [have_sasl_paths=]) + CPPFLAGS=$sav_CPPFLAGS + + if test -z "$have_sasl_paths"; then + if test -n "$ob_cv_with_sasl"; then + AC_MSG_ERROR([SASL libs and/or includes were not found where specified]) + fi + else + AC_DEFINE(HAVE_LIBSASL, 1, [if you have the SASL libraries]) + CPPFLAGS="$CPPFLAGS $SASL_CPPFLAGS" + LDFLAGS="$LDFLAGS $SASL_LDFLAGS" + fi +fi +AC_SUBST(SASL_LIBS) + +AC_CACHE_CHECK([for Berkeley DB >= 4.1], ac_cv_berkdb4, [ac_cv_berkdb4=no + sav_LIBS=$LIBS + LIBS="$LIBS -ldb" AC_TRY_LINK([#include ], [DB *db; + db_create(&db, 0, 0); db->truncate(db, 0, 0, 0); db->open(db, 0, "foo", "foo", DB_HASH, DB_CREATE, 0)], - [ac_cv_berkdb4=yes])]) -if test "x$ac_cv_berkdb4" = xno; then - AC_MSG_ERROR([Berkley DB >= 4.2 not found.]) + [ac_cv_berkdb4=yes]) + LIBS=$sav_LIBS + ]) +if test "x$ac_cv_berkdb4" = xyes; then + AC_SUBST([DB_LIBS], ["-ldb"]) + AC_DEFINE(USE_DB, 1, [if Berkeley DB should be used]) +fi + +have_zlib= +AC_ARG_WITH(zlib, + AS_HELP_STRING([--with-zlib], [use zlib [detect]]), + [ob_cv_with_zlib=$withval]) +if test "x$ob_cv_with_zlib" != xno; then + AC_CHECK_LIB([z], [deflate], + [AC_CHECK_HEADER(zlib.h, + [have_zlib=1 + AC_SUBST([Z_LIBS], ["-lz"]) + AC_DEFINE([HAVE_LIBZ], 1, [if you have the zlib library])] + )] + ) fi AC_ARG_ENABLE(compat, @@ -117,17 +176,31 @@ if test "x$ob_cv_enable_compat" != xno; then AC_CHECK_FUNCS(getopt_long) fi -AM_CONDITIONAL(with_compat, test "x$ob_cv_enable_compat" != xno) +AM_CONDITIONAL(with_compat, test "x$ob_cv_enable_compat" != xno -a "x$ac_cv_berkdb4" = xyes) +AM_CONDITIONAL(with_mdconvert, test "x$ac_cv_berkdb4" = xyes) AC_CONFIG_FILES([Makefile src/Makefile src/compat/Makefile isync.spec]) AC_OUTPUT +AC_MSG_RESULT() if test -n "$have_ssl_paths"; then - AC_MSG_RESULT([ -Using SSL -]) + AC_MSG_RESULT([Using SSL]) +else + AC_MSG_RESULT([Not using SSL]) +fi +if test -n "$have_sasl_paths"; then + AC_MSG_RESULT([Using SASL]) +else + AC_MSG_RESULT([Not using SASL]) +fi +if test -n "$have_zlib"; then + AC_MSG_RESULT([Using zlib]) +else + AC_MSG_RESULT([Not using zlib]) +fi +if test "x$ac_cv_berkdb4" = xyes; then + AC_MSG_RESULT([Using Berkeley DB]) else - AC_MSG_RESULT([ -Not using SSL -]) + AC_MSG_RESULT([Not using Berkeley DB]) fi +AC_MSG_RESULT() diff -Nru isync-1.1.0/debian/bzr-builder.manifest isync-1.2.1-1.812.20170514/debian/bzr-builder.manifest --- isync-1.1.0/debian/bzr-builder.manifest 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/bzr-builder.manifest 2017-05-26 14:36:32.000000000 +0000 @@ -0,0 +1,3 @@ +# bzr-builder format 0.4 deb-version 1.2.1-1.812.20170514-ubuntu1 +lp:~slgeorge/isync/trunk revid:git-v1:4b3768806278a70db696ba52645dc1b6eb8de58a +merge slg-build lp:~slgeorge/isync/isync-dailybuild-slg revid:sg@futurile.net-20160818112152-x1kpio4egsu97b3w diff -Nru isync-1.1.0/debian/changelog isync-1.2.1-1.812.20170514/debian/changelog --- isync-1.1.0/debian/changelog 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/changelog 2017-05-26 14:36:32.000000000 +0000 @@ -1,44 +1,14 @@ -isync (1.1.0-2) unstable; urgency=medium +isync (1.2.1-1.812.20170514-ubuntu1~ubuntu14.04.1) trusty; urgency=low - * Drop 02_fix-duplicate-changelog.patch - (rm the file after installation instead) - * Update 01_fix-manpages.patch - * Add 02_fix-empty-folder-sync.patch (Closes: #738873) - - -- Alessandro Ghedini Fri, 14 Feb 2014 20:41:49 +0100 - -isync (1.1.0-1) unstable; urgency=low - - * New upstream release (Closes: #674403) - - Fix overlapping memcpy (Closes: #650373) - - Fix segfault while syncing mailboxes (Closes: #411120) - - Fix segfault when invoked with arguments without configuration - (Closes: #727239) - * Bump debhelper compat level, update Build-Depends - * Switch to short-form dh rules, remove useless files - * Switch to 3.0 (quilt) source format - * Remove empty patches/ directory - * Drop local source modifications - * Update short/long descriptions - * Add 01_fix-manpages.patch to fix manpage errors and typos - * Add Homepage field - * Update copyright file to Copyright-Format 1.0 - * Add Vcs-* fields - * Add 02_fix-duplicate-changelog.patch to avoid duplicate changelog install - * Add myself to Uploaders - * Bump Standards-Version to 3.9.5 (no changes needed) - * Use dh-autoreconf instead of autotools-dev - - -- Alessandro Ghedini Sun, 12 Jan 2014 16:35:52 +0100 - -isync (1.0.4-2.2) unstable; urgency=low - - * Non-maintainer upload. - * Apply upstream patch for CVE-2013-0289. - Fix incorrect server's SSL x509.v3 certificate validation when - performing IMAP synchronization. (Closes: #701052) + * Auto build. - -- Salvatore Bonaccorso Sun, 24 Feb 2013 09:27:55 +0100 + -- David Fraser Fri, 26 May 2017 14:36:32 +0000 + +isync (1.2.1-1) trusty; urgency=medium + + * New upstream release 1.2-1 (previous deb archive one 1.0.4) + + -- Steve George Thu, 18 Aug 2016 13:20:51 +0200 isync (1.0.4-2.1) unstable; urgency=low diff -Nru isync-1.1.0/debian/compat isync-1.2.1-1.812.20170514/debian/compat --- isync-1.1.0/debian/compat 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/compat 2017-05-26 14:36:31.000000000 +0000 @@ -1 +1 @@ -9 +4 diff -Nru isync-1.1.0/debian/control isync-1.2.1-1.812.20170514/debian/control --- isync-1.1.0/debian/control 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/control 2017-05-26 14:36:32.000000000 +0000 @@ -2,39 +2,33 @@ Section: mail Priority: optional Maintainer: Nicolas Boullis -Uploaders: Theodore Y. Ts'o , - Alessandro Ghedini -Standards-Version: 3.9.5 -Build-Depends: debhelper (>= 9), - dh-autoreconf, - libdb-dev, - libssl-dev -Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/isync.git -Vcs-Git: git://anonscm.debian.org/collab-maint/isync.git -Homepage: http://isync.sourceforge.net/ +Uploaders: Theodore Y. Ts'o +Standards-Version: 3.7.3 +Build-Depends: libssl-dev (>= 0.9.8), debhelper (>= 4.1.16), dpkg-dev (>= 1.9.0), libdb-dev, autoconf, automake Package: isync Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: mutt -Description: IMAP and MailDir mailbox synchronizer - mbsync/isync is a command line application which synchronizes mailboxes; - currently Maildir and IMAP4 mailboxes are supported. New messages, message - deletions and flag changes can be propagated both ways. isync is suitable - for use in IMAP-disconnected mode. +Description: Synchronize Maildir and IMAP4 mailboxes + A command line application which synchronizes mailboxes; currently + Maildir and IMAP4 mailboxes are supported. + New messages, message deletions and flag changes can be propagated both ways. + It is useful for working in disconnected mode, such as on a laptop or with a + non-permanent internet collection (dIMAP). . - The main application was much improved in version 1.0. Those improvements - lead to interface changes and the application being renamed to mbsync. The - application isync is now only a wrapper to keep compatibility with earlier - versions. + The main application was much improved in version 1.0. Those + improvements lead to interface changes and the application being + renamed to mbsync. The application isync is now only a wrapper to + keep compatibility with earlier versions. . Features: * Fine-grained selection of synchronization operations to perform * Synchronizes single mailboxes or entire mailbox collections * Partial mirrors possible: keep only the latest messages locally * Trash functionality: backup messages before removing them - IMAP features: - * Security: supports TLS/SSL via imaps: (port 993) and STARTTLS; CRAM-MD5 - for authentication - * Supports NAMESPACE for simplified configuration - * Pipelining for maximum speed (currently only partially implemented) + * IMAP features: + * Supports TLS/SSL via imaps: (port 993) and STARTTLS (RFC2595) + * Supports CRAM-MD5 (RFC2195) for authentication + * Supports NAMESPACE (RFC2342) for simplified configuration + * Pipelining for maximum speed diff -Nru isync-1.1.0/debian/copyright isync-1.2.1-1.812.20170514/debian/copyright --- isync-1.1.0/debian/copyright 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/copyright 2017-05-26 14:36:31.000000000 +0000 @@ -1,33 +1,32 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: isync -Source: http://isync.sourceforge.net +This package was debianized by Tommi Virtanen and is now +maintained by Nicolas Boullis . -Files: * -Copyright: 2000-2002, Michael R. Elkins - 2002-2004, Oswald Buddenhagen - 2004, Theodore Y. Ts'o -License: GPL-2+ +It was downloaded from http://isync.sourceforge.net/ -Files: debian/* -Copyright: 2013, Alessandro Ghedini -License: GPL-2+ +Upstream Author: Michael R. Elkins , + Oswald Buddenhagen -License: GPL-2+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - As a special exception, mbsync may be linked with the OpenSSL library, - despite that library's more restrictive license. - . - On Debian systems, the complete text of the GNU General Public License version - 2 can be found in "/usr/share/common-licenses/GPL-2". +Copyright: + + * isync - IMAP4 to maildir mailbox synchronizer + * Copyright (C) 2000-2002 Michael R. Elkins + * Copyright (C) 2002-2006 Oswald Buddenhagen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception, isync may be linked with the OpenSSL library, + * despite that library's more restrictive license. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL diff -Nru isync-1.1.0/debian/dirs isync-1.2.1-1.812.20170514/debian/dirs --- isync-1.1.0/debian/dirs 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/dirs 2017-05-26 14:36:31.000000000 +0000 @@ -0,0 +1 @@ +usr/bin diff -Nru isync-1.1.0/debian/generate-deb isync-1.2.1-1.812.20170514/debian/generate-deb --- isync-1.1.0/debian/generate-deb 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/generate-deb 2017-05-26 14:36:31.000000000 +0000 @@ -0,0 +1,39 @@ +#!/bin/sh +# +# Intended to be run from the root of the isync source tree in the repository. +# +VERSION=`dpkg-parsechangelog | sed -ne 's/^Version: \(.*\)-[^-]\+$/\1/p'` +OLDVERSION=$VERSION + +if echo $VERSION | grep +cvsXXXXXXXX; then + DATE=`date +%Y%m%d` + VERSION=`echo $VERSION | sed -e s/+cvsXXXXXXXX/+cvs${DATE}/` +else + if [ ! -f ../isync_$VERSION.orig.tar.gz ]; then + echo isync_$VERSION.orig.tar.gz must be found in the parent directory. + exit 1 + fi +fi +rm -rf ../isync-$VERSION + +fakeroot ./debian/rules clean +cp -rl . ../isync-$VERSION +cd ../isync-$VERSION +if [ "$OLDVERSION" != "$VERSION" ]; then + sed -e s/+cvsXXXXXXXX/+cvs${DATE}/ < debian/changelog > debian/changelog.new + mv debian/changelog.new debian/changelog +fi +find . -name .git -print0 | xargs -0r rm -rf +find . -name .gitignore -print0 | xargs -0r rm +find . -type l -print0 | xargs -0r rm +find . -name .#\*# -print0 | xargs -0r rm +aclocal +autoheader +automake --add-missing --copy +autoconf +if [ -n "$DOSIGN" ]; then + SIGNOPTS= +else + SIGNOPTS="-us -uc" +fi +dpkg-buildpackage -rfakeroot $SIGNOPTS diff -Nru isync-1.1.0/debian/isync.examples isync-1.2.1-1.812.20170514/debian/isync.examples --- isync-1.1.0/debian/isync.examples 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/isync.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -src/mbsyncrc.sample -src/compat/isyncrc.sample diff -Nru isync-1.1.0/debian/NEWS isync-1.2.1-1.812.20170514/debian/NEWS --- isync-1.1.0/debian/NEWS 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/NEWS 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -isync (1.0.3-1) experimental; urgency=low - - Since 1.0, isync is a wrapper around the new, more powerful, mbsync - program. The major rewrite leads to several improvements. Among them, - it is no longer needed to set the T (trash) flag to have a message be - deleted remotely. Simply removing the message now works. The (minor) - downside is that anyone expecting the old broken behavior (messaged - deleted locally being refetched) may lose some messages. - - -- Nicolas Boullis Sun, 19 Nov 2006 15:04:31 +0100 - -isync (0.8-1) unstable; urgency=low - - IMPORTANT upgrade note: - - This version includes a change to the way the UID for each message is - stored in the local mailbox. You need to remove all the messages in your - local folder if you were previously using another version of isync or else - you will end up with duplicate messages on your IMAP server. - - A suggested upgrade procedure is to use isync version 0.7 to synchronize - any local changes in isync-managed mailboxes with your IMAP server, and - then remove the contents of the local mailboxes, before upgrading to this - version. Then run isync again to pull down the mail again. You must do - this manually, the Debian package will not do this for you. - - -- Joey Hess Tue, 29 Oct 2002 13:50:40 -0500 diff -Nru isync-1.1.0/debian/patches/01_fix-manpages.patch isync-1.2.1-1.812.20170514/debian/patches/01_fix-manpages.patch --- isync-1.1.0/debian/patches/01_fix-manpages.patch 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/patches/01_fix-manpages.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: Fix typos -Origin: vendor -Forwarded: yes -Last-Update: 2014-02-13 - ---- a/src/mbsync.1 -+++ b/src/mbsync.1 -@@ -199,7 +199,7 @@ - are used as keys into a Berkeley database named .isyncuidmap.db, which holds - the UID validity as well. - .br --The \fBnative\fR scheme is faster, more space efficient, endianess independent -+The \fBnative\fR scheme is faster, more space efficient, endianness independent - and "human readable", but will be disrupted if a message is copied from another - mailbox without getting a new file name; this would result in duplicated UIDs - sooner or later, which in turn results in a UID validity change, making -@@ -439,7 +439,7 @@ - that Store is expunged. - .br - \fBFlags\fR - propagate flag changes. Note that Deleted/Trashed is a flag as --well; this is particularily interesting if you use \fBmutt\fR with the -+well; this is particularly interesting if you use \fBmutt\fR with the - maildir_trash option. - .br - \fBAll\fR (\fB--full\fR on the command line) - all of the above. diff -Nru isync-1.1.0/debian/patches/02_fix-empty-folder-sync.patch isync-1.2.1-1.812.20170514/debian/patches/02_fix-empty-folder-sync.patch --- isync-1.1.0/debian/patches/02_fix-empty-folder-sync.patch 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/patches/02_fix-empty-folder-sync.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -From 3161540ab9d4702809b9bf90a2fb39db1f3a7c9c Mon Sep 17 00:00:00 2001 -From: Oswald Buddenhagen -Date: Sat, 8 Feb 2014 13:21:28 +0100 -Subject: [PATCH] fix crash on store without prior fetch with non-UIDPLUS - servers - -we'd never initialize the message list append pointer, so -imap_find_new_msgs()'s FETCH would go awry. - -REFMAIL: <20140207101719.GB17125@mac.home> -Bug-Debian: http://bugs.debian.org/738873 ---- - src/drv_imap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/drv_imap.c b/src/drv_imap.c -index 6007e54..fbb8817 100644 ---- a/src/drv_imap.c -+++ b/src/drv_imap.c -@@ -1818,6 +1818,7 @@ imap_select( store_t *gctx, int create, - - free_generic_messages( gctx->msgs ); - gctx->msgs = 0; -+ ctx->msgapp = &gctx->msgs; - - if (prepare_box( &buf, ctx ) < 0) { - cb( DRV_BOX_BAD, aux ); -@@ -1852,7 +1853,6 @@ imap_load( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int nex - } else { - struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux ); - -- ctx->msgapp = &ctx->gen.msgs; - sort_ints( excs, nexcs ); - for (i = 0; i < nexcs; ) { - for (bl = 0; i < nexcs && bl < 960; i++) { --- -1.9.0.rc3 - diff -Nru isync-1.1.0/debian/patches/series isync-1.2.1-1.812.20170514/debian/patches/series --- isync-1.1.0/debian/patches/series 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -01_fix-manpages.patch -02_fix-empty-folder-sync.patch diff -Nru isync-1.1.0/debian/README.Debian isync-1.2.1-1.812.20170514/debian/README.Debian --- isync-1.1.0/debian/README.Debian 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/README.Debian 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -A note from isync's web site: - -isync can be integrated into Mutt fairly easily with a few hooks: - - folder-hook ~A bind index $ - folder-hook +maildir 'macro index $ "!isync -e maildir\n"' - -where maildir is the name of the local mailbox (or its alias). This works well -so long as you are not modifying the IMAP mailbox outside of Mutt. However, if -you are using another mail program simultaneously Mutt will have the wrong idea -of the local mailbox flags and messages will start disappearing from its index -display (don't worry, they are still on disk). diff -Nru isync-1.1.0/debian/rules isync-1.2.1-1.812.20170514/debian/rules --- isync-1.1.0/debian/rules 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/rules 2017-05-26 14:36:32.000000000 +0000 @@ -1,10 +1,60 @@ #!/usr/bin/make -f -%: - dh $@ --with=autoreconf +CFLAGS = -Wall -g +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) +CFLAGS += -O0 +else +CFLAGS += -O2 +endif -override_dh_auto_install: - dh_auto_install - mv $(CURDIR)/debian/isync/usr/bin/get-cert \ - $(CURDIR)/debian/isync/usr/bin/mbsync-get-cert - $(RM) $(CURDIR)/debian/isync/usr/share/doc/isync/ChangeLog +DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +build: build-stamp +build-stamp: + dh_testdir + aclocal + autoheader + autoconf + touch ./ChangeLog + automake --add-missing --copy + ./configure --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE) --prefix=/usr --mandir=/usr/share/man + $(MAKE) CFLAGS="$(CFLAGS)" + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + [ ! -f Makefile ] || $(MAKE) distclean + dh_clean Makefile config.log config.status + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs usr/bin usr/share/man/man1 + $(MAKE) DESTDIR=$(CURDIR)/debian/isync install + rm -r $(CURDIR)/debian/isync/usr/share/doc + mv $(CURDIR)/debian/isync/usr/bin/get-cert $(CURDIR)/debian/isync/usr/bin/mbsync-get-cert + +binary-indep: build install + +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs ChangeLog + dh_installdocs AUTHORS NEWS README TODO + dh_installexamples src/mbsyncrc.sample src/compat/isyncrc.sample + dh_installman + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff -Nru isync-1.1.0/debian/source/format isync-1.2.1-1.812.20170514/debian/source/format --- isync-1.1.0/debian/source/format 2014-02-14 19:41:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/debian/source/format 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -3.0 (quilt) diff -Nru isync-1.1.0/depcomp isync-1.2.1-1.812.20170514/depcomp --- isync-1.1.0/depcomp 2013-12-18 21:09:58.000000000 +0000 +++ isync-1.2.1-1.812.20170514/depcomp 1970-01-01 00:00:00.000000000 +0000 @@ -1,791 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2013-05-30.07; # UTC - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by 'PROGRAMS ARGS'. - object Object file output by 'PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputting dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -# Get the directory component of the given path, and save it in the -# global variables '$dir'. Note that this directory component will -# be either empty or ending with a '/' character. This is deliberate. -set_dir_from () -{ - case $1 in - */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; - *) dir=;; - esac -} - -# Get the suffix-stripped basename of the given path, and save it the -# global variable '$base'. -set_base_from () -{ - base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` -} - -# If no dependency file was actually created by the compiler invocation, -# we still have to create a dummy depfile, to avoid errors with the -# Makefile "include basename.Plo" scheme. -make_dummy_depfile () -{ - echo "#dummy" > "$depfile" -} - -# Factor out some common post-processing of the generated depfile. -# Requires the auxiliary global variable '$tmpdepfile' to be set. -aix_post_process_depfile () -{ - # If the compiler actually managed to produce a dependency file, - # post-process it. - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependency.h'. - # Do two passes, one to just change these to - # $object: dependency.h - # and one to simply output - # dependency.h: - # which is needed to avoid the deleted-header problem. - { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" - sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" - } > "$depfile" - rm -f "$tmpdepfile" - else - make_dummy_depfile - fi -} - -# A tabulation character. -tab=' ' -# A newline character. -nl=' -' -# Character ranges might be problematic outside the C locale. -# These definitions help. -upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ -lower=abcdefghijklmnopqrstuvwxyz -digits=0123456789 -alpha=${upper}${lower} - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Avoid interferences from the environment. -gccflag= dashmflag= - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -cygpath_u="cygpath -u -f -" -if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp -fi - -if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 -fi - -if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. - gccflag=-qmakedep=gcc,-MF - depmode=gcc -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. -## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. -## (see the conditional assignment to $gccflag above). -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). Also, it might not be -## supported by the other compilers which use the 'gcc' depmode. -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The second -e expression handles DOS-style file names with drive - # letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the "deleted header file" problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. -## Some versions of gcc put a space before the ':'. On the theory -## that the space means something, we add a space to the output as -## well. hp depmode also adds that space, but also prefixes the VPATH -## to the object. Take care to not repeat it in the output. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like '#:fec' to the end of the - # dependency line. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ - | tr "$nl" ' ' >> "$depfile" - echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" - else - make_dummy_depfile - fi - rm -f "$tmpdepfile" - ;; - -xlc) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts '$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - set_dir_from "$object" - set_base_from "$object" - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - aix_post_process_depfile - ;; - -tcc) - # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 - # FIXME: That version still under development at the moment of writing. - # Make that this statement remains true also for stable, released - # versions. - # It will wrap lines (doesn't matter whether long or short) with a - # trailing '\', as in: - # - # foo.o : \ - # foo.c \ - # foo.h \ - # - # It will put a trailing '\' even on the last line, and will use leading - # spaces rather than leading tabs (at least since its commit 0394caf7 - # "Emit spaces for -MD"). - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. - # We have to change lines of the first kind to '$object: \'. - sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" - # And for each line of the second kind, we have to emit a 'dep.h:' - # dummy dependency, to avoid the deleted-header problem. - sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" - rm -f "$tmpdepfile" - ;; - -## The order of this option in the case statement is important, since the -## shell code in configure will try each of these formats in the order -## listed in this file. A plain '-MD' option would be understood by many -## compilers, so we must ensure this comes after the gcc and icc options. -pgcc) - # Portland's C compiler understands '-MD'. - # Will always output deps to 'file.d' where file is the root name of the - # source file under compilation, even if file resides in a subdirectory. - # The object file name does not affect the name of the '.d' file. - # pgcc 10.2 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\' : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - set_dir_from "$object" - # Use the source, not the object, to determine the base name, since - # that's sadly what pgcc will do too. - set_base_from "$source" - tmpdepfile=$base.d - - # For projects that build the same source file twice into different object - # files, the pgcc approach of using the *source* file root name can cause - # problems in parallel builds. Use a locking strategy to avoid stomping on - # the same $tmpdepfile. - lockdir=$base.d-lock - trap " - echo '$0: caught signal, cleaning up...' >&2 - rmdir '$lockdir' - exit 1 - " 1 2 13 15 - numtries=100 - i=$numtries - while test $i -gt 0; do - # mkdir is a portable test-and-set. - if mkdir "$lockdir" 2>/dev/null; then - # This process acquired the lock. - "$@" -MD - stat=$? - # Release the lock. - rmdir "$lockdir" - break - else - # If the lock is being held by a different process, wait - # until the winning process is done or we timeout. - while test -d "$lockdir" && test $i -gt 0; do - sleep 1 - i=`expr $i - 1` - done - fi - i=`expr $i - 1` - done - trap - 1 2 13 15 - if test $i -le 0; then - echo "$0: failed to acquire lock after $numtries attempts" >&2 - echo "$0: check lockdir '$lockdir'" >&2 - exit 1 - fi - - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - set_dir_from "$object" - set_base_from "$object" - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" - # Add 'dependent.h:' lines. - sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" - else - make_dummy_depfile - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - set_dir_from "$object" - set_base_from "$object" - - if test "$libtool" = yes; then - # Libtool generates 2 separate objects for the 2 libraries. These - # two compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir$base.o.d # libtool 1.5 - tmpdepfile2=$dir.libs/$base.o.d # Likewise. - tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - # Same post-processing that is required for AIX mode. - aix_post_process_depfile - ;; - -msvc7) - if test "$libtool" = yes; then - showIncludes=-Wc,-showIncludes - else - showIncludes=-showIncludes - fi - "$@" $showIncludes > "$tmpdepfile" - stat=$? - grep -v '^Note: including file: ' "$tmpdepfile" - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The first sed program below extracts the file names and escapes - # backslashes for cygpath. The second sed program outputs the file - # name when reading, but also accumulates all include files in the - # hold buffer in order to output them again at the end. This only - # works with sed implementations that can handle large buffers. - sed < "$tmpdepfile" -n ' -/^Note: including file: *\(.*\)/ { - s//\1/ - s/\\/\\\\/g - p -}' | $cygpath_u | sort -u | sed -n ' -s/ /\\ /g -s/\(.*\)/'"$tab"'\1 \\/p -s/.\(.*\) \\/\1:/ -H -$ { - s/.*/'"$tab"'/ - G - p -}' >> "$depfile" - echo >> "$depfile" # make sure the fragment doesn't end with a backslash - rm -f "$tmpdepfile" - ;; - -msvc7msys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for ':' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. - "$@" $dashmflag | - sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this sed invocation - # correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no eat=no - for arg - do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - if test $eat = yes; then - eat=no - continue - fi - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -arch) - eat=yes ;; - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix=`echo "$object" | sed 's/^.*\././'` - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - # makedepend may prepend the VPATH from the source file name to the object. - # No need to regex-escape $object, excess matching of '.' is harmless. - sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process the last invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed '1,2d' "$tmpdepfile" \ - | tr ' ' "$nl" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E \ - | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - | sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - IFS=" " - for arg - do - case "$arg" in - -o) - shift - ;; - $object) - shift - ;; - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E 2>/dev/null | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" - echo "$tab" >> "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvcmsys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff -Nru isync-1.1.0/INSTALL isync-1.2.1-1.812.20170514/INSTALL --- isync-1.1.0/INSTALL 2013-12-18 21:09:58.000000000 +0000 +++ isync-1.2.1-1.812.20170514/INSTALL 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, -Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: - - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. diff -Nru isync-1.1.0/install-sh isync-1.2.1-1.812.20170514/install-sh --- isync-1.1.0/install-sh 2013-12-18 21:09:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/install-sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,527 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2011-11-20.07; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff -Nru isync-1.1.0/isync.spec isync-1.2.1-1.812.20170514/isync.spec --- isync-1.1.0/isync.spec 2013-12-18 21:10:05.000000000 +0000 +++ isync-1.2.1-1.812.20170514/isync.spec 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -Summary: Utility to synchronize IMAP mailboxes with local maildir folders -Name: isync -Version: 1.1.0 -Release: 1 -License: GPL -Group: Applications/Internet -Source: isync-1.1.0.tar.gz -URL: http://isync.sf.net/ -Packager: Oswald Buddenhagen -BuildRoot: /var/tmp/%{name}-buildroot - -%description -isync is a command line utility which synchronizes mailboxes; currently -Maildir and IMAP4 mailboxes are supported. -New messages, message deletions and flag changes can be propagated both ways. -It is useful for working in disconnected mode, such as on a laptop or with a -non-permanent internet collection (dIMAP). - -%prep -%setup -%build -%configure - -%install -rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT install -rm -rf $RPM_BUILD_ROOT%{_docdir}/%{name} - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%doc AUTHORS COPYING NEWS README TODO ChangeLog src/mbsyncrc.sample src/compat/isyncrc.sample -%{_bindir}/* -%{_mandir}/man1/* diff -Nru isync-1.1.0/Makefile.am isync-1.2.1-1.812.20170514/Makefile.am --- isync-1.1.0/Makefile.am 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/Makefile.am 2017-05-26 14:36:31.000000000 +0000 @@ -51,9 +51,13 @@ log: @test -z "$(srcdir)" || cd $(srcdir) && \ ( ! test -d .git || \ - git log --date=iso --log-size --name-only | \ + git log --pretty=medium --date=iso --log-size --name-only --no-merges | \ perl -e '$(LOG_PL)' > ChangeLog ) +cov-scan: clean + /opt/cov-analysis-*/bin/cov-build --dir cov-int $(MAKE) + tar cavf isync.tar.xz cov-int + deb: deb-clean CFLAGS= fakeroot debian/rules binary diff -Nru isync-1.1.0/Makefile.in isync-1.2.1-1.812.20170514/Makefile.in --- isync-1.1.0/Makefile.in 2013-12-18 21:09:58.000000000 +0000 +++ isync-1.2.1-1.812.20170514/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,930 +0,0 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ - $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/autodefs.h.in $(srcdir)/isync.spec.in COPYING TODO \ - compile depcomp install-sh missing -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = autodefs.h -CONFIG_CLEAN_FILES = isync.spec -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" -SCRIPTS = $(bin_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -DATA = $(doc_DATA) -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)autodefs.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKGCONFIG = @PKGCONFIG@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SOCK_LIBS = @SOCK_LIBS@ -SSL_LIBS = @SSL_LIBS@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -SUBDIRS = src -bin_SCRIPTS = get-cert -EXTRA_DIST = debian isync.spec $(bin_SCRIPTS) -LOG_PL = \ - use POSIX qw(strftime); \ - use Date::Parse; \ - use Text::Wrap; \ - $$Text::Wrap::columns = 72; \ - while (defined($$_ = <>)) { \ - /^commit / or die "commit missing: $$_"; \ - <> =~ /^log size (\d+)$$/ or die "wrong size"; \ - $$len = $$1; \ - read(STDIN, $$log, $$len) == $$len or die "unexpected EOF"; \ - $$log =~ s/^Author: ([^>]+>)\nDate: (\d{4}-\d\d-\d\d \d\d:\d\d:\d\d [-+]\d{4})\n(.*)$$/$$3/s or die "unexpected log format"; \ - $$author = $$1; $$date = str2time($$2); \ - scalar(<>); \ - @files = (); \ - $$pfx = ""; \ - while (defined($$l = <>) and $$l ne "\n") { \ - chomp $$l; \ - next if ($$l =~ m,^(ChangeLog$$|NEWS$$|TODO$$|debian/),); \ - if (!@files) { \ - $$pfx = $$l; \ - $$pfx =~ s,/?[^/]+$$,,; \ - } else { \ - while (length($$pfx)) { \ - $$l =~ m,^\Q$$pfx/\E, and last; \ - $$pfx =~ s,/?[^/]+$$,,; \ - } \ - } \ - push @files, $$l; \ - } \ - next if (!@files); \ - print strftime("%F %H:%M", gmtime($$date))." ".$$author."\n\n"; \ - if (@files > 1 and ($$len = length($$pfx))) { \ - @efiles = (); \ - for $$f (@files) { push @efiles, substr($$f, $$len + 1); } \ - $$fstr = $$pfx."/: "; \ - } else { \ - @efiles = @files; \ - $$fstr = ""; \ - } \ - print wrap("\t* ", "\t ", $$fstr.join(", ", @efiles).":")."\n"; \ - $$log =~ s, +$$,,gm; \ - $$log =~ s,^ ,\t,gm; \ - print $$log."\n"; \ - } - -doc_DATA = README TODO NEWS ChangeLog AUTHORS -all: autodefs.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -.SUFFIXES: -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -autodefs.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/autodefs.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status autodefs.h -$(srcdir)/autodefs.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f autodefs.h stamp-h1 -isync.spec: $(top_builddir)/config.status $(srcdir)/isync.spec.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -install-binSCRIPTS: $(bin_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) -install-docDATA: $(doc_DATA) - @$(NORMAL_INSTALL) - @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ - done - -uninstall-docDATA: - @$(NORMAL_UNINSTALL) - @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile $(SCRIPTS) $(DATA) autodefs.h -installdirs: installdirs-recursive -installdirs-am: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-hdr distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: install-docDATA - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: install-binSCRIPTS - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: uninstall-binSCRIPTS uninstall-docDATA - -.MAKE: $(am__recursive_targets) all install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-am clean clean-cscope clean-generic \ - cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ - dist-zip distcheck distclean distclean-generic distclean-hdr \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-binSCRIPTS install-data install-data-am \ - install-docDATA install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-binSCRIPTS uninstall-docDATA - - -$(srcdir)/ChangeLog: log -log: - @test -z "$(srcdir)" || cd $(srcdir) && \ - ( ! test -d .git || \ - git log --date=iso --log-size --name-only | \ - perl -e '$(LOG_PL)' > ChangeLog ) - -deb: deb-clean - CFLAGS= fakeroot debian/rules binary - -deb-clean: - dh_clean -Xsrc/ - fakeroot debian/rules clean - -dist-hook: - find $(distdir)/debian \( -name .#\*# -o -type l \) -print0 | xargs -0r rm -rf - -cd $(distdir)/debian && test -f .gitignore && rm -rf `cat .gitignore` .gitignore - -dist-sign: dist - gpg -b -a $(PACKAGE)-$(VERSION).tar.gz - -rpm: dist - CFLAGS="-O2 -mtune=core2" rpmbuild --clean -ta $(PACKAGE)-$(VERSION).tar.gz - -rpm-ia32: dist - CFLAGS="-O2 -m32 -march=i686" rpmbuild --target i686-unknown-linux --clean -ta $(PACKAGE)-$(VERSION).tar.gz - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff -Nru isync-1.1.0/missing isync-1.2.1-1.812.20170514/missing --- isync-1.1.0/missing 2013-12-18 21:09:57.000000000 +0000 +++ isync-1.2.1-1.812.20170514/missing 1970-01-01 00:00:00.000000000 +0000 @@ -1,215 +0,0 @@ -#! /bin/sh -# Common wrapper for a few potentially missing GNU programs. - -scriptversion=2012-06-26.16; # UTC - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" - exit 1 -fi - -case $1 in - - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; - - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man - -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" - exit 1 - ;; - -esac - -# Run the given program, remember its exit status. -"$@"; st=$? - -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi - -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'automa4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" - ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} - -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 - -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff -Nru isync-1.1.0/NEWS isync-1.2.1-1.812.20170514/NEWS --- isync-1.1.0/NEWS 2013-12-15 12:46:25.000000000 +0000 +++ isync-1.2.1-1.812.20170514/NEWS 2017-05-26 14:36:31.000000000 +0000 @@ -1,3 +1,35 @@ +[1.3.0] + +Network timeout handling has been added. + +A Maildir sub-folder naming style without extra dots has been added. + +Support for TLS client certificates was added. + +Support for recovering from baseless UID validity changes was added. + +[1.2.0] + +The 'isync' compatibility wrapper is now deprecated. + +An IMAP Path/NAMESPACE rooted in INBOX won't be handled specially any more. +This means that some Patterns may need adjustment. + +The default output is a lot less verbose now. +The meanings of the -V and -D options changed significantly. + +The SSL/TLS configuration has been re-designed. +SSL is now explicitly enabled or disabled - "use SSL if available" is gone. +Notice: Tunnels are assumed to be secure and thus default to no SSL. + +Support for SASL (flexible authentication) has been added. + +Support for Windows file systems has been added. + +Support for compressed data transfer has been added. + +Folder deletions can be propagated now. + [1.1.0] Support for hierarchical mailboxes in Patterns. diff -Nru isync-1.1.0/README isync-1.2.1-1.812.20170514/README --- isync-1.1.0/README 2013-12-15 12:46:25.000000000 +0000 +++ isync-1.2.1-1.812.20170514/README 2017-05-26 14:36:31.000000000 +0000 @@ -14,11 +14,13 @@ deletions and flag changes can be propagated both ways. ``mbsync'' is suitable for use in IMAP-disconnected mode. -Synchronization is based on unique message identifiers (UIDs), so no -identification conflicts can occur (as opposed to some other mail +Synchronization is based on unique message identifiers (UIDs), so +no identification conflicts can occur (unlike with some other mail synchronizers). Synchronization state is kept in one local text file per mailbox pair; -multiple replicas of a mailbox can be maintained. +these files are protected against concurrent ``mbsync'' processes. +Mailboxes can be safely modified while ``mbsync'' operates. +Multiple replicas of each mailbox can be maintained. isync is the project name, while mbsync is the current executable name; this change was necessary because of massive changes in the user interface. An @@ -31,9 +33,8 @@ * Partial mirrors possible: keep only the latest messages locally * Trash functionality: backup messages before removing them * IMAP features: - * Supports TLS/SSL via imaps: (port 993) and STARTTLS (RFC2595) - * Supports CRAM-MD5 (RFC2195) for authentication - * Supports NAMESPACE (RFC2342) for simplified configuration + * Supports TLS/SSL via imaps: (port 993) and STARTTLS + * Supports SASL for authentication * Pipelining for maximum speed * Compatibility @@ -44,28 +45,20 @@ Courier 1.4.3 is known to be buggy, version 1.7.3 works fine. - c-client (UW-IMAP, Pine) is mostly fine, but versions less than 2004a.352 - tend to change UIDVALIDITY pretty often when used with unix/mbox mailboxes, - making isync refuse synchronization. - M$ Exchange (up to 2010 at least) occasionally exposes the same problem. - The "cure" is to simply copy the new UIDVALIDITY from the affected - mailbox to mbsync's state file. This is a Bad Hack (TM), but it works - - use at your own risk (if the UIDVALIDITY change was genuine, this will - delete all messages in the affected mailbox - not that this ever - happened to me). + M$ Exchange (2013 at least) needs DisableExtension MOVE to be compatible + with the Trash functionality. * Platforms At some point, ``isync'' has successfully run on: Linux, Solaris 2.7, OpenBSD 2.8, FreeBSD 4.3. - Note that Cygwin cannot be reasonably supported due to restrictions - of the Windows file system. - * Requirements - Berkley DB 4.2+ + Berkeley DB 4.1+ (optional) OpenSSL for TLS/SSL support (optional) + Cyrus SASL (optional) + zlib (optional) * Installation diff -Nru isync-1.1.0/src/common.h isync-1.2.1-1.812.20170514/src/common.h --- isync-1.1.0/src/common.h 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/common.h 2017-05-26 14:36:31.000000000 +0000 @@ -28,20 +28,30 @@ #include #include #include +#include + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; #define as(ar) (sizeof(ar)/sizeof(ar[0])) #define __stringify(x) #x #define stringify(x) __stringify(x) +#define shifted_bit(in, from, to) \ + (((uint)(in) / (from > to ? from / to : 1) * (to > from ? to / from : 1)) & to) + #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) # define ATTR_UNUSED __attribute__((unused)) # define ATTR_NORETURN __attribute__((noreturn)) # define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) +# define ATTR_PACKED(ref) __attribute__((packed,aligned(sizeof(ref)))) #else # define ATTR_UNUSED # define ATTR_NORETURN # define ATTR_PRINTFLIKE(fmt,var) +# define ATTR_PACKED(ref) #endif #ifdef __GNUC__ @@ -54,28 +64,47 @@ /* main.c */ -#define DEBUG 1 -#define VERBOSE 2 -#define XVERBOSE 4 -#define QUIET 8 -#define VERYQUIET 16 -#define KEEPJOURNAL 32 -#define ZERODELAY 64 -#define CRASHDEBUG 128 +#define DEBUG_CRASH 0x01 +#define DEBUG_MAILDIR 0x02 +#define DEBUG_NET 0x04 +#define DEBUG_NET_ALL 0x08 +#define DEBUG_SYNC 0x10 +#define DEBUG_MAIN 0x20 +#define DEBUG_DRV 0x40 +#define DEBUG_DRV_ALL 0x80 +#define DEBUG_ALL (0xFF & ~(DEBUG_NET_ALL | DEBUG_DRV_ALL)) +#define QUIET 0x100 +#define VERYQUIET 0x200 +#define PROGRESS 0x400 +#define VERBOSE 0x800 +#define KEEPJOURNAL 0x1000 +#define ZERODELAY 0x2000 extern int DFlags; +extern int JLimit; extern int UseFSync; +extern char FieldDelimiter; extern int Pid; extern char Hostname[256]; extern const char *Home; +extern int BufferLimit; + +extern int new_total[2], new_done[2]; +extern int flags_total[2], flags_done[2]; +extern int trash_total[2], trash_done[2]; + +void stats( void ); + /* util.c */ -void ATTR_PRINTFLIKE(1, 2) debug( const char *, ... ); -void ATTR_PRINTFLIKE(1, 2) debugn( const char *, ... ); +void vdebug( int, const char *, va_list va ); +void vdebugn( int, const char *, va_list va ); void ATTR_PRINTFLIKE(1, 2) info( const char *, ... ); void ATTR_PRINTFLIKE(1, 2) infon( const char *, ... ); +void ATTR_PRINTFLIKE(1, 2) progress( const char *, ... ); +void ATTR_PRINTFLIKE(1, 2) notice( const char *, ... ); void ATTR_PRINTFLIKE(1, 2) warn( const char *, ... ); void ATTR_PRINTFLIKE(1, 2) error( const char *, ... ); void ATTR_PRINTFLIKE(1, 2) sys_error( const char *, ... ); @@ -84,7 +113,7 @@ typedef struct string_list { struct string_list *next; char string[1]; -} string_list_t; +} ATTR_PACKED(void *) string_list_t; void add_string_list_n( string_list_t **list, const char *str, int len ); void add_string_list( string_list_t **list, const char *str ); @@ -93,10 +122,22 @@ #ifndef HAVE_MEMRCHR void *memrchr( const void *s, int c, size_t n ); #endif +#ifndef HAVE_STRNLEN +size_t strnlen( const char *str, size_t maxlen ); +#endif + +int starts_with( const char *str, int strl, const char *cmp, int cmpl ); +int starts_with_upper( const char *str, int strl, const char *cmp, int cmpl ); +int equals( const char *str, int strl, const char *cmp, int cmpl ); + +#ifndef HAVE_TIMEGM +time_t timegm( struct tm *tm ); +#endif void *nfmalloc( size_t sz ); void *nfcalloc( size_t sz ); void *nfrealloc( void *mem, size_t sz ); +char *nfstrndup( const char *str, size_t nchars ); char *nfstrdup( const char *str ); int nfvasprintf( char **str, const char *fmt, va_list va ); int ATTR_PRINTFLIKE(2, 3) nfasprintf( char **str, const char *fmt, ... ); @@ -107,13 +148,56 @@ int map_name( const char *arg, char **result, int reserve, const char *in, const char *out ); -void sort_ints( int *arr, int len ); +#define DEFINE_ARRAY_TYPE(T) \ + typedef struct { \ + T *data; \ + int size; \ + } ATTR_PACKED(T *) T##_array_t; \ + typedef struct { \ + T##_array_t array; \ + int alloc; \ + } ATTR_PACKED(T *) T##_array_alloc_t; \ + static INLINE T *T##_array_append( T##_array_alloc_t *arr ) \ + { \ + if (arr->array.size == arr->alloc) { \ + arr->alloc = arr->alloc * 2 + 100; \ + arr->array.data = nfrealloc( arr->array.data, arr->alloc * sizeof(T) ); \ + } \ + return &arr->array.data[arr->array.size++]; \ + } + +#define ARRAY_INIT(arr) \ + do { (arr)->array.data = 0; (arr)->array.size = (arr)->alloc = 0; } while (0) + +#define ARRAY_SQUEEZE(arr) \ + do { \ + (arr)->data = nfrealloc( (arr)->data, (arr)->size * sizeof((arr)->data[0]) ); \ + } while (0) + +DEFINE_ARRAY_TYPE(uint) +void sort_uint_array( uint_array_t array ); +int find_uint_array( const uint_array_t array, uint value ); void arc4_init( void ); -unsigned char arc4_getbyte( void ); +uchar arc4_getbyte( void ); int bucketsForSize( int size ); +typedef struct list_head { + struct list_head *next, *prev; +} list_head_t; + +typedef struct notifier { + struct notifier *next; + void (*cb)( int what, void *aux ); + void *aux; +#ifdef HAVE_SYS_POLL_H + int index; +#else + int fd, events; +#endif +} notifier_t; + #ifdef HAVE_SYS_POLL_H # include #else @@ -122,10 +206,22 @@ # define POLLERR 8 #endif -void add_fd( int fd, void (*cb)( int events, void *aux ), void *aux ); -void conf_fd( int fd, int and_events, int or_events ); -void fake_fd( int fd, int events ); -void del_fd( int fd ); +void init_notifier( notifier_t *sn, int fd, void (*cb)( int, void * ), void *aux ); +void conf_notifier( notifier_t *sn, int and_events, int or_events ); +void wipe_notifier( notifier_t *sn ); + +typedef struct { + list_head_t links; + void (*cb)( void *aux ); + void *aux; + time_t timeout; +} wakeup_t; + +void init_wakeup( wakeup_t *tmr, void (*cb)( void * ), void *aux ); +void conf_wakeup( wakeup_t *tmr, int timeout ); +void wipe_wakeup( wakeup_t *tmr ); +static INLINE int pending_wakeup( wakeup_t *tmr ) { return tmr->links.next != 0; } + void main_loop( void ); #endif diff -Nru isync-1.1.0/src/compat/config.c isync-1.2.1-1.812.20170514/src/compat/config.c --- isync-1.1.0/src/compat/config.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/config.c 2017-05-26 14:36:31.000000000 +0000 @@ -27,8 +27,7 @@ #include #include #include - -static int local_home, local_root; +#include static char * my_strndup( const char *s, size_t nchars ) @@ -120,16 +119,6 @@ cfg = **stor = nfmalloc( sizeof(config_t) ); *stor = &cfg->next; memcpy( cfg, &global, sizeof(config_t) ); - if (val[0] == '~' && val[1] == '/') { - val += 2; - local_home = 1; - } else if (!memcmp( val, Home, HomeLen ) && val[HomeLen] == '/') { - val += HomeLen + 1; - local_home = 1; - } else if (val[0] == '/') - local_root = 1; - else - local_home = 1; /* not expanded at this point */ cfg->path = nfstrdup( val ); } else if (!strcasecmp( "OneToOne", cmd )) { @@ -155,7 +144,7 @@ goto forbid; inbox = nfstrdup( val ); } else if (!strcasecmp( "Host", cmd )) { - if (!memcmp( "imaps:", val, 6 )) { + if (starts_with( val, -1, "imaps:", 6 )) { val += 6; cfg->use_imaps = 1; cfg->port = 993; @@ -234,6 +223,21 @@ return on ? "yes" : "no"; } +static const char * +quotify( const char *str ) +{ + char *ostr; + int i; + + for (i = 0; str[i]; i++) { + if (isspace( str[i] )) { + nfasprintf( &ostr, "\"%s\"", str ); + return ostr; + } + } + return str; +} + static void write_imap_server( FILE *fp, config_t *cfg ) { @@ -243,9 +247,11 @@ char buf[128], ubuf[64]; static int tunnels; + /* The old server names determine the derived store names. They are kinda stupid, + * but can't be changed, because store names are encoded in state file names. */ if (cfg->tunnel) nfasprintf( (char **)&cfg->old_server_name, "tunnel%d", ++tunnels ); - else if (cfg->host) { + else { if (sscanf( cfg->host, "%d.%d.%d.%d", &a1, &a2, &a3, &a4 ) == 4) hl = nfsnprintf( buf, sizeof(buf), "%s", cfg->host ); else { @@ -262,18 +268,17 @@ } if (boxes) /* !o2o */ for (pbox = boxes; pbox != cfg; pbox = pbox->next) - if (!memcmp( pbox->server_name, buf, hl + 1 )) { + if (equals( pbox->old_server_name, -1, buf, hl )) { nfasprintf( (char **)&cfg->old_server_name, "%s-%d", buf, ++pbox->old_servers ); goto gotsrv; } cfg->old_server_name = nfstrdup( buf ); cfg->old_servers = 1; gotsrv: ; - } else { - fprintf( stderr, "ERROR: Neither host nor tunnel specified for mailbox %s.\n", cfg->path ); - exit( 1 ); } + /* The "new" server names determine the names of the accounts themselves. + * They are optimized for descriptiveness, e.g. in password prompts. */ if (cfg->user) nfsnprintf( ubuf, sizeof(ubuf), "%s@", cfg->user ); else @@ -288,7 +293,7 @@ } if (boxes) /* !o2o */ for (pbox = boxes; pbox != cfg; pbox = pbox->next) - if (!memcmp( pbox->server_name, buf, hl + 1 )) { + if (equals( pbox->server_name, -1, buf, hl )) { nfasprintf( (char **)&cfg->server_name, "%s-%d", buf, ++pbox->servers ); goto ngotsrv; } @@ -307,16 +312,16 @@ fprintf( fp, "Port %d\n", cfg->port ); } if (cfg->user) - fprintf( fp, "User \"%s\"\n", cfg->user ); + fprintf( fp, "User %s\n", quotify( cfg->user ) ); if (cfg->pass) - fprintf( fp, "Pass \"%s\"\n", cfg->pass ); + fprintf( fp, "Pass %s\n", quotify( cfg->pass ) ); fprintf( fp, "RequireCRAM %s\nRequireSSL %s\n" "UseSSLv2 %s\nUseSSLv3 %s\nUseTLSv1 %s\n", tb(cfg->require_cram), tb(cfg->require_ssl), tb(cfg->use_sslv2), tb(cfg->use_sslv3), tb(cfg->use_tlsv1) ); if ((cfg->use_imaps || cfg->use_sslv2 || cfg->use_sslv3 || cfg->use_tlsv1) && cfg->cert_file) - fprintf( fp, "CertificateFile %s\n", cfg->cert_file ); + fprintf( fp, "CertificateFile %s\n", quotify( cfg->cert_file ) ); fputc( '\n', fp ); } @@ -330,13 +335,13 @@ fprintf( fp, "IMAPStore %s\nAccount %s\n", cfg->store_name, cfg->server_name ); if (*folder) - fprintf( fp, "Path \"%s\"\n", folder ); + fprintf( fp, "Path %s\n", quotify( folder ) ); else fprintf( fp, "UseNamespace %s\n", tb(cfg->use_namespace) ); if (inbox) - fprintf( fp, "MapInbox \"%s\"\n", inbox ); + fprintf( fp, "MapInbox %s\n", quotify( inbox ) ); if (cfg->copy_deleted_to) - fprintf( fp, "Trash \"%s\"\n", cfg->copy_deleted_to ); + fprintf( fp, "Trash %s\n", quotify( cfg->copy_deleted_to ) ); fputc( '\n', fp ); } @@ -347,9 +352,9 @@ fprintf( fp, "MaxSize %d\n", cfg->max_size ); if (cfg->max_messages) fprintf( fp, "MaxMessages %d\n", cfg->max_messages ); - if (!cfg->delete && !delete) - fputs( "Sync New ReNew Flags\n", fp ); - if (cfg->expunge || expunge) + if (cfg->delete && !global.delete && !delete) + fputs( "Sync All\n", fp ); + if (cfg->expunge && !global.expunge && !expunge) fputs( "Expunge Both\n", fp ); fputc( '\n', fp ); } @@ -369,23 +374,32 @@ { FILE *fp; const char *cn, *scn; + char *path, *local_box, *local_store; config_t *box, *sbox, *pbox; + int pl; if (!(fp = fdopen( fd, "w" ))) { perror( "fdopen" ); return; } - fprintf( fp, "SyncState *\n\n" ); - if (local_home || o2o) - fprintf( fp, "MaildirStore local\nPath \"%s/\"\nInbox \"%s/INBOX\"\nAltMap %s\n\n", - maildir, maildir, tb( altmap > 0 ) ); - if (local_root) - fprintf( fp, "MaildirStore local_root\nPath /\nAltMap %s\n\n", tb( altmap > 0 ) ); + fputs( "SyncState *\n", fp ); + if (!global.delete && !delete) + fputs( "Sync New ReNew Flags\n", fp ); + if (global.expunge || expunge) + fputs( "Expunge Both\n", fp ); + fputc( '\n', fp ); if (o2o) { write_imap_server( fp, &global ); write_imap_store( fp, &global ); - fprintf( fp, "Channel o2o\nMaster :%s:\nSlave :local:\nPattern %%\n", global.store_name ); + fprintf( fp, "MaildirStore local\nPath %s/\n", quotify( maildir ) ); + if (!inbox) { /* just in case listing actually produces an INBOX ... */ + nfasprintf( (char **)&inbox, "%s/INBOX", maildir ); + fprintf( fp, "Inbox %s\n", quotify( inbox ) ); + } + if (altmap > 0) + fputs( "AltMap yes\n", fp ); + fprintf( fp, "\nChannel o2o\nMaster :%s:\nSlave :local:\nPattern %%\n", global.store_name ); write_channel_parm( fp, &global ); } else { for (box = boxes; box; box = box->next) { @@ -428,6 +442,55 @@ gotsrv: write_imap_store( fp, box ); gotall: + + path = expand_strdup( box->path ); + if (starts_with( path, -1, Home, HomeLen ) && path[HomeLen] == '/') + nfasprintf( &path, "~%s", path + HomeLen ); + local_store = local_box = strrchr( path, '/' ) + 1; + pl = local_store - path; + /* try to re-use existing store */ + for (pbox = boxes; pbox != box; pbox = pbox->next) + if (pbox->local_store_path && equals( pbox->local_store_path, -1, path, pl )) + goto gotstor; + box->local_store_path = my_strndup( path, pl ); + /* derive a suitable name */ + if (!strcmp( box->local_store_path, "/var/mail/" ) || !strcmp( box->local_store_path, "/var/spool/mail/" )) { + local_store = nfstrdup( "spool" ); + } else if (!strcmp( box->local_store_path, "~/" )) { + local_store = nfstrdup( "home" ); + } else { + local_store = memrchr( box->local_store_path, '/', pl - 1 ); + if (local_store) { + local_store = my_strndup( local_store + 1, pl - 2 - (local_store - box->local_store_path) ); + for (pl = 0; local_store[pl]; pl++) + local_store[pl] = tolower( local_store[pl] ); + } else { + local_store = nfstrdup( "local" ); + } + } + /* avoid name clashes with imap stores */ + for (pbox = boxes; pbox != box; pbox = pbox->next) + if (!strcmp( pbox->store_name, local_store )) { + nfasprintf( &local_store, "local_%s", local_store ); + goto gotsdup; + } + gotsdup: + /* avoid name clashes with other local stores */ + for (pbox = boxes; pbox != box; pbox = pbox->next) + if (pbox->local_store_name && !strcmp( pbox->local_store_name, local_store )) { + nfasprintf( (char **)&box->local_store_name, "%s-%d", local_store, ++pbox->local_stores ); + goto gotdup; + } + box->local_store_name = local_store; + box->local_stores = 1; + gotdup: + fprintf( fp, "MaildirStore %s\nPath %s\n", box->local_store_name, quotify( box->local_store_path ) ); + if (altmap > 0) + fputs( "AltMap yes\n", fp ); + fputc( '\n', fp ); + pbox = box; + gotstor: + if (box->alias) cn = box->alias; else { @@ -455,12 +518,9 @@ box->channels = 1; box->channel_name = cn; gotchan: - if (box->path[0] == '/') - fprintf( fp, "Channel %s\nMaster :%s:\"%s\"\nSlave :local_root:\"%s\"\n", - box->channel_name, box->store_name, box->box, box->path + 1 ); - else - fprintf( fp, "Channel %s\nMaster :%s:\"%s\"\nSlave :local:\"%s\"\n", - box->channel_name, box->store_name, box->box, box->path ); + + fprintf( fp, "Channel %s\nMaster :%s:%s\nSlave :%s:%s\n", + box->channel_name, box->store_name, quotify( box->box ), pbox->local_store_name, quotify( local_box ) ); write_channel_parm( fp, box ); } @@ -475,7 +535,7 @@ config_t *p; char *t; - if (!memcmp( s, Home, HomeLen ) && s[HomeLen] == '/') + if (starts_with( s, -1, Home, HomeLen ) && s[HomeLen] == '/') s += HomeLen + 1; for (p = boxes; p; p = p->next) { if (!strcmp( s, p->path ) || (p->alias && !strcmp( s, p->alias ))) diff -Nru isync-1.1.0/src/compat/convert.c isync-1.2.1-1.812.20170514/src/compat/convert.c --- isync-1.1.0/src/compat/convert.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/convert.c 2017-05-26 14:36:31.000000000 +0000 @@ -128,13 +128,21 @@ sys_error( "Cannot open %s", iuvname ); goto err2; } - fscanf( fp, "%d", &uidval ); + if (fscanf( fp, "%d", &uidval ) != 1) { + sys_error( "Cannot read %s", iuvname ); + err3: + fclose( fp ); + goto err2; + } fclose( fp ); if (!(fp = fopen( imuname, "r" ))) { sys_error( "Cannot open %s", imuname ); goto err2; } - fscanf( fp, "%d", &maxuid ); + if (fscanf( fp, "%d", &maxuid ) != 1) { + sys_error( "Cannot read %s", imuname ); + goto err3; + } fclose( fp ); if (!stat( iumname, &sb )) { @@ -232,7 +240,10 @@ goto err4; } db->close( db, 0 ); - rename( iumname, diumname ); + if (rename( iumname, diumname )) { + sys_error( "Cannot rename %s to %s", iumname, diumname ); + goto err4; + } } else { if (!(fp = fopen( uvname, "w" ))) { sys_error( "Cannot create %s", uvname ); diff -Nru isync-1.1.0/src/compat/isync.1 isync-1.2.1-1.812.20170514/src/compat/isync.1 --- isync-1.1.0/src/compat/isync.1 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/isync.1 2017-05-26 14:36:31.000000000 +0000 @@ -37,6 +37,9 @@ \fBmbsync\fR. If you were using \fBisync\fR version 0.8 or 0.9.x you might want to use \fBmdconvert\fR to convert the mailboxes to the more efficient \fBnative\fR UID storage scheme after migrating them. +.br +\fBisync\fR is deprecated. Please use the \fB-w\fR option to permanently +migrate the configuration and start using \fBmbsync\fR directly. .. .SH OPTIONS .TP @@ -256,7 +259,12 @@ .. .TP \fBCertificateFile\fR \fIpath\fR -File containing X.509 CA certificates used to verify server identities. +File containing additional X.509 certificates used to verify server +identities. Directly matched peer certificates are always trusted, +regardless of validity. +.br +Note that the system's default certificate store is always used +and should not be specified here. .. .TP \fBUseSSLv2\fR \fIyes\fR|\fIno\fR diff -Nru isync-1.1.0/src/compat/isync.h isync-1.2.1-1.812.20170514/src/compat/isync.h --- isync-1.1.0/src/compat/isync.h 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/isync.h 2017-05-26 14:36:31.000000000 +0000 @@ -56,6 +56,9 @@ const char *store_name; int stores; + const char *local_store_name; + const char *local_store_path; + int local_stores; char *copy_deleted_to; unsigned int use_namespace:1; @@ -99,3 +102,10 @@ int nfsnprintf( char *buf, int blen, const char *fmt, ... ); void sys_error( const char *, ... ); void ATTR_NORETURN oob( void ); + +#ifndef HAVE_MEMRCHR +void *memrchr( const void *s, int c, size_t n ); +#endif + +int starts_with( const char *str, int strl, const char *cmp, int cmpl ); +int equals( const char *str, int strl, const char *cmp, int cmpl ); diff -Nru isync-1.1.0/src/compat/isyncrc.sample isync-1.2.1-1.812.20170514/src/compat/isyncrc.sample --- isync-1.1.0/src/compat/isyncrc.sample 2010-02-06 10:48:16.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/isyncrc.sample 2017-05-26 14:36:31.000000000 +0000 @@ -3,7 +3,7 @@ # doesn't specify it. # SSL server certificate file -CertificateFile /etc/ssl/certs/ca-certificates.crt +CertificateFile ~/.isync.certs # by default, expunge deleted messages (same as -e on command line) Expunge yes diff -Nru isync-1.1.0/src/compat/main.c isync-1.2.1-1.812.20170514/src/compat/main.c --- isync-1.1.0/src/compat/main.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/main.c 2017-05-26 14:36:31.000000000 +0000 @@ -174,7 +174,7 @@ global.user = getenv( "LOGNAME" ); #endif global.port = 143; - global.box = "INBOX"; + global.box = ""; /* implicit INBOX in resulting Master/Slave entries */ global.use_namespace = 1; global.require_ssl = 1; global.use_tlsv1 = 1; @@ -288,6 +288,9 @@ } } + if (!writeout) + fputs( "Notice: please run 'isync -w' and start using 'mbsync' directly.\n", stderr ); + if (config) { if (*config != '/') { if (!getcwd( path1, sizeof(path1) )) { @@ -307,7 +310,7 @@ if (!all && !o2o) for (i = optind; argv[i]; i++) - if (!(box = find_box( argv[i] ))) { + if (!find_box( argv[i] )) { box = nfmalloc( sizeof(config_t) ); memcpy( box, &global, sizeof(config_t) ); box->path = argv[i]; diff -Nru isync-1.1.0/src/compat/Makefile.am isync-1.2.1-1.812.20170514/src/compat/Makefile.am --- isync-1.1.0/src/compat/Makefile.am 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/Makefile.am 2017-05-26 14:36:31.000000000 +0000 @@ -1,7 +1,7 @@ bin_PROGRAMS = isync isync_SOURCES = main.c config.c convert.c util.c -isync_LDADD = -ldb +isync_LDADD = $(DB_LIBS) noinst_HEADERS = isync.h man_MANS = isync.1 diff -Nru isync-1.1.0/src/compat/Makefile.in isync-1.2.1-1.812.20170514/src/compat/Makefile.in --- isync-1.1.0/src/compat/Makefile.in 2013-12-18 21:09:58.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,667 +0,0 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -bin_PROGRAMS = isync$(EXEEXT) -subdir = src/compat -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/depcomp $(noinst_HEADERS) -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/autodefs.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(exampledir)" -PROGRAMS = $(bin_PROGRAMS) -am_isync_OBJECTS = main.$(OBJEXT) config.$(OBJEXT) convert.$(OBJEXT) \ - util.$(OBJEXT) -isync_OBJECTS = $(am_isync_OBJECTS) -isync_DEPENDENCIES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(isync_SOURCES) -DIST_SOURCES = $(isync_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -man1dir = $(mandir)/man1 -NROFF = nroff -MANS = $(man_MANS) -DATA = $(example_DATA) -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKGCONFIG = @PKGCONFIG@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SOCK_LIBS = @SOCK_LIBS@ -SSL_LIBS = @SSL_LIBS@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -isync_SOURCES = main.c config.c convert.c util.c -isync_LDADD = -ldb -noinst_HEADERS = isync.h -man_MANS = isync.1 -exampledir = $(docdir)/examples -example_DATA = isyncrc.sample -EXTRA_DIST = $(example_DATA) $(man_MANS) -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/compat/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/compat/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) - -isync$(EXEEXT): $(isync_OBJECTS) $(isync_DEPENDENCIES) $(EXTRA_isync_DEPENDENCIES) - @rm -f isync$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(isync_OBJECTS) $(isync_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -install-man1: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man1dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.1[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -install-exampleDATA: $(example_DATA) - @$(NORMAL_INSTALL) - @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exampledir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(exampledir)" || exit $$?; \ - done - -uninstall-exampleDATA: - @$(NORMAL_UNINSTALL) - @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(exampledir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(exampledir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-exampleDATA install-man - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: install-man1 - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-exampleDATA \ - uninstall-man - -uninstall-man: uninstall-man1 - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ - clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ - distclean distclean-compile distclean-generic distclean-tags \ - distdir dvi dvi-am html html-am info info-am install \ - install-am install-binPROGRAMS install-data install-data-am \ - install-dvi install-dvi-am install-exampleDATA install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-man1 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-exampleDATA \ - uninstall-man uninstall-man1 - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff -Nru isync-1.1.0/src/compat/util.c isync-1.2.1-1.812.20170514/src/compat/util.c --- isync-1.1.0/src/compat/util.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/compat/util.c 2017-05-26 14:36:31.000000000 +0000 @@ -87,6 +87,48 @@ } #endif +#ifndef HAVE_MEMRCHR +void * +memrchr( const void *s, int c, size_t n ) +{ + u_char *b = (u_char *)s, *e = b + n; + + while (--e >= b) + if (*e == c) + return (void *)e; + return 0; +} +#endif + +#ifndef HAVE_STRNLEN +int +strnlen( const char *str, size_t maxlen ) +{ + size_t len; + + /* It's tempting to use memchr(), but it's allowed to read past the end of the actual string. */ + for (len = 0; len < maxlen && str[len]; len++) {} + return len; +} + +#endif + +int +starts_with( const char *str, int strl, const char *cmp, int cmpl ) +{ + if (strl < 0) + strl = strnlen( str, cmpl + 1 ); + return (strl >= cmpl) && !memcmp( str, cmp, cmpl ); +} + +int +equals( const char *str, int strl, const char *cmp, int cmpl ) +{ + if (strl < 0) + strl = strnlen( str, cmpl + 1 ); + return (strl == cmpl) && !memcmp( str, cmp, cmpl ); +} + void oob( void ) { diff -Nru isync-1.1.0/src/config.c isync-1.2.1-1.812.20170514/src/config.c --- isync-1.1.0/src/config.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/config.c 2017-05-26 14:36:31.000000000 +0000 @@ -36,10 +36,7 @@ store_conf_t *stores; -#define ARG_OPTIONAL 0 -#define ARG_REQUIRED 1 - -static char * +char * get_arg( conffile_t *cfile, int required, int *comment ) { char *ret, *p, *t; @@ -48,7 +45,7 @@ p = cfile->rest; assert( p ); - while ((c = *p) && isspace( (unsigned char) c )) + while ((c = *p) && isspace( (uchar)c )) p++; if (!c || c == '#') { if (comment) @@ -68,7 +65,7 @@ escaped = 1; else if (c == '"') quoted ^= 1; - else if (!quoted && isspace( (unsigned char) c )) + else if (!quoted && isspace( (uchar)c )) break; else *t++ = c; @@ -146,10 +143,20 @@ return ret; } +static const struct { + int op; + const char *name; +} boxOps[] = { + { OP_EXPUNGE, "Expunge" }, + { OP_CREATE, "Create" }, + { OP_REMOVE, "Remove" }, +}; + static int getopt_helper( conffile_t *cfile, int *cops, channel_conf_t *conf ) { char *arg; + uint i; if (!strcasecmp( "Sync", cfile->cmd )) { arg = cfile->val; @@ -191,38 +198,6 @@ } while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); conf->ops[M] |= XOP_HAVE_TYPE; - } else if (!strcasecmp( "Expunge", cfile->cmd )) { - arg = cfile->val; - do - if (!strcasecmp( "Both", arg )) - *cops |= OP_EXPUNGE; - else if (!strcasecmp( "Master", arg )) - conf->ops[M] |= OP_EXPUNGE; - else if (!strcasecmp( "Slave", arg )) - conf->ops[S] |= OP_EXPUNGE; - else if (strcasecmp( "None", arg )) { - error( "%s:%d: invalid Expunge arg '%s'\n", - cfile->file, cfile->line, arg ); - cfile->err = 1; - } - while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); - conf->ops[M] |= XOP_HAVE_EXPUNGE; - } else if (!strcasecmp( "Create", cfile->cmd )) { - arg = cfile->val; - do - if (!strcasecmp( "Both", arg )) - *cops |= OP_CREATE; - else if (!strcasecmp( "Master", arg )) - conf->ops[M] |= OP_CREATE; - else if (!strcasecmp( "Slave", arg )) - conf->ops[S] |= OP_CREATE; - else if (strcasecmp( "None", arg )) { - error( "%s:%d: invalid Create arg '%s'\n", - cfile->file, cfile->line, arg ); - cfile->err = 1; - } - while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); - conf->ops[M] |= XOP_HAVE_CREATE; } else if (!strcasecmp( "SyncState", cfile->cmd )) conf->sync_state = expand_strdup( cfile->val ); else if (!strcasecmp( "CopyArrivalDate", cfile->cmd )) @@ -231,16 +206,43 @@ conf->max_messages = parse_int( cfile ); else if (!strcasecmp( "ExpireUnread", cfile->cmd )) conf->expire_unread = parse_bool( cfile ); - else + else { + for (i = 0; i < as(boxOps); i++) { + if (!strcasecmp( boxOps[i].name, cfile->cmd )) { + int op = boxOps[i].op; + arg = cfile->val; + do { + if (!strcasecmp( "Both", arg )) { + *cops |= op; + } else if (!strcasecmp( "Master", arg )) { + conf->ops[M] |= op; + } else if (!strcasecmp( "Slave", arg )) { + conf->ops[S] |= op; + } else if (strcasecmp( "None", arg )) { + error( "%s:%d: invalid %s arg '%s'\n", + cfile->file, cfile->line, boxOps[i].name, arg ); + cfile->err = 1; + } + } while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); + conf->ops[M] |= op * (XOP_HAVE_EXPUNGE / OP_EXPUNGE); + return 1; + } + } return 0; + } return 1; } int getcline( conffile_t *cfile ) { + char *arg; int comment; + if (cfile->rest && (arg = get_arg( cfile, ARG_OPTIONAL, 0 ))) { + error( "%s:%d: excess token '%s'\n", cfile->file, cfile->line, arg ); + cfile->err = 1; + } while (fgets( cfile->buf, cfile->bufl, cfile->fp )) { cfile->line++; cfile->rest = cfile->buf; @@ -260,7 +262,8 @@ int merge_ops( int cops, int ops[] ) { - int aops; + int aops, op; + uint i; aops = ops[M] | ops[S]; if (ops[M] & XOP_HAVE_TYPE) { @@ -293,21 +296,16 @@ ops[M] |= cops & OP_MASK_TYPE; } } - if (ops[M] & XOP_HAVE_EXPUNGE) { - if (aops & cops & OP_EXPUNGE) { - error( "Conflicting Expunge args specified.\n" ); - return 1; - } - ops[M] |= cops & OP_EXPUNGE; - ops[S] |= cops & OP_EXPUNGE; - } - if (ops[M] & XOP_HAVE_CREATE) { - if (aops & cops & OP_CREATE) { - error( "Conflicting Create args specified.\n" ); - return 1; + for (i = 0; i < as(boxOps); i++) { + op = boxOps[i].op; + if (ops[M] & (op * (XOP_HAVE_EXPUNGE / OP_EXPUNGE))) { + if (aops & cops & op) { + error( "Conflicting %s args specified.\n", boxOps[i].name ); + return 1; + } + ops[M] |= cops & op; + ops[S] |= cops & op; } - ops[M] |= cops & OP_CREATE; - ops[S] |= cops & OP_CREATE; } return 0; } @@ -326,6 +324,7 @@ char buf[1024]; if (!where) { + assert( !pseudo ); nfsnprintf( path, sizeof(path), "%s/." EXE "rc", Home ); cfile.file = path; } else @@ -343,6 +342,7 @@ cfile.bufl = sizeof(buf) - 1; cfile.line = 0; cfile.err = 0; + cfile.rest = 0; gcops = 0; global_conf.expire_unread = -1; @@ -353,8 +353,6 @@ for (i = 0; i < N_DRIVERS; i++) if (drivers[i]->parse_store( &cfile, &store )) { if (store) { - if (!store->path) - store->path = ""; if (!store->max_size) store->max_size = INT_MAX; *storeapp = store; @@ -422,8 +420,11 @@ } else if (merge_ops( cops, channel->ops )) cfile.err = 1; else { - if (max_size >= 0) + if (max_size >= 0) { + if (!max_size) + max_size = INT_MAX; channel->stores[M]->max_size = channel->stores[S]->max_size = max_size; + } *channelapp = channel; channelapp = &channel->next; } @@ -468,6 +469,27 @@ { UseFSync = parse_bool( &cfile ); } + else if (!strcasecmp( "FieldDelimiter", cfile.cmd )) + { + if (strlen( cfile.val ) != 1) { + error( "%s:%d: Field delimiter must be exactly one character long\n", cfile.file, cfile.line ); + cfile.err = 1; + } else { + FieldDelimiter = cfile.val[0]; + if (!ispunct( FieldDelimiter )) { + error( "%s:%d: Field delimiter must be a punctuation character\n", cfile.file, cfile.line ); + cfile.err = 1; + } + } + } + else if (!strcasecmp( "BufferLimit", cfile.cmd )) + { + BufferLimit = parse_size( &cfile ); + if (BufferLimit <= 0) { + error( "%s:%d: BufferLimit must be positive\n", cfile.file, cfile.line ); + cfile.err = 1; + } + } else if (!getopt_helper( &cfile, &gcops, &global_conf )) { error( "%s:%d: unknown section keyword '%s'\n", diff -Nru isync-1.1.0/src/config.h isync-1.2.1-1.812.20170514/src/config.h --- isync-1.1.0/src/config.h 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/config.h 2017-05-26 14:36:31.000000000 +0000 @@ -25,7 +25,7 @@ #include "common.h" -typedef struct conffile { +typedef struct { const char *file; FILE *fp; char *buf; @@ -35,6 +35,11 @@ char *cmd, *val, *rest; } conffile_t; +#define ARG_OPTIONAL 0 +#define ARG_REQUIRED 1 + +char *get_arg( conffile_t *cfile, int required, int *comment ); + int parse_bool( conffile_t *cfile ); int parse_int( conffile_t *cfile ); int parse_size( conffile_t *cfile ); diff -Nru isync-1.1.0/src/driver.c isync-1.2.1-1.812.20170514/src/driver.c --- isync-1.1.0/src/driver.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/driver.c 2017-05-26 14:36:31.000000000 +0000 @@ -34,6 +34,7 @@ for (; msgs; msgs = tmsg) { tmsg = msgs->next; + free( msgs->msgid ); free( msgs ); } } diff -Nru isync-1.1.0/src/driver.h isync-1.2.1-1.812.20170514/src/driver.h --- isync-1.1.0/src/driver.h 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/driver.h 2017-05-26 14:36:31.000000000 +0000 @@ -27,6 +27,10 @@ typedef struct driver driver_t; +#define FAIL_TEMP 0 /* Retry immediately (also: no error) */ +#define FAIL_WAIT 1 /* Retry after some time (if at all) */ +#define FAIL_FINAL 2 /* Don't retry until store reconfiguration */ + typedef struct store_conf { struct store_conf *next; char *name; @@ -35,7 +39,7 @@ const char *flat_delim; const char *map_inbox; const char *trash; - unsigned max_size; /* off_t is overkill */ + int max_size; /* off_t is overkill */ char trash_remote_new, trash_only_new; } store_conf_t; @@ -59,10 +63,11 @@ typedef struct message { struct message *next; struct sync_rec *srec; + char *msgid; /* owned */ /* string_list_t *keywords; */ - size_t size; /* zero implies "not fetched" */ - int uid; - unsigned char flags, status; + int size; /* zero implies "not fetched" */ + uint uid; + uchar flags, status; char tuid[TUIDL]; } message_t; @@ -70,48 +75,27 @@ #define OPEN_OLD (1<<0) #define OPEN_NEW (1<<1) #define OPEN_FLAGS (1<<2) -#define OPEN_SIZE (1<<3) +#define OPEN_OLD_SIZE (1<<3) +#define OPEN_NEW_SIZE (1<<4) #define OPEN_EXPUNGE (1<<5) #define OPEN_SETFLAGS (1<<6) #define OPEN_APPEND (1<<7) #define OPEN_FIND (1<<8) +#define OPEN_OLD_IDS (1<<9) + +#define UIDVAL_BAD ((uint)-1) typedef struct store { struct store *next; + driver_t *driver; store_conf_t *conf; /* foreign */ - string_list_t *boxes; /* _list results - own */ - char listed; /* was _list already run? */ - - void (*bad_callback)( void *aux ); - void *bad_callback_aux; - - /* currently open mailbox */ - const char *orig_name; /* foreign! maybe preset? */ - char *name; /* foreign! maybe preset? */ - char *path; /* own */ - message_t *msgs; /* own */ - int uidvalidity; - int uidnext; /* from SELECT responses */ - unsigned opts; /* maybe preset? */ - /* note that the following do _not_ reflect stats from msgs, but mailbox totals */ - int count; /* # of messages */ - int recent; /* # of recent messages - don't trust this beyond the initial read */ } store_t; -/* When the callback is invoked (at most once per store), the store is fubar; - * call the driver's cancel_store() to dispose of it. */ -static INLINE void -set_bad_callback( store_t *ctx, void (*cb)( void *aux ), void *aux ) -{ - ctx->bad_callback = cb; - ctx->bad_callback_aux = aux; -} - typedef struct { char *data; int len; time_t date; - unsigned char flags; + uchar flags; } msg_data_t; #define DRV_OK 0 @@ -119,8 +103,10 @@ #define DRV_MSG_BAD 1 /* Something is wrong with the current mailbox - probably it is somehow inaccessible. */ #define DRV_BOX_BAD 2 +/* Failed to connect store. */ +#define DRV_STORE_BAD 3 /* The command has been cancel()ed or cancel_store()d. */ -#define DRV_CANCELED 3 +#define DRV_CANCELED 4 /* All memory belongs to the driver's user, unless stated otherwise. */ @@ -135,73 +121,116 @@ */ #define DRV_VERBOSE 2 -#define LIST_PATH 1 -#define LIST_INBOX 2 +#define LIST_INBOX 1 +#define LIST_PATH 2 +#define LIST_PATH_MAYBE 4 + +#define xint int // For auto-generation of appropriate printf() formats. struct driver { - int flags; + /* Return driver capabilities. */ + xint (*get_caps)( store_t *ctx ); /* Parse configuration. */ int (*parse_store)( conffile_t *cfg, store_conf_t **storep ); - /* Close remaining server connections. All stores must be disowned first. */ + /* Close remaining server connections. All stores must be discarded first. */ void (*cleanup)( void ); - /* Open a store with the given configuration. This may recycle existing - * server connections. Upon failure, a null store is passed to the callback. */ - void (*open_store)( store_conf_t *conf, const char *label, - void (*cb)( store_t *ctx, void *aux ), void *aux ); + /* Allocate a store with the given configuration. This is expected to + * return quickly, and must not fail. */ + store_t *(*alloc_store)( store_conf_t *conf, const char *label ); + + /* When this callback is invoked (at most once per store), the store is fubar; + * call cancel_store() to dispose of it. */ + void (*set_bad_callback)( store_t *ctx, void (*cb)( void *aux ), void *aux ); + + /* Open/connect the store. This may recycle existing server connections. */ + void (*connect_store)( store_t *ctx, + void (*cb)( int sts, void *aux ), void *aux ); - /* Mark the store as available for recycling. Server connection may be kept alive. */ - void (*disown_store)( store_t *ctx ); + /* Discard the store. Underlying server connection may be kept alive. */ + void (*free_store)( store_t *ctx ); /* Discard the store after a bad_callback. The server connections will be closed. * Pending commands will have their callbacks synchronously invoked with DRV_CANCELED. */ void (*cancel_store)( store_t *ctx ); - /* List the mailboxes in this store. Flags are ORed LIST_* values. */ - void (*list)( store_t *ctx, int flags, - void (*cb)( int sts, void *aux ), void *aux ); + /* List the mailboxes in this store. Flags are ORed LIST_* values. + * The returned box list remains owned by the driver. */ + void (*list_store)( store_t *ctx, int flags, + void (*cb)( int sts, string_list_t *boxes, void *aux ), void *aux ); + + /* Invoked before open_box(), this informs the driver which box is to be opened. */ + int (*select_box)( store_t *ctx, const char *name ); + + /* Get the selected box' on-disk path, if applicable, null otherwise. */ + const char *(*get_box_path)( store_t *ctx ); + + /* Create the selected mailbox. */ + void (*create_box)( store_t *ctx, + void (*cb)( int sts, void *aux ), void *aux ); + + /* Open the selected mailbox. + * Note that this should not directly complain about failure to open. */ + void (*open_box)( store_t *ctx, + void (*cb)( int sts, int uidvalidity, void *aux ), void *aux ); + + /* Return the minimal UID the next stored message will have. */ + int (*get_uidnext)( store_t *ctx ); + + /* Confirm that the open mailbox is empty. */ + int (*confirm_box_empty)( store_t *ctx ); + + /* Delete the open mailbox. The mailbox is expected to be empty. + * Subfolders of the mailbox are *not* deleted. + * Some artifacts of the mailbox may remain, but they won't be + * recognized as a mailbox any more. */ + void (*delete_box)( store_t *ctx, + void (*cb)( int sts, void *aux ), void *aux ); - /* Invoked before select(), this informs the driver which operations (OP_*) - * will be performed on the mailbox. The driver may extend the set by implicitly - * needed or available operations. */ - void (*prepare_opts)( store_t *ctx, int opts ); + /* Remove the last artifacts of the open mailbox, as far as possible. */ + int (*finish_delete_box)( store_t *ctx ); - /* Open the mailbox ctx->name. Optionally create missing boxes. - * As a side effect, this should resolve ctx->path if applicable. */ - void (*select)( store_t *ctx, int create, - void (*cb)( int sts, void *aux ), void *aux ); + /* Invoked before load_box(), this informs the driver which operations (OP_*) + * will be performed on the mailbox. The driver may extend the set by implicitly + * needed or available operations. Returns this possibly extended set. */ + xint (*prepare_load_box)( store_t *ctx, xint opts ); /* Load the message attributes needed to perform the requested operations. * Consider only messages with UIDs between minuid and maxuid (inclusive) * and those named in the excs array (smaller than minuid). - * The driver takes ownership of the excs array. Messages below newuid do not need - * to have the TUID populated even if OPEN_FIND is set. */ - void (*load)( store_t *ctx, int minuid, int maxuid, int newuid, int *excs, int nexcs, - void (*cb)( int sts, void *aux ), void *aux ); + * The driver takes ownership of the excs array. + * Messages starting with newuid need to have the TUID populated when OPEN_FIND is set. + * Messages up to seenuid need to have the Message-Id populated when OPEN_OLD_IDS is set. + * Messages up to seenuid need to have the size populated when OPEN_OLD_SIZE is set; + * likewise messages above seenuid when OPEN_NEW_SIZE is set. + * The returned message list remains owned by the driver. */ + void (*load_box)( store_t *ctx, uint minuid, uint maxuid, uint newuid, uint seenuid, uint_array_t excs, + void (*cb)( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ), void *aux ); /* Fetch the contents and flags of the given message from the current mailbox. */ void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data, void (*cb)( int sts, void *aux ), void *aux ); /* Store the given message to either the current mailbox or the trash folder. - * If the new copy's UID can be immediately determined, return it, otherwise -2. */ + * If the new copy's UID can be immediately determined, return it, otherwise 0. */ void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash, - void (*cb)( int sts, int uid, void *aux ), void *aux ); + void (*cb)( int sts, uint uid, void *aux ), void *aux ); /* Index the messages which have newly appeared in the mailbox, including their * temporary UID headers. This is needed if store_msg() does not guarantee returning - * a UID; otherwise the driver needs to implement only the OPEN_FIND flag. */ - void (*find_new_msgs)( store_t *ctx, - void (*cb)( int sts, void *aux ), void *aux ); + * a UID; otherwise the driver needs to implement only the OPEN_FIND flag. + * The returned message list remains owned by the driver. */ + void (*find_new_msgs)( store_t *ctx, uint newuid, + void (*cb)( int sts, message_t *msgs, void *aux ), void *aux ); /* Add/remove the named flags to/from the given message. The message may be either * a pre-fetched one (in which case the in-memory representation is updated), * or it may be identifed by UID only. The operation may be delayed until commit() * is called. */ - void (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int del, /* msg can be null, therefore uid as a fallback */ - void (*cb)( int sts, void *aux ), void *aux ); + void (*set_msg_flags)( store_t *ctx, message_t *msg, uint uid, int add, int del, /* msg can be null, therefore uid as a fallback */ + void (*cb)( int sts, void *aux ), void *aux ); /* Move the given message from the current mailbox to the trash folder. * This may expunge the original message immediately, but it needn't to. */ @@ -210,26 +239,34 @@ /* Expunge deleted messages from the current mailbox and close it. * There is no need to explicitly close a mailbox if no expunge is needed. */ - void (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */ - void (*cb)( int sts, void *aux ), void *aux ); + void (*close_box)( store_t *ctx, /* IMAP-style: expunge inclusive */ + void (*cb)( int sts, void *aux ), void *aux ); /* Cancel queued commands which are not in flight yet; they will have their * callbacks invoked with DRV_CANCELED. Afterwards, wait for the completion of * the in-flight commands. If the store is canceled before this command completes, * the callback will *not* be invoked. */ - void (*cancel)( store_t *ctx, - void (*cb)( void *aux ), void *aux ); + void (*cancel_cmds)( store_t *ctx, + void (*cb)( void *aux ), void *aux ); + + /* Commit any pending set_msg_flags() commands. */ + void (*commit_cmds)( store_t *ctx ); - /* Commit any pending set_flags() commands. */ - void (*commit)( store_t *ctx ); + /* Get approximate amount of memory occupied by the driver. */ + int (*get_memory_usage)( store_t *ctx ); + + /* Get the FAIL_* state of the driver. */ + int (*get_fail_state)( store_conf_t *conf ); }; void free_generic_messages( message_t * ); void parse_generic_store( store_conf_t *store, conffile_t *cfg ); +store_t *proxy_alloc_store( store_t *real_ctx, const char *label ); + #define N_DRIVERS 2 extern driver_t *drivers[N_DRIVERS]; -extern driver_t maildir_driver, imap_driver; +extern driver_t maildir_driver, imap_driver, proxy_driver; #endif diff -Nru isync-1.1.0/src/drv_imap.c isync-1.2.1-1.812.20170514/src/drv_imap.c --- isync-1.1.0/src/drv_imap.c 2013-12-15 12:46:06.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/drv_imap.c 2017-05-26 14:36:31.000000000 +0000 @@ -36,6 +36,15 @@ #include #include +#ifdef HAVE_LIBSASL +# include +# include +#endif + +#ifdef HAVE_LIBSSL +enum { SSL_None, SSL_STARTTLS, SSL_IMAPS }; +#endif + typedef struct imap_server_conf { struct imap_server_conf *next; char *name; @@ -44,20 +53,22 @@ char *pass; char *pass_cmd; int max_in_progress; + int cap_mask; + string_list_t *auth_mechs; #ifdef HAVE_LIBSSL - char require_ssl; - char require_cram; + char ssl_type; #endif + char failed; } imap_server_conf_t; -typedef struct imap_store_conf { +typedef struct { store_conf_t gen; imap_server_conf_t *server; - char *delimiter; + char delimiter; char use_namespace; } imap_store_conf_t; -typedef struct imap_message { +typedef struct { message_t gen; /* int seq; will be needed when expunges are tracked */ } imap_message_t; @@ -73,45 +84,66 @@ #define MAX_LIST_DEPTH 5 -struct imap_store; +typedef struct imap_store imap_store_t; -typedef struct parse_list_state { +typedef struct { list_t *head, **stack[MAX_LIST_DEPTH]; - int (*callback)( struct imap_store *ctx, list_t *list, char *cmd ); + int (*callback)( imap_store_t *ctx, list_t *list, char *cmd ); int level, need_bytes; } parse_list_state_t; -struct imap_cmd; +typedef struct imap_cmd imap_cmd_t; -typedef struct imap_store { +struct imap_store { store_t gen; const char *label; /* foreign */ const char *prefix; + const char *name; int ref_count; + uint opts; + enum { SST_BAD, SST_HALF, SST_GOOD } state; /* trash folder's existence is not confirmed yet */ enum { TrashUnknown, TrashChecking, TrashKnown } trashnc; - unsigned got_namespace:1; - char *delimiter; /* hierarchy delimiter */ + uint got_namespace:1; + char delimiter[2]; /* hierarchy delimiter */ list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */ + string_list_t *boxes; // _list results + char listed; // was _list already run with these flags? + // note that the message counts do _not_ reflect stats from msgs, + // but mailbox totals. also, don't trust them beyond the initial load. + int total_msgs, recent_msgs; + uint uidvalidity, uidnext; + message_t *msgs; message_t **msgapp; /* FETCH results */ - unsigned caps; /* CAPABILITY results */ + uint caps; /* CAPABILITY results */ + string_list_t *auth_mechs; parse_list_state_t parse_list_sts; /* command queue */ int nexttag, num_in_progress; - struct imap_cmd *pending, **pending_append; - struct imap_cmd *in_progress, **in_progress_append; + imap_cmd_t *pending, **pending_append; + imap_cmd_t *in_progress, **in_progress_append; + int buffer_mem; /* memory currently occupied by buffers in the queue */ /* Used during sequential operations like connect */ enum { GreetingPending = 0, GreetingBad, GreetingOk, GreetingPreauth } greeting; + int expectBYE; /* LOGOUT is in progress */ + int expectEOF; /* received LOGOUT's OK or unsolicited BYE */ int canceling; /* imap_cancel() is in progress */ union { - void (*imap_open)( store_t *srv, void *aux ); + void (*imap_open)( int sts, void *aux ); void (*imap_cancel)( void *aux ); } callbacks; void *callback_aux; +#ifdef HAVE_LIBSASL + sasl_conn_t *sasl; + int sasl_cont; +#endif + + void (*bad_callback)( void *aux ); + void *bad_callback_aux; conn_t conn; /* this is BIG, so put it last */ -} imap_store_t; +}; struct imap_cmd { struct imap_cmd *next; @@ -121,72 +153,85 @@ struct { /* Will be called on each continuation request until it resets this pointer. * Needs to invoke bad_callback and return -1 on error, otherwise return 0. */ - int (*cont)( imap_store_t *ctx, struct imap_cmd *cmd, const char *prompt ); - void (*done)( imap_store_t *ctx, struct imap_cmd *cmd, int response ); + int (*cont)( imap_store_t *ctx, imap_cmd_t *cmd, const char *prompt ); + void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response ); char *data; int data_len; - int uid; /* to identify fetch responses */ + uint uid; /* to identify fetch responses */ char high_prio; /* if command is queued, put it at the front of the queue. */ char to_trash; /* we are storing to trash, not current. */ - char create; /* create the mailbox if we get an error ... */ - char trycreate; /* ... but only if this is true or the server says so. */ + char create; /* create the mailbox if we get an error which suggests so. */ + char failok; /* Don't complain about NO response. */ + char lastuid; /* querying the last UID in the mailbox. */ } param; }; -struct imap_cmd_simple { - struct imap_cmd gen; +typedef struct { + imap_cmd_t gen; void (*callback)( int sts, void *aux ); void *callback_aux; -}; +} imap_cmd_simple_t; -struct imap_cmd_fetch_msg { - struct imap_cmd_simple gen; +typedef struct { + imap_cmd_simple_t gen; msg_data_t *msg_data; -}; +} imap_cmd_fetch_msg_t; -struct imap_cmd_out_uid { - struct imap_cmd gen; - void (*callback)( int sts, int uid, void *aux ); +typedef struct { + imap_cmd_t gen; + void (*callback)( int sts, uint uid, void *aux ); void *callback_aux; - int out_uid; -}; + uint out_uid; +} imap_cmd_out_uid_t; -struct imap_cmd_refcounted_state { - void (*callback)( int sts, void *aux ); +typedef struct { + imap_cmd_t gen; + void (*callback)( int sts, message_t *msgs, void *aux ); void *callback_aux; + message_t **out_msgs; + uint uid; +} imap_cmd_find_new_t; + +typedef struct { int ref_count; int ret_val; -}; +} imap_cmd_refcounted_state_t; -struct imap_cmd_refcounted { - struct imap_cmd gen; - struct imap_cmd_refcounted_state *state; -}; +typedef struct { + imap_cmd_t gen; + imap_cmd_refcounted_state_t *state; +} imap_cmd_refcounted_t; #define CAP(cap) (ctx->caps & (1 << (cap))) enum CAPABILITY { NOLOGIN = 0, +#ifdef HAVE_LIBSASL + SASLIR, +#endif #ifdef HAVE_LIBSSL - CRAM, STARTTLS, #endif UIDPLUS, LITERALPLUS, MOVE, - NAMESPACE + NAMESPACE, + COMPRESS_DEFLATE }; static const char *cap_list[] = { "LOGINDISABLED", +#ifdef HAVE_LIBSASL + "SASL-IR", +#endif #ifdef HAVE_LIBSSL - "AUTH=CRAM-MD5", "STARTTLS", #endif "UIDPLUS", "LITERAL+", "MOVE", - "NAMESPACE" + "NAMESPACE", + "COMPRESS=DEFLATE" }; #define RESP_OK 0 @@ -206,45 +251,49 @@ "Deleted", }; -static struct imap_cmd * +static imap_cmd_t * new_imap_cmd( int size ) { - struct imap_cmd *cmd = nfmalloc( size ); + imap_cmd_t *cmd = nfmalloc( size ); memset( &cmd->param, 0, sizeof(cmd->param) ); return cmd; } #define INIT_IMAP_CMD(type, cmdp, cb, aux) \ - cmdp = (struct type *)new_imap_cmd( sizeof(*cmdp) ); \ + cmdp = (type *)new_imap_cmd( sizeof(*cmdp) ); \ cmdp->callback = cb; \ cmdp->callback_aux = aux; #define INIT_IMAP_CMD_X(type, cmdp, cb, aux) \ - cmdp = (struct type *)new_imap_cmd( sizeof(*cmdp) ); \ + cmdp = (type *)new_imap_cmd( sizeof(*cmdp) ); \ cmdp->gen.callback = cb; \ cmdp->gen.callback_aux = aux; static void -done_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd, int response ) +done_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd, int response ) { cmd->param.done( ctx, cmd, response ); - free( cmd->param.data ); + if (cmd->param.data) { + free( cmd->param.data ); + ctx->buffer_mem -= cmd->param.data_len; + } free( cmd->cmd ); free( cmd ); } -static int -send_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd ) +static void +send_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd ) { - int bufl, litplus; + int bufl, litplus, iovcnt = 1; const char *buffmt; + conn_iovec_t iov[3]; char buf[1024]; cmd->tag = ++ctx->nexttag; if (!cmd->param.data) { buffmt = "%d %s\r\n"; litplus = 0; - } else if ((cmd->param.to_trash && ctx->trashnc == TrashUnknown) || !CAP(LITERALPLUS)) { + } else if ((cmd->param.to_trash && ctx->trashnc == TrashUnknown) || !CAP(LITERALPLUS) || cmd->param.data_len >= 100*1024) { buffmt = "%d %s{%d}\r\n"; litplus = 0; } else { @@ -253,69 +302,95 @@ } bufl = nfsnprintf( buf, sizeof(buf), buffmt, cmd->tag, cmd->cmd, cmd->param.data_len ); - if (DFlags & VERBOSE) { + if (DFlags & DEBUG_NET) { if (ctx->num_in_progress) printf( "(%d in progress) ", ctx->num_in_progress ); - if (memcmp( cmd->cmd, "LOGIN", 5 )) - printf( "%s>>> %s", ctx->label, buf ); - else + if (starts_with( cmd->cmd, -1, "LOGIN", 5 )) printf( "%s>>> %d LOGIN \n", ctx->label, cmd->tag ); + else if (starts_with( cmd->cmd, -1, "AUTHENTICATE PLAIN", 18 )) + printf( "%s>>> %d AUTHENTICATE PLAIN \n", ctx->label, cmd->tag ); + else + printf( "%s>>> %s", ctx->label, buf ); fflush( stdout ); } - if (socket_write( &ctx->conn, buf, bufl, KeepOwn ) < 0) - goto bail; + iov[0].buf = buf; + iov[0].len = bufl; + iov[0].takeOwn = KeepOwn; if (litplus) { - char *p = cmd->param.data; + if (DFlags & DEBUG_NET_ALL) { + printf( "%s>>>>>>>>>\n", ctx->label ); + fwrite( cmd->param.data, cmd->param.data_len, 1, stdout ); + printf( "%s>>>>>>>>>\n", ctx->label ); + fflush( stdout ); + } + iov[1].buf = cmd->param.data; + iov[1].len = cmd->param.data_len; + iov[1].takeOwn = GiveOwn; cmd->param.data = 0; - if (socket_write( &ctx->conn, p, cmd->param.data_len, GiveOwn ) < 0 || - socket_write( &ctx->conn, "\r\n", 2, KeepOwn ) < 0) - goto bail; + ctx->buffer_mem -= cmd->param.data_len; + iov[2].buf = "\r\n"; + iov[2].len = 2; + iov[2].takeOwn = KeepOwn; + iovcnt = 3; } + socket_write( &ctx->conn, iov, iovcnt ); if (cmd->param.to_trash && ctx->trashnc == TrashUnknown) ctx->trashnc = TrashChecking; cmd->next = 0; *ctx->in_progress_append = cmd; ctx->in_progress_append = &cmd->next; ctx->num_in_progress++; - return 0; - - bail: - done_imap_cmd( ctx, cmd, RESP_CANCEL ); - return -1; + socket_expect_read( &ctx->conn, 1 ); } static int -cmd_submittable( imap_store_t *ctx, struct imap_cmd *cmd ) +cmd_sendable( imap_store_t *ctx, imap_cmd_t *cmd ) { - struct imap_cmd *cmdp; - - return !ctx->conn.write_buf && - !(ctx->in_progress && - (cmdp = (struct imap_cmd *)((char *)ctx->in_progress_append - - offsetof(struct imap_cmd, next)), 1) && - (cmdp->param.cont || cmdp->param.data)) && - !(cmd->param.to_trash && ctx->trashnc == TrashChecking) && - ctx->num_in_progress < ((imap_store_conf_t *)ctx->gen.conf)->server->max_in_progress; + if (ctx->conn.write_buf) { + /* Don't build up a long queue in the socket, so we can + * control when the commands are actually sent. + * This allows reliable cancelation of pending commands, + * injecting commands in front of other pending commands, + * and keeping num_in_progress accurate. */ + return 0; + } + if (ctx->in_progress) { + /* If the last command in flight ... */ + imap_cmd_t *cmdp = (imap_cmd_t *)((char *)ctx->in_progress_append - + offsetof(imap_cmd_t, next)); + if (cmdp->param.cont || cmdp->param.data) { + /* ... is expected to trigger a continuation request, we need to + * wait for that round-trip before sending the next command. */ + return 0; + } + } + if (cmd->param.to_trash && ctx->trashnc == TrashChecking) { + /* Don't build a queue of MOVE/COPY/APPEND commands that may all fail. */ + return 0; + } + if (ctx->num_in_progress >= ((imap_store_conf_t *)ctx->gen.conf)->server->max_in_progress) { + /* Too many commands in flight. */ + return 0; + } + return 1; } -static int +static void flush_imap_cmds( imap_store_t *ctx ) { - struct imap_cmd *cmd; + imap_cmd_t *cmd; - while ((cmd = ctx->pending) && cmd_submittable( ctx, cmd )) { + if ((cmd = ctx->pending) && cmd_sendable( ctx, cmd )) { if (!(ctx->pending = cmd->next)) ctx->pending_append = &ctx->pending; - if (send_imap_cmd( ctx, cmd ) < 0) - return -1; + send_imap_cmd( ctx, cmd ); } - return 0; } static void cancel_pending_imap_cmds( imap_store_t *ctx ) { - struct imap_cmd *cmd; + imap_cmd_t *cmd; while ((cmd = ctx->pending)) { if (!(ctx->pending = cmd->next)) @@ -325,10 +400,11 @@ } static void -cancel_submitted_imap_cmds( imap_store_t *ctx ) +cancel_sent_imap_cmds( imap_store_t *ctx ) { - struct imap_cmd *cmd; + imap_cmd_t *cmd; + socket_expect_read( &ctx->conn, 0 ); while ((cmd = ctx->in_progress)) { ctx->in_progress = cmd->next; /* don't update num_in_progress and in_progress_append - store is dead */ @@ -336,15 +412,15 @@ } } -static int -submit_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd ) +static void +submit_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd ) { assert( ctx ); - assert( ctx->gen.bad_callback ); + assert( ctx->bad_callback ); assert( cmd ); assert( cmd->param.done ); - if ((ctx->pending && !cmd->param.high_prio) || !cmd_submittable( ctx, cmd )) { + if ((ctx->pending && !cmd->param.high_prio) || !cmd_sendable( ctx, cmd )) { if (ctx->pending && cmd->param.high_prio) { cmd->next = ctx->pending; ctx->pending = cmd; @@ -353,10 +429,9 @@ *ctx->pending_append = cmd; ctx->pending_append = &cmd->next; } - return 0; + } else { + send_imap_cmd( ctx, cmd ); } - - return send_imap_cmd( ctx, cmd ); } /* Minimal printf() replacement that supports an %\s format sequence to print backslash-escaped @@ -365,7 +440,7 @@ static char * imap_vprintf( const char *fmt, va_list ap ) { - const char *s, *es; + const char *s; char *d, *ed; int maxlen; char c; @@ -382,13 +457,8 @@ oob(); memcpy( d, s, l ); d += l; - if (!c) { - l = d - buf; - ed = nfmalloc( l + 1 ); - memcpy( ed, buf, l ); - ed[l] = 0; - return ed; - } + if (!c) + return nfstrndup( buf, d - buf ); maxlen = INT_MAX; c = *++fmt; if (c == '\\') { @@ -421,14 +491,15 @@ *d++ = (char)va_arg( ap , int ); } else if (c == 's') { s = va_arg( ap, const char * ); - es = memchr( s, 0, maxlen ); - l = es ? es - s : maxlen; + l = strnlen( s, maxlen ); if (d + l > ed) oob(); memcpy( d, s, l ); d += l; } else if (c == 'd') { d += nfsnprintf( d, ed - d, "%d", va_arg( ap , int ) ); + } else if (c == 'u') { + d += nfsnprintf( d, ed - d, "%u", va_arg( ap , uint ) ); } else { fputs( "Fatal: unsupported format specifier. Please report a bug.\n", stderr ); abort(); @@ -441,9 +512,9 @@ } } -static int -imap_exec( imap_store_t *ctx, struct imap_cmd *cmdp, - void (*done)( imap_store_t *ctx, struct imap_cmd *cmd, int response ), +static void +imap_exec( imap_store_t *ctx, imap_cmd_t *cmdp, + void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response ), const char *fmt, ... ) { va_list ap; @@ -454,7 +525,7 @@ va_start( ap, fmt ); cmdp->cmd = imap_vprintf( fmt, ap ); va_end( ap ); - return submit_imap_cmd( ctx, cmdp ); + submit_imap_cmd( ctx, cmdp ); } static void @@ -469,9 +540,9 @@ static void imap_done_simple_box( imap_store_t *ctx ATTR_UNUSED, - struct imap_cmd *cmd, int response ) + imap_cmd_t *cmd, int response ) { - struct imap_cmd_simple *cmdp = (struct imap_cmd_simple *)cmd; + imap_cmd_simple_t *cmdp = (imap_cmd_simple_t *)cmd; transform_box_response( &response ); cmdp->callback( response, cmdp->callback_aux ); @@ -489,58 +560,75 @@ static void imap_done_simple_msg( imap_store_t *ctx ATTR_UNUSED, - struct imap_cmd *cmd, int response ) + imap_cmd_t *cmd, int response ) { - struct imap_cmd_simple *cmdp = (struct imap_cmd_simple *)cmd; + imap_cmd_simple_t *cmdp = (imap_cmd_simple_t *)cmd; transform_msg_response( &response ); cmdp->callback( response, cmdp->callback_aux ); } -static struct imap_cmd_refcounted_state * -imap_refcounted_new_state( void (*cb)( int, void * ), void *aux ) +static imap_cmd_refcounted_state_t * +imap_refcounted_new_state( int sz ) { - struct imap_cmd_refcounted_state *sts = nfmalloc( sizeof(*sts) ); - sts->callback = cb; - sts->callback_aux = aux; + imap_cmd_refcounted_state_t *sts = nfmalloc( sz ); sts->ref_count = 1; /* so forced sync does not cause an early exit */ sts->ret_val = DRV_OK; return sts; } -static struct imap_cmd * -imap_refcounted_new_cmd( struct imap_cmd_refcounted_state *sts ) +#define INIT_REFCOUNTED_STATE(type, sts, cb, aux) \ + type *sts = (type *)imap_refcounted_new_state( sizeof(type) ); \ + sts->callback = cb; \ + sts->callback_aux = aux; + +static imap_cmd_t * +imap_refcounted_new_cmd( imap_cmd_refcounted_state_t *sts ) { - struct imap_cmd_refcounted *cmd = (struct imap_cmd_refcounted *)new_imap_cmd( sizeof(*cmd) ); + imap_cmd_refcounted_t *cmd = (imap_cmd_refcounted_t *)new_imap_cmd( sizeof(*cmd) ); cmd->state = sts; sts->ref_count++; return &cmd->gen; } +#define DONE_REFCOUNTED_STATE(sts) \ + if (!--sts->gen.ref_count) { \ + sts->callback( sts->gen.ret_val, sts->callback_aux ); \ + free( sts ); \ + } + +#define DONE_REFCOUNTED_STATE_ARGS(sts, ...) \ + if (!--sts->gen.ref_count) { \ + sts->callback( sts->gen.ret_val, __VA_ARGS__, sts->callback_aux ); \ + free( sts ); \ + } + static void -imap_refcounted_done( struct imap_cmd_refcounted_state *sts ) +transform_refcounted_box_response( imap_cmd_refcounted_state_t *sts, int response ) { - if (!--sts->ref_count) { - sts->callback( sts->ret_val, sts->callback_aux ); - free( sts ); + switch (response) { + case RESP_CANCEL: + sts->ret_val = DRV_CANCELED; + break; + case RESP_NO: + if (sts->ret_val == DRV_OK) /* Don't override cancelation. */ + sts->ret_val = DRV_BOX_BAD; + break; } } static void -imap_refcounted_done_box( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int response ) +transform_refcounted_msg_response( imap_cmd_refcounted_state_t *sts, int response ) { - struct imap_cmd_refcounted_state *sts = ((struct imap_cmd_refcounted *)cmd)->state; - switch (response) { case RESP_CANCEL: sts->ret_val = DRV_CANCELED; break; case RESP_NO: if (sts->ret_val == DRV_OK) /* Don't override cancelation. */ - sts->ret_val = DRV_BOX_BAD; + sts->ret_val = DRV_MSG_BAD; break; } - imap_refcounted_done( sts ); } static const char * @@ -567,7 +655,7 @@ s = *ps; if (!s) return 0; - while (isspace( (unsigned char)*s )) + while (isspace( (uchar)*s )) s++; if (!*s) { *ps = 0; @@ -589,7 +677,7 @@ } else { ret = s; while ((c = *s)) { - if (isspace( (unsigned char)c )) { + if (isspace( (uchar)c )) { *s++ = 0; break; } @@ -604,6 +692,12 @@ } static int +is_opt_atom( list_t *list ) +{ + return list && list->val && list->val != LIST; +} + +static int is_atom( list_t *list ) { return list && list->val && list->val != NIL && list->val != LIST; @@ -641,7 +735,7 @@ { list_t *cur, **curp; char *s = *sp, *d, *p; - int bytes; + int n, bytes; char c; assert( sts ); @@ -660,7 +754,7 @@ if (!s) return LIST_BAD; for (;;) { - while (isspace( (unsigned char)*s )) + while (isspace( (uchar)*s )) s++; if (sts->level && *s == ')') { s++; @@ -687,14 +781,21 @@ if (*s != '}' || *++s) goto bail; - s = cur->val = nfmalloc( cur->len ); + s = cur->val = nfmalloc( cur->len + 1 ); + s[cur->len] = 0; getbytes: - bytes -= socket_read( &ctx->conn, s, bytes ); + n = socket_read( &ctx->conn, s, bytes ); + if (n < 0) { + badeof: + error( "IMAP error: unexpected EOF from %s\n", ctx->conn.name ); + goto bail; + } + bytes -= n; if (bytes > 0) goto postpone; - if (DFlags & XVERBOSE) { + if (DFlags & DEBUG_NET_ALL) { printf( "%s=========\n", ctx->label ); fwrite( cur->val, cur->len, 1, stdout ); printf( "%s=========\n", ctx->label ); @@ -704,7 +805,9 @@ getline: if (!(s = socket_read_line( &ctx->conn ))) goto postpone; - if (DFlags & VERBOSE) { + if (s == (void *)~0) + goto badeof; + if (DFlags & DEBUG_NET) { printf( "%s%s\n", ctx->label, s ); fflush( stdout ); } @@ -720,23 +823,18 @@ *d++ = c; } cur->len = d - p; - cur->val = nfmalloc( cur->len + 1 ); - memcpy( cur->val, p, cur->len ); - cur->val[cur->len] = 0; + cur->val = nfstrndup( p, cur->len ); } else { /* atom */ p = s; - for (; *s && !isspace( (unsigned char)*s ); s++) + for (; *s && !isspace( (uchar)*s ); s++) if (sts->level && *s == ')') break; cur->len = s - p; - if (cur->len == 3 && !memcmp ("NIL", p, 3)) + if (equals( p, cur->len, "NIL", 3 )) cur->val = NIL; - else { - cur->val = nfmalloc( cur->len + 1 ); - memcpy( cur->val, p, cur->len ); - cur->val[cur->len] = 0; - } + else + cur->val = nfstrndup( p, cur->len ); } next: @@ -794,33 +892,50 @@ static int parse_namespace_rsp_p3( imap_store_t *, list_t *, char * ); static int -parse_namespace_rsp_fail( void ) +parse_namespace_check( list_t *list ) { + if (!list) + goto bad; + if (list->val == NIL) + return 0; + if (list->val != LIST) + goto bad; + for (list = list->child; list; list = list->next) { + if (list->val != LIST) + goto bad; + if (!is_atom( list->child )) + goto bad; + if (!is_opt_atom( list->child->next )) + goto bad; + /* Namespace response extensions may follow here; we don't care. */ + } + return 0; + bad: error( "IMAP error: malformed NAMESPACE response\n" ); - return LIST_BAD; + return -1; } static int parse_namespace_rsp( imap_store_t *ctx, list_t *list, char *s ) { - if (!(ctx->ns_personal = list)) - return parse_namespace_rsp_fail(); + if (parse_namespace_check( (ctx->ns_personal = list) )) + return LIST_BAD; return parse_list( ctx, s, parse_namespace_rsp_p2 ); } static int parse_namespace_rsp_p2( imap_store_t *ctx, list_t *list, char *s ) { - if (!(ctx->ns_other = list)) - return parse_namespace_rsp_fail(); + if (parse_namespace_check( (ctx->ns_other = list) )) + return LIST_BAD; return parse_list( ctx, s, parse_namespace_rsp_p3 ); } static int parse_namespace_rsp_p3( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED ) { - if (!(ctx->ns_shared = list)) - return parse_namespace_rsp_fail(); + if (parse_namespace_check( (ctx->ns_shared = list) )) + return LIST_BAD; return LIST_OK; } @@ -835,23 +950,23 @@ memset( &datetime, 0, sizeof(datetime) ); if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ", &datetime ))) return -1; - if ((date = mktime( &datetime )) == -1) + if ((date = timegm( &datetime )) == -1) return -1; if (sscanf( end, "%3d%2d", &hours, &mins ) != 2) return -1; - return date - (hours * 60 + mins) * 60 - timezone; + return date - (hours * 60 + mins) * 60; } static int parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED ) { list_t *tmp, *flags; - char *body = 0, *tuid = 0; + char *body = 0, *tuid = 0, *msgid = 0, *ep; imap_message_t *cur; msg_data_t *msgdata; - struct imap_cmd *cmdp; - int uid = 0, mask = 0, status = 0, size = 0; - unsigned i; + imap_cmd_t *cmdp; + int mask = 0, status = 0, size = 0; + uint i, uid = 0; time_t date = 0; if (!is_list( list )) { @@ -864,9 +979,7 @@ if (is_atom( tmp )) { if (!strcmp( "UID", tmp->val )) { tmp = tmp->next; - if (is_atom( tmp )) - uid = atoi( tmp->val ); - else + if (!is_atom( tmp ) || (uid = strtoul( tmp->val, &ep, 10 ), *ep)) error( "IMAP error: unable to parse UID\n" ); } else if (!strcmp( "FLAGS", tmp->val )) { tmp = tmp->next; @@ -903,9 +1016,7 @@ error( "IMAP error: unable to parse INTERNALDATE\n" ); } else if (!strcmp( "RFC822.SIZE", tmp->val )) { tmp = tmp->next; - if (is_atom( tmp )) - size = atoi( tmp->val ); - else + if (!is_atom( tmp ) || (size = strtoul( tmp->val, &ep, 10 ), *ep)) error( "IMAP error: unable to parse RFC822.SIZE\n" ); } else if (!strcmp( "BODY[]", tmp->val )) { tmp = tmp->next; @@ -922,9 +1033,44 @@ if (!is_atom( tmp ) || strcmp( tmp->val, "]" )) goto bfail; tmp = tmp->next; - if (!is_atom( tmp ) || memcmp( tmp->val, "X-TUID: ", 8 )) + if (!is_atom( tmp )) goto bfail; - tuid = tmp->val + 8; + int off, in_msgid = 0; + for (char *val = tmp->val, *end; (end = strchr( val, '\n' )); val = end + 1) { + int len = (int)(end - val); + if (len && end[-1] == '\r') + len--; + if (!len) + break; + if (starts_with_upper( val, len, "X-TUID: ", 8 )) { + if (len < 8 + TUIDL) { + error( "IMAP error: malformed X-TUID header (UID %u)\n", uid ); + continue; + } + tuid = val + 8; + in_msgid = 0; + continue; + } + if (starts_with_upper( val, len, "MESSAGE-ID:", 11 )) { + off = 11; + } else if (in_msgid) { + if (!isspace( val[0] )) { + in_msgid = 0; + continue; + } + off = 1; + } else { + continue; + } + while (off < len && isspace( val[off] )) + off++; + if (off == len) { + in_msgid = 1; + continue; + } + msgid = nfstrndup( val + off, len - off ); + in_msgid = 0; + } } else { bfail: error( "IMAP error: unable to parse BODY[HEADER.FIELDS ...]\n" ); @@ -933,21 +1079,29 @@ } } - if (body) { + if (!uid) { + assert( !body && !tuid && !msgid ); + // Ignore async flag updates for now. + } else if ((cmdp = ctx->in_progress) && cmdp->param.lastuid) { + assert( !body && !tuid && !msgid ); + // Workaround for server not sending UIDNEXT and/or APPENDUID. + ctx->uidnext = uid + 1; + } else if (body) { + assert( !tuid && !msgid ); for (cmdp = ctx->in_progress; cmdp; cmdp = cmdp->next) if (cmdp->param.uid == uid) goto gotuid; - error( "IMAP error: unexpected FETCH response (UID %d)\n", uid ); + error( "IMAP error: unexpected FETCH response (UID %u)\n", uid ); free_list( list ); return LIST_BAD; gotuid: - msgdata = ((struct imap_cmd_fetch_msg *)cmdp)->msg_data; + msgdata = ((imap_cmd_fetch_msg_t *)cmdp)->msg_data; msgdata->data = body; msgdata->len = size; msgdata->date = date; if (status & M_FLAGS) msgdata->flags = mask; - } else if (uid) { /* ignore async flag updates for now */ + } else { /* XXX this will need sorting for out-of-order (multiple queries) */ cur = nfcalloc( sizeof(*cur) ); *ctx->msgapp = &cur->gen; @@ -958,12 +1112,11 @@ cur->gen.status = status; cur->gen.size = size; cur->gen.srec = 0; + cur->gen.msgid = msgid; if (tuid) - strncpy( cur->gen.tuid, tuid, TUIDL ); + memcpy( cur->gen.tuid, tuid, TUIDL ); else cur->gen.tuid[0] = 0; - if (ctx->gen.uidnext <= uid) /* in case the server sends no UIDNEXT */ - ctx->gen.uidnext = uid + 1; } free_list( list ); @@ -974,17 +1127,27 @@ parse_capability( imap_store_t *ctx, char *cmd ) { char *arg; - unsigned i; + uint i; + free_string_list( ctx->auth_mechs ); + ctx->auth_mechs = 0; ctx->caps = 0x80000000; - while ((arg = next_arg( &cmd ))) - for (i = 0; i < as(cap_list); i++) - if (!strcmp( cap_list[i], arg )) - ctx->caps |= 1 << i; + while ((arg = next_arg( &cmd ))) { + if (starts_with( arg, -1, "AUTH=", 5 )) { + add_string_list( &ctx->auth_mechs, arg + 5 ); + } else { + for (i = 0; i < as(cap_list); i++) + if (!strcmp( cap_list[i], arg )) + ctx->caps |= 1 << i; + } + } + ctx->caps &= ~((imap_store_conf_t *)ctx->gen.conf)->server->cap_mask; + if (!CAP(NOLOGIN)) + add_string_list( &ctx->auth_mechs, "LOGIN" ); } static int -parse_response_code( imap_store_t *ctx, struct imap_cmd *cmd, char *s ) +parse_response_code( imap_store_t *ctx, imap_cmd_t *cmd, char *s ) { char *arg, *earg, *p; @@ -992,20 +1155,24 @@ return RESP_OK; /* no response code */ s++; if (!(p = strchr( s, ']' ))) { + bad_resp: error( "IMAP error: malformed response code\n" ); return RESP_CANCEL; } *p++ = 0; - arg = next_arg( &s ); + if (!(arg = next_arg( &s ))) + goto bad_resp; if (!strcmp( "UIDVALIDITY", arg )) { if (!(arg = next_arg( &s )) || - (ctx->gen.uidvalidity = strtoll( arg, &earg, 10 ), *earg)) + (ctx->uidvalidity = strtoul( arg, &earg, 10 ), *earg)) { error( "IMAP error: malformed UIDVALIDITY status\n" ); return RESP_CANCEL; } } else if (!strcmp( "UIDNEXT", arg )) { - if (!(arg = next_arg( &s )) || !(ctx->gen.uidnext = atoi( arg ))) { + if (!(arg = next_arg( &s )) || + (ctx->uidnext = strtoul( arg, &earg, 10 ), *earg)) + { error( "IMAP error: malformed NEXTUID status\n" ); return RESP_CANCEL; } @@ -1015,13 +1182,13 @@ /* RFC2060 says that these messages MUST be displayed * to the user */ - for (; isspace( (unsigned char)*p ); p++); + for (; isspace( (uchar)*p ); p++); error( "*** IMAP ALERT *** %s\n", p ); } else if (cmd && !strcmp( "APPENDUID", arg )) { if (!(arg = next_arg( &s )) || - (ctx->gen.uidvalidity = strtoll( arg, &earg, 10 ), *earg) || + (ctx->uidvalidity = strtoul( arg, &earg, 10 ), *earg) || !(arg = next_arg( &s )) || - !(((struct imap_cmd_out_uid *)cmd)->out_uid = atoi( arg ))) + (((imap_cmd_out_uid_t *)cmd)->out_uid = strtoul( arg, &earg, 10 ), *earg)) { error( "IMAP error: malformed APPENDUID status\n" ); return RESP_CANCEL; @@ -1039,8 +1206,9 @@ list_t *lp; if (!is_list( list )) { - error( "IMAP error: malformed LIST response\n" ); free_list( list ); + bad_list: + error( "IMAP error: malformed LIST response\n" ); return LIST_BAD; } for (lp = list->child; lp; lp = lp->next) @@ -1049,24 +1217,20 @@ return LIST_OK; } free_list( list ); - arg = next_arg( &cmd ); - if (!ctx->delimiter) - ctx->delimiter = nfstrdup( arg ); + if (!(arg = next_arg( &cmd ))) + goto bad_list; + if (!ctx->delimiter[0]) + ctx->delimiter[0] = arg[0]; return parse_list( ctx, cmd, parse_list_rsp_p2 ); } static int -is_inbox( imap_store_t *ctx, const char *arg ) +is_inbox( imap_store_t *ctx, const char *arg, int argl ) { - int i; - char c; - - if (memcmp( arg, "INBOX", 5 )) + if (!starts_with( arg, argl, "INBOX", 5 )) + return 0; + if (arg[5] && arg[5] != ctx->delimiter[0]) return 0; - if (arg[5]) - for (i = 0; (c = ctx->delimiter[i]); i++) - if (arg[i + 5] != c) - return 0; return 1; } @@ -1075,7 +1239,7 @@ { string_list_t *narg; char *arg; - int l; + int argl, l; if (!is_atom( list )) { error( "IMAP error: malformed LIST response\n" ); @@ -1083,25 +1247,28 @@ return LIST_BAD; } arg = list->val; - if (!is_inbox( ctx, arg )) { - l = strlen( ctx->gen.conf->path ); - if (memcmp( arg, ctx->gen.conf->path, l )) - goto skip; - arg += l; - if (is_inbox( ctx, arg )) { - if (!arg[5]) - warn( "IMAP warning: ignoring INBOX in %s\n", ctx->gen.conf->path ); + argl = list->len; + if ((l = strlen( ctx->prefix ))) { + if (starts_with( arg, argl, ctx->prefix, l )) { + arg += l; + argl -= l; + if (is_inbox( ctx, arg, argl )) { + if (!arg[5]) + warn( "IMAP warning: ignoring INBOX in %s\n", ctx->prefix ); + goto skip; + } + } else if (!is_inbox( ctx, arg, argl )) { goto skip; } } - if ((l = strlen( arg )) >= 5 && !memcmp( arg + l - 5, ".lock", 5 )) /* workaround broken servers */ + if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */ goto skip; if (map_name( arg, (char **)&narg, offsetof(string_list_t, string), ctx->delimiter, "/") < 0) { warn( "IMAP warning: ignoring mailbox %s (reserved character '/' in name)\n", arg ); goto skip; } - narg->next = ctx->gen.boxes; - ctx->gen.boxes = narg; + narg->next = ctx->boxes; + ctx->boxes = narg; skip: free_list( list ); return LIST_OK; @@ -1128,10 +1295,10 @@ static int prepare_box( char **buf, const imap_store_t *ctx ) { - const char *name = ctx->gen.name; + const char *name = ctx->name; return prepare_name( buf, ctx, - (!memcmp( name, "INBOX", 5 ) && (!name[5] || name[5] == '/')) ? "" : ctx->prefix, name ); + (starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == '/')) ? "" : ctx->prefix, name ); } static int @@ -1140,23 +1307,23 @@ return prepare_name( buf, ctx, ctx->prefix, ctx->gen.conf->trash ); } -struct imap_cmd_trycreate { - struct imap_cmd gen; - struct imap_cmd *orig_cmd; -}; +typedef struct { + imap_cmd_t gen; + imap_cmd_t *orig_cmd; +} imap_cmd_trycreate_t; static void imap_open_store_greeted( imap_store_t * ); -static void get_cmd_result_p2( imap_store_t *, struct imap_cmd *, int ); +static void get_cmd_result_p2( imap_store_t *, imap_cmd_t *, int ); static void imap_socket_read( void *aux ) { imap_store_t *ctx = (imap_store_t *)aux; - struct imap_cmd *cmdp, **pcmdp; + imap_cmd_t *cmdp, **pcmdp; char *cmd, *arg, *arg1, *p; - int resp, resp2, tag, greeted; + int resp, resp2, tag; + conn_iovec_t iov[2]; - greeted = ctx->greeting; for (;;) { if (ctx->parse_list_sts.level) { resp = parse_list_continue( ctx, 0 ); @@ -1169,7 +1336,13 @@ } if (!(cmd = socket_read_line( &ctx->conn ))) return; - if (DFlags & VERBOSE) { + if (cmd == (void *)~0) { + if (!ctx->expectEOF) + error( "IMAP error: unexpected EOF from %s\n", ctx->conn.name ); + /* A clean shutdown sequence ends with bad_callback as well (see imap_cleanup()). */ + break; + } + if (DFlags & DEBUG_NET) { printf( "%s%s\n", ctx->label, cmd ); fflush( stdout ); } @@ -1186,28 +1359,49 @@ break; } - if (!strcmp( "NAMESPACE", arg )) { - resp = parse_list( ctx, cmd, parse_namespace_rsp ); - goto listret; - } else if (ctx->greeting == GreetingPending && !strcmp( "PREAUTH", arg )) { - ctx->greeting = GreetingPreauth; + if (ctx->greeting == GreetingPending && !strcmp( "PREAUTH", arg )) { parse_response_code( ctx, 0, cmd ); + ctx->greeting = GreetingPreauth; + dogreet: + imap_ref( ctx ); + imap_open_store_greeted( ctx ); + if (imap_deref( ctx )) + return; } else if (!strcmp( "OK", arg )) { - ctx->greeting = GreetingOk; - parse_response_code( ctx, 0, cmd ); - } else if (!strcmp( "BAD", arg ) || !strcmp( "NO", arg ) || !strcmp( "BYE", arg )) { - ctx->greeting = GreetingBad; parse_response_code( ctx, 0, cmd ); + if (ctx->greeting == GreetingPending) { + ctx->greeting = GreetingOk; + goto dogreet; + } + } else if (!strcmp( "BYE", arg )) { + if (!ctx->expectBYE) { + ctx->greeting = GreetingBad; + error( "IMAP error: unexpected BYE response: %s\n", cmd ); + /* We just wait for the server to close the connection now. */ + ctx->expectEOF = 1; + } else { + /* We still need to wait for the LOGOUT's tagged OK. */ + } + } else if (ctx->greeting == GreetingPending) { + error( "IMAP error: bogus greeting response %s\n", arg ); + break; + } else if (!strcmp( "NO", arg )) { + warn( "Warning from IMAP server: %s\n", cmd ); + } else if (!strcmp( "BAD", arg )) { + error( "Error from IMAP server: %s\n", cmd ); } else if (!strcmp( "CAPABILITY", arg )) { parse_capability( ctx, cmd ); } else if (!strcmp( "LIST", arg )) { resp = parse_list( ctx, cmd, parse_list_rsp ); goto listret; + } else if (!strcmp( "NAMESPACE", arg )) { + resp = parse_list( ctx, cmd, parse_namespace_rsp ); + goto listret; } else if ((arg1 = next_arg( &cmd ))) { if (!strcmp( "EXISTS", arg1 )) - ctx->gen.count = atoi( arg ); + ctx->total_msgs = atoi( arg ); else if (!strcmp( "RECENT", arg1 )) - ctx->gen.recent = atoi( arg ); + ctx->recent_msgs = atoi( arg ); else if(!strcmp ( "FETCH", arg1 )) { resp = parse_list( ctx, cmd, parse_fetch_rsp ); goto listret; @@ -1216,27 +1410,34 @@ error( "IMAP error: unrecognized untagged response '%s'\n", arg ); break; /* this may mean anything, so prefer not to spam the log */ } - if (greeted == GreetingPending) { - imap_ref( ctx ); - imap_open_store_greeted( ctx ); - if (imap_deref( ctx )) - return; - } continue; } else if (!ctx->in_progress) { error( "IMAP error: unexpected reply: %s %s\n", arg, cmd ? cmd : "" ); break; /* this may mean anything, so prefer not to spam the log */ } else if (*arg == '+') { - /* This can happen only with the last command underway, as - it enforces a round-trip. */ - cmdp = ctx->in_progress; + socket_expect_read( &ctx->conn, 0 ); + /* There can be any number of commands in flight, but only the last + * one can require a continuation, as it enforces a round-trip. */ + cmdp = (imap_cmd_t *)((char *)ctx->in_progress_append - + offsetof(imap_cmd_t, next)); if (cmdp->param.data) { if (cmdp->param.to_trash) ctx->trashnc = TrashKnown; /* Can't get NO [TRYCREATE] any more. */ - p = cmdp->param.data; + if (DFlags & DEBUG_NET_ALL) { + printf( "%s>>>>>>>>>\n", ctx->label ); + fwrite( cmdp->param.data, cmdp->param.data_len, 1, stdout ); + printf( "%s>>>>>>>>>\n", ctx->label ); + fflush( stdout ); + } + iov[0].buf = cmdp->param.data; + iov[0].len = cmdp->param.data_len; + iov[0].takeOwn = GiveOwn; cmdp->param.data = 0; - if (socket_write( &ctx->conn, p, cmdp->param.data_len, GiveOwn ) < 0) - return; + ctx->buffer_mem -= cmdp->param.data_len; + iov[1].buf = "\r\n"; + iov[1].len = 2; + iov[1].takeOwn = KeepOwn; + socket_write( &ctx->conn, iov, 2 ); } else if (cmdp->param.cont) { if (cmdp->param.cont( ctx, cmdp, cmd )) return; @@ -1244,8 +1445,7 @@ error( "IMAP error: unexpected command continuation request\n" ); break; } - if (socket_write( &ctx->conn, "\r\n", 2, KeepOwn ) < 0) - return; + socket_expect_read( &ctx->conn, 1 ); } else { tag = atoi( arg ); for (pcmdp = &ctx->in_progress; (cmdp = *pcmdp); pcmdp = &cmdp->next) @@ -1256,7 +1456,8 @@ gottag: if (!(*pcmdp = cmdp->next)) ctx->in_progress_append = pcmdp; - ctx->num_in_progress--; + if (!--ctx->num_in_progress) + socket_expect_read( &ctx->conn, 0 ); arg = next_arg( &cmd ); if (!arg) { error( "IMAP error: malformed tagged response\n" ); @@ -1268,27 +1469,30 @@ resp = RESP_OK; } else { if (!strcmp( "NO", arg )) { - if (cmdp->param.create && - (cmdp->param.trycreate || - (cmd && !memcmp( cmd, "[TRYCREATE]", 11 )))) - { /* SELECT, APPEND or UID COPY */ - struct imap_cmd_trycreate *cmd2 = - (struct imap_cmd_trycreate *)new_imap_cmd( sizeof(*cmd2) ); + if (cmdp->param.create && cmd && starts_with( cmd, -1, "[TRYCREATE]", 11 )) { /* APPEND or UID COPY */ + imap_cmd_trycreate_t *cmd2 = + (imap_cmd_trycreate_t *)new_imap_cmd( sizeof(*cmd2) ); cmd2->orig_cmd = cmdp; cmd2->gen.param.high_prio = 1; p = strchr( cmdp->cmd, '"' ); - if (imap_exec( ctx, &cmd2->gen, get_cmd_result_p2, - "CREATE %.*s", imap_strchr( p + 1, '"' ) - p + 1, p ) < 0) - return; + imap_exec( ctx, &cmd2->gen, get_cmd_result_p2, + "CREATE %.*s", imap_strchr( p + 1, '"' ) - p + 1, p ); continue; } resp = RESP_NO; + if (cmdp->param.failok) + goto doresp; } else /*if (!strcmp( "BAD", arg ))*/ resp = RESP_CANCEL; error( "IMAP command '%s' returned an error: %s %s\n", - memcmp( cmdp->cmd, "LOGIN", 5 ) ? cmdp->cmd : "LOGIN ", + starts_with( cmdp->cmd, -1, "LOGIN", 5 ) ? + "LOGIN " : + starts_with( cmdp->cmd, -1, "AUTHENTICATE PLAIN", 18 ) ? + "AUTHENTICATE PLAIN " : + cmdp->cmd, arg, cmd ? cmd : "" ); } + doresp: if ((resp2 = parse_response_code( ctx, cmdp, cmd )) > resp) resp = resp2; imap_ref( ctx ); @@ -1303,22 +1507,21 @@ return; } } - if (flush_imap_cmds( ctx ) < 0) - return; + flush_imap_cmds( ctx ); } imap_invoke_bad_callback( ctx ); } static void -get_cmd_result_p2( imap_store_t *ctx, struct imap_cmd *cmd, int response ) +get_cmd_result_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response ) { - struct imap_cmd_trycreate *cmdp = (struct imap_cmd_trycreate *)cmd; - struct imap_cmd *ocmd = cmdp->orig_cmd; + imap_cmd_trycreate_t *cmdp = (imap_cmd_trycreate_t *)cmd; + imap_cmd_t *ocmd = cmdp->orig_cmd; if (response != RESP_OK) { done_imap_cmd( ctx, ocmd, response ); } else { - ctx->gen.uidnext = 1; + ctx->uidnext = 1; if (ocmd->param.to_trash) ctx->trashnc = TrashKnown; ocmd->param.create = 0; @@ -1329,20 +1532,30 @@ /******************* imap_cancel_store *******************/ + +static void +imap_cleanup_store( imap_store_t *ctx ) +{ + free_generic_messages( ctx->msgs ); + free_string_list( ctx->boxes ); +} + static void imap_cancel_store( store_t *gctx ) { imap_store_t *ctx = (imap_store_t *)gctx; +#ifdef HAVE_LIBSASL + sasl_dispose( &ctx->sasl ); +#endif socket_close( &ctx->conn ); - cancel_submitted_imap_cmds( ctx ); + cancel_sent_imap_cmds( ctx ); cancel_pending_imap_cmds( ctx ); - free_generic_messages( ctx->gen.msgs ); - free_string_list( ctx->gen.boxes ); free_list( ctx->ns_personal ); free_list( ctx->ns_other ); free_list( ctx->ns_shared ); - free( ctx->delimiter ); + free_string_list( ctx->auth_mechs ); + imap_cleanup_store( ctx ); imap_deref( ctx ); } @@ -1357,12 +1570,21 @@ } static void +imap_set_bad_callback( store_t *gctx, void (*cb)( void *aux ), void *aux ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + ctx->bad_callback = cb; + ctx->bad_callback_aux = aux; +} + +static void imap_invoke_bad_callback( imap_store_t *ctx ) { - ctx->gen.bad_callback( ctx->gen.bad_callback_aux ); + ctx->bad_callback( ctx->bad_callback_aux ); } -/******************* imap_disown_store *******************/ +/******************* imap_free_store *******************/ static store_t *unowned; @@ -1380,18 +1602,20 @@ } static void -imap_disown_store( store_t *gctx ) +imap_free_store( store_t *gctx ) { - free_generic_messages( gctx->msgs ); - gctx->msgs = 0; - set_bad_callback( gctx, imap_cancel_unowned, gctx ); + imap_store_t *ctx = (imap_store_t *)gctx; + + free_generic_messages( ctx->msgs ); + ctx->msgs = 0; + imap_set_bad_callback( gctx, imap_cancel_unowned, gctx ); gctx->next = unowned; unowned = gctx; } /******************* imap_cleanup *******************/ -static void imap_cleanup_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_cleanup_p2( imap_store_t *, imap_cmd_t *, int ); static void imap_cleanup( void ) @@ -1400,114 +1624,113 @@ for (ctx = unowned; ctx; ctx = nctx) { nctx = ctx->next; - set_bad_callback( ctx, (void (*)(void *))imap_cancel_store, ctx ); - imap_exec( (imap_store_t *)ctx, 0, imap_cleanup_p2, "LOGOUT" ); + imap_set_bad_callback( ctx, (void (*)(void *))imap_cancel_store, ctx ); + if (((imap_store_t *)ctx)->state != SST_BAD) { + ((imap_store_t *)ctx)->expectBYE = 1; + imap_exec( (imap_store_t *)ctx, 0, imap_cleanup_p2, "LOGOUT" ); + } else { + imap_cancel_store( ctx ); + } } } static void imap_cleanup_p2( imap_store_t *ctx, - struct imap_cmd *cmd ATTR_UNUSED, int response ) + imap_cmd_t *cmd ATTR_UNUSED, int response ) { - if (response != RESP_CANCEL) + if (response == RESP_NO) imap_cancel_store( &ctx->gen ); + else if (response == RESP_OK) + ctx->expectEOF = 1; } /******************* imap_open_store *******************/ -#ifdef HAVE_LIBSSL -static int -do_cram_auth( imap_store_t *ctx, struct imap_cmd *cmdp, const char *prompt ) -{ - imap_server_conf_t *srvc = ((imap_store_conf_t *)ctx->gen.conf)->server; - char *resp; - int l; - - cmdp->param.cont = 0; - - cram( prompt, srvc->user, srvc->pass, &resp, &l ); - - if (DFlags & VERBOSE) { - printf( "%s>+> %s\n", ctx->label, resp ); - fflush( stdout ); - } - if (socket_write( &ctx->conn, resp, l, GiveOwn ) < 0) - return -1; - return socket_write( &ctx->conn, "\r\n", 2, KeepOwn ); -} -#endif - static void imap_open_store_connected( int, void * ); #ifdef HAVE_LIBSSL static void imap_open_store_tlsstarted1( int, void * ); #endif -static void imap_open_store_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_open_store_p2( imap_store_t *, imap_cmd_t *, int ); static void imap_open_store_authenticate( imap_store_t * ); #ifdef HAVE_LIBSSL -static void imap_open_store_authenticate_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_open_store_authenticate_p2( imap_store_t *, imap_cmd_t *, int ); static void imap_open_store_tlsstarted2( int, void * ); -static void imap_open_store_authenticate_p3( imap_store_t *, struct imap_cmd *, int ); +static void imap_open_store_authenticate_p3( imap_store_t *, imap_cmd_t *, int ); #endif static void imap_open_store_authenticate2( imap_store_t * ); -static void imap_open_store_authenticate2_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_open_store_authenticate2_p2( imap_store_t *, imap_cmd_t *, int ); +static void imap_open_store_compress( imap_store_t * ); +#ifdef HAVE_LIBZ +static void imap_open_store_compress_p2( imap_store_t *, imap_cmd_t *, int ); +#endif static void imap_open_store_namespace( imap_store_t * ); -static void imap_open_store_namespace_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_open_store_namespace_p2( imap_store_t *, imap_cmd_t *, int ); static void imap_open_store_namespace2( imap_store_t * ); static void imap_open_store_finalize( imap_store_t * ); #ifdef HAVE_LIBSSL static void imap_open_store_ssl_bail( imap_store_t * ); #endif -static void imap_open_store_bail( imap_store_t * ); +static void imap_open_store_bail( imap_store_t *, int ); -static void -imap_open_store( store_conf_t *conf, const char *label, - void (*cb)( store_t *srv, void *aux ), void *aux ) +static store_t * +imap_alloc_store( store_conf_t *conf, const char *label ) { imap_store_conf_t *cfg = (imap_store_conf_t *)conf; imap_server_conf_t *srvc = cfg->server; imap_store_t *ctx; store_t **ctxp; + /* First try to recycle a whole store. */ for (ctxp = &unowned; (ctx = (imap_store_t *)*ctxp); ctxp = &ctx->gen.next) - if (ctx->gen.conf == conf) { + if (ctx->state == SST_GOOD && ctx->gen.conf == conf) { *ctxp = ctx->gen.next; ctx->label = label; - cb( &ctx->gen, aux ); - return; + return &ctx->gen; } + + /* Then try to recycle a server connection. */ for (ctxp = &unowned; (ctx = (imap_store_t *)*ctxp); ctxp = &ctx->gen.next) - if (((imap_store_conf_t *)ctx->gen.conf)->server == srvc) { + if (ctx->state != SST_BAD && ((imap_store_conf_t *)ctx->gen.conf)->server == srvc) { *ctxp = ctx->gen.next; - ctx->label = label; + imap_cleanup_store( ctx ); /* One could ping the server here, but given that the idle timeout * is at least 30 minutes, this sounds pretty pointless. */ - free_string_list( ctx->gen.boxes ); - ctx->gen.boxes = 0; - ctx->gen.listed = 0; - ctx->gen.conf = conf; - free( ctx->delimiter ); - ctx->delimiter = 0; - ctx->callbacks.imap_open = cb; - ctx->callback_aux = aux; - set_bad_callback( &ctx->gen, (void (*)(void *))imap_open_store_bail, ctx ); - imap_open_store_namespace( ctx ); - return; + ctx->state = SST_HALF; + goto gotsrv; } + /* Finally, schedule opening a new server connection. */ ctx = nfcalloc( sizeof(*ctx) ); + socket_init( &ctx->conn, &srvc->sconf, + (void (*)( void * ))imap_invoke_bad_callback, + imap_socket_read, (void (*)(void *))flush_imap_cmds, ctx ); + ctx->in_progress_append = &ctx->in_progress; + ctx->pending_append = &ctx->pending; + + gotsrv: + ctx->gen.driver = &imap_driver; ctx->gen.conf = conf; ctx->label = label; ctx->ref_count = 1; - ctx->callbacks.imap_open = cb; - ctx->callback_aux = aux; - set_bad_callback( &ctx->gen, (void (*)(void *))imap_open_store_bail, ctx ); - ctx->in_progress_append = &ctx->in_progress; - ctx->pending_append = &ctx->pending; + return &ctx->gen; +} - socket_init( &ctx->conn, &srvc->sconf, - (void (*)( void * ))imap_invoke_bad_callback, - imap_socket_read, (int (*)(void *))flush_imap_cmds, ctx ); - socket_connect( &ctx->conn, imap_open_store_connected ); +static void +imap_connect_store( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + if (ctx->state == SST_GOOD) { + cb( DRV_OK, aux ); + } else { + ctx->callbacks.imap_open = cb; + ctx->callback_aux = aux; + if (ctx->state == SST_HALF) + imap_open_store_namespace( ctx ); + else + socket_connect( &ctx->conn, imap_open_store_connected ); + } } static void @@ -1520,11 +1743,13 @@ #endif if (!ok) - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_WAIT ); #ifdef HAVE_LIBSSL - else if (srvc->sconf.use_imaps) + else if (srvc->ssl_type == SSL_IMAPS) socket_start_tls( &ctx->conn, imap_open_store_tlsstarted1 ); #endif + else + socket_expect_read( &ctx->conn, 1 ); } #ifdef HAVE_LIBSSL @@ -1535,18 +1760,15 @@ if (!ok) imap_open_store_ssl_bail( ctx ); + else + socket_expect_read( &ctx->conn, 1 ); } #endif static void imap_open_store_greeted( imap_store_t *ctx ) { - if (ctx->greeting == GreetingBad) { - error( "IMAP error: unknown greeting response\n" ); - imap_open_store_bail( ctx ); - return; - } - + socket_expect_read( &ctx->conn, 0 ); if (!ctx->caps) imap_exec( ctx, 0, imap_open_store_p2, "CAPABILITY" ); else @@ -1554,10 +1776,10 @@ } static void -imap_open_store_p2( imap_store_t *ctx, struct imap_cmd *cmd ATTR_UNUSED, int response ) +imap_open_store_p2( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) { if (response == RESP_NO) - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_FINAL ); else if (response == RESP_OK) imap_open_store_authenticate( ctx ); } @@ -1565,40 +1787,43 @@ static void imap_open_store_authenticate( imap_store_t *ctx ) { - if (ctx->greeting != GreetingPreauth) { #ifdef HAVE_LIBSSL - imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf; - imap_server_conf_t *srvc = cfg->server; + imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf; + imap_server_conf_t *srvc = cfg->server; +#endif - if (!srvc->sconf.use_imaps && - (srvc->sconf.use_sslv2 || srvc->sconf.use_sslv3 || srvc->sconf.use_tlsv1)) { - /* always try to select SSL support if available */ + if (ctx->greeting != GreetingPreauth) { +#ifdef HAVE_LIBSSL + if (srvc->ssl_type == SSL_STARTTLS) { if (CAP(STARTTLS)) { imap_exec( ctx, 0, imap_open_store_authenticate_p2, "STARTTLS" ); return; } else { - if (srvc->require_ssl) { - error( "IMAP error: SSL support not available\n" ); - imap_open_store_bail( ctx ); - return; - } else { - warn( "IMAP warning: SSL support not available\n" ); - } + error( "IMAP error: SSL support not available\n" ); + imap_open_store_bail( ctx, FAIL_FINAL ); + return; } } #endif imap_open_store_authenticate2( ctx ); } else { - imap_open_store_namespace( ctx ); +#ifdef HAVE_LIBSSL + if (srvc->ssl_type == SSL_STARTTLS) { + error( "IMAP error: SSL support not available\n" ); + imap_open_store_bail( ctx, FAIL_FINAL ); + return; + } +#endif + imap_open_store_compress( ctx ); } } #ifdef HAVE_LIBSSL static void -imap_open_store_authenticate_p2( imap_store_t *ctx, struct imap_cmd *cmd ATTR_UNUSED, int response ) +imap_open_store_authenticate_p2( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) { if (response == RESP_NO) - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_FINAL ); else if (response == RESP_OK) socket_start_tls( &ctx->conn, imap_open_store_tlsstarted2 ); } @@ -1615,36 +1840,43 @@ } static void -imap_open_store_authenticate_p3( imap_store_t *ctx, struct imap_cmd *cmd ATTR_UNUSED, int response ) +imap_open_store_authenticate_p3( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) { if (response == RESP_NO) - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_FINAL ); else if (response == RESP_OK) imap_open_store_authenticate2( ctx ); } #endif -static void -imap_open_store_authenticate2( imap_store_t *ctx ) +static const char * +ensure_user( imap_server_conf_t *srvc ) { - imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf; - imap_server_conf_t *srvc = cfg->server; - char *arg; - - info ("Logging in...\n"); if (!srvc->user) { error( "Skipping account %s, no user\n", srvc->name ); - goto bail; + return 0; } - if (srvc->pass_cmd) { + return srvc->user; +} + +static const char * +ensure_password( imap_server_conf_t *srvc ) +{ + char *cmd = srvc->pass_cmd; + + if (cmd) { FILE *fp; int ret; char buffer[80]; - if (!(fp = popen( srvc->pass_cmd, "r" ))) { + if (*cmd == '+') { + flushn(); + cmd++; + } + if (!(fp = popen( cmd, "r" ))) { pipeerr: sys_error( "Skipping account %s, password command failed", srvc->name ); - goto bail; + return 0; } if (!fgets( buffer, sizeof(buffer), fp )) buffer[0] = 0; @@ -1655,80 +1887,371 @@ error( "Skipping account %s, password command crashed\n", srvc->name ); else error( "Skipping account %s, password command exited with status %d\n", srvc->name, WEXITSTATUS( ret ) ); - goto bail; + return 0; } if (!buffer[0]) { error( "Skipping account %s, password command produced no output\n", srvc->name ); - goto bail; + return 0; } buffer[strcspn( buffer, "\n" )] = 0; /* Strip trailing newline */ free( srvc->pass ); /* From previous runs */ srvc->pass = nfstrdup( buffer ); } else if (!srvc->pass) { - char prompt[80]; + char *pass, prompt[80]; + + flushn(); sprintf( prompt, "Password (%s): ", srvc->name ); - arg = getpass( prompt ); - if (!arg) { + pass = getpass( prompt ); + if (!pass) { perror( "getpass" ); exit( 1 ); } - if (!*arg) { + if (!*pass) { error( "Skipping account %s, no password\n", srvc->name ); - goto bail; + return 0; } - /* - * getpass() returns a pointer to a static buffer. make a copy - * for long term storage. - */ - srvc->pass = nfstrdup( arg ); + /* getpass() returns a pointer to a static buffer. Make a copy for long term storage. */ + srvc->pass = nfstrdup( pass ); } -#ifdef HAVE_LIBSSL - if (CAP(CRAM)) { - struct imap_cmd *cmd = new_imap_cmd( sizeof(*cmd) ); + return srvc->pass; +} - info( "Authenticating with CRAM-MD5\n" ); - cmd->param.cont = do_cram_auth; - imap_exec( ctx, cmd, imap_open_store_authenticate2_p2, "AUTHENTICATE CRAM-MD5" ); - return; - } - if (srvc->require_cram) { - error( "IMAP error: CRAM-MD5 authentication is not supported by server\n" ); - goto bail; - } -#endif - if (CAP(NOLOGIN)) { - error( "Skipping account %s, server forbids LOGIN\n", srvc->name ); - goto bail; - } -#ifdef HAVE_LIBSSL - if (!ctx->conn.ssl) -#endif - warn( "*** IMAP Warning *** Password is being sent in the clear\n" ); - imap_exec( ctx, 0, imap_open_store_authenticate2_p2, - "LOGIN \"%\\s\" \"%\\s\"", srvc->user, srvc->pass ); - return; +#ifdef HAVE_LIBSASL - bail: - imap_open_store_bail( ctx ); -} +static sasl_callback_t sasl_callbacks[] = { + { SASL_CB_USER, NULL, NULL }, + { SASL_CB_AUTHNAME, NULL, NULL }, + { SASL_CB_PASS, NULL, NULL }, + { SASL_CB_LIST_END, NULL, NULL } +}; -static void -imap_open_store_authenticate2_p2( imap_store_t *ctx, struct imap_cmd *cmd ATTR_UNUSED, int response ) +static int +process_sasl_interact( sasl_interact_t *interact, imap_server_conf_t *srvc ) +{ + const char *val; + + for (;; ++interact) { + switch (interact->id) { + case SASL_CB_LIST_END: + return 0; + case SASL_CB_USER: + case SASL_CB_AUTHNAME: + val = ensure_user( srvc ); + break; + case SASL_CB_PASS: + val = ensure_password( srvc ); + break; + default: + error( "Error: Unknown SASL interaction ID\n" ); + return -1; + } + if (!val) + return -1; + interact->result = val; + interact->len = strlen( val ); + } +} + +static int +process_sasl_step( imap_store_t *ctx, int rc, const char *in, uint in_len, + sasl_interact_t *interact, const char **out, uint *out_len ) +{ + imap_server_conf_t *srvc = ((imap_store_conf_t *)ctx->gen.conf)->server; + + while (rc == SASL_INTERACT) { + if (process_sasl_interact( interact, srvc ) < 0) + return -1; + rc = sasl_client_step( ctx->sasl, in, in_len, &interact, out, out_len ); + } + if (rc == SASL_CONTINUE) { + ctx->sasl_cont = 1; + } else if (rc == SASL_OK) { + ctx->sasl_cont = 0; + } else { + error( "Error: %s\n", sasl_errdetail( ctx->sasl ) ); + return -1; + } + return 0; +} + +static int +decode_sasl_data( const char *prompt, char **in, uint *in_len ) +{ + if (prompt) { + int rc; + uint prompt_len = strlen( prompt ); + /* We're decoding, the output will be shorter than prompt_len. */ + *in = nfmalloc( prompt_len ); + rc = sasl_decode64( prompt, prompt_len, *in, prompt_len, in_len ); + if (rc != SASL_OK) { + free( *in ); + error( "Error: SASL(%d): %s\n", rc, sasl_errstring( rc, NULL, NULL ) ); + return -1; + } + } else { + *in = NULL; + *in_len = 0; + } + return 0; +} + +static int +encode_sasl_data( const char *out, uint out_len, char **enc, uint *enc_len ) +{ + int rc; + uint enc_len_max = ((out_len + 2) / 3) * 4 + 1; + *enc = nfmalloc( enc_len_max ); + rc = sasl_encode64( out, out_len, *enc, enc_len_max, enc_len ); + if (rc != SASL_OK) { + free( *enc ); + error( "Error: SASL(%d): %s\n", rc, sasl_errstring( rc, NULL, NULL ) ); + return -1; + } + return 0; +} + +static int +do_sasl_auth( imap_store_t *ctx, imap_cmd_t *cmdp ATTR_UNUSED, const char *prompt ) +{ + int rc, ret, iovcnt = 0; + uint in_len, out_len, enc_len; + const char *out; + char *in, *enc; + sasl_interact_t *interact = NULL; + conn_iovec_t iov[2]; + + if (!ctx->sasl_cont) { + error( "Error: IMAP wants more steps despite successful SASL authentication.\n" ); + goto bail; + } + if (decode_sasl_data( prompt, &in, &in_len ) < 0) + goto bail; + rc = sasl_client_step( ctx->sasl, in, in_len, &interact, &out, &out_len ); + ret = process_sasl_step( ctx, rc, in, in_len, interact, &out, &out_len ); + free( in ); + if (ret < 0) + goto bail; + + if (out) { + if (encode_sasl_data( out, out_len, &enc, &enc_len ) < 0) + goto bail; + + iov[0].buf = enc; + iov[0].len = enc_len; + iov[0].takeOwn = GiveOwn; + iovcnt = 1; + + if (DFlags & DEBUG_NET) { + printf( "%s>+> %s\n", ctx->label, enc ); + fflush( stdout ); + } + } else { + if (DFlags & DEBUG_NET) { + printf( "%s>+>\n", ctx->label ); + fflush( stdout ); + } + } + iov[iovcnt].buf = "\r\n"; + iov[iovcnt].len = 2; + iov[iovcnt].takeOwn = KeepOwn; + iovcnt++; + socket_write( &ctx->conn, iov, iovcnt ); + return 0; + + bail: + imap_open_store_bail( ctx, FAIL_FINAL ); + return -1; +} + +static void +done_sasl_auth( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) +{ + if (response == RESP_OK && ctx->sasl_cont) { + sasl_interact_t *interact = NULL; + const char *out; + uint out_len; + int rc = sasl_client_step( ctx->sasl, NULL, 0, &interact, &out, &out_len ); + if (process_sasl_step( ctx, rc, NULL, 0, interact, &out, &out_len ) < 0) + warn( "Warning: SASL reported failure despite successful IMAP authentication. Ignoring...\n" ); + else if (out) + warn( "Warning: SASL wants more steps despite successful IMAP authentication. Ignoring...\n" ); + } + + imap_open_store_authenticate2_p2( ctx, NULL, response ); +} + +#endif + +static void +imap_open_store_authenticate2( imap_store_t *ctx ) +{ + imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf; + imap_server_conf_t *srvc = cfg->server; + string_list_t *mech, *cmech; + int auth_login = 0; + int skipped_login = 0; +#ifdef HAVE_LIBSASL + const char *saslavail; + char saslmechs[1024], *saslend = saslmechs; +#endif + + info( "Logging in...\n" ); + for (mech = srvc->auth_mechs; mech; mech = mech->next) { + int any = !strcmp( mech->string, "*" ); + for (cmech = ctx->auth_mechs; cmech; cmech = cmech->next) { + if (any || !strcasecmp( mech->string, cmech->string )) { + if (!strcasecmp( cmech->string, "LOGIN" )) { +#ifdef HAVE_LIBSSL + if (ctx->conn.ssl || !any) +#else + if (!any) +#endif + auth_login = 1; + else + skipped_login = 1; +#ifdef HAVE_LIBSASL + } else { + int len = strlen( cmech->string ); + if (saslend + len + 2 > saslmechs + sizeof(saslmechs)) + oob(); + *saslend++ = ' '; + memcpy( saslend, cmech->string, len + 1 ); + saslend += len; +#endif + } + } + } + } +#ifdef HAVE_LIBSASL + if (saslend != saslmechs) { + int rc; + uint out_len = 0; + char *enc = NULL; + const char *gotmech = NULL, *out = NULL; + sasl_interact_t *interact = NULL; + imap_cmd_t *cmd; + static int sasl_inited; + + if (!sasl_inited) { + rc = sasl_client_init( sasl_callbacks ); + if (rc != SASL_OK) { + saslbail: + error( "Error: SASL(%d): %s\n", rc, sasl_errstring( rc, NULL, NULL ) ); + goto bail; + } + sasl_inited = 1; + } + + rc = sasl_client_new( "imap", srvc->sconf.host, NULL, NULL, NULL, 0, &ctx->sasl ); + if (rc != SASL_OK) { + if (rc == SASL_NOMECH) + goto notsasl; + if (!ctx->sasl) + goto saslbail; + error( "Error: %s\n", sasl_errdetail( ctx->sasl ) ); + goto bail; + } + + rc = sasl_client_start( ctx->sasl, saslmechs + 1, &interact, CAP(SASLIR) ? &out : NULL, &out_len, &gotmech ); + if (rc == SASL_NOMECH) + goto notsasl; + if (gotmech) + info( "Authenticating with SASL mechanism %s...\n", gotmech ); + /* Technically, we are supposed to loop over sasl_client_start(), + * but it just calls sasl_client_step() anyway. */ + if (process_sasl_step( ctx, rc, NULL, 0, interact, CAP(SASLIR) ? &out : NULL, &out_len ) < 0) + goto bail; + if (out) { + if (!out_len) + enc = nfstrdup( "=" ); /* A zero-length initial response is encoded as padding. */ + else if (encode_sasl_data( out, out_len, &enc, NULL ) < 0) + goto bail; + } + + cmd = new_imap_cmd( sizeof(*cmd) ); + cmd->param.cont = do_sasl_auth; + imap_exec( ctx, cmd, done_sasl_auth, enc ? "AUTHENTICATE %s %s" : "AUTHENTICATE %s", gotmech, enc ); + free( enc ); + return; + notsasl: + if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", "", "", &saslavail, NULL, NULL ) != SASL_OK) + saslavail = "(none)"; /* EXTERNAL is always there anyway. */ + if (!auth_login) { + error( "IMAP error: selected SASL mechanism(s) not available;\n" + " selected:%s\n available: %s\n", saslmechs, saslavail ); + goto skipnote; + } + info( "NOT using available SASL mechanism(s): %s\n", saslavail ); + sasl_dispose( &ctx->sasl ); + } +#endif + if (auth_login) { + if (!ensure_user( srvc ) || !ensure_password( srvc )) + goto bail; +#ifdef HAVE_LIBSSL + if (!ctx->conn.ssl) +#endif + warn( "*** IMAP Warning *** Password is being sent in the clear\n" ); + imap_exec( ctx, 0, imap_open_store_authenticate2_p2, + "LOGIN \"%\\s\" \"%\\s\"", srvc->user, srvc->pass ); + return; + } + error( "IMAP error: server supports no acceptable authentication mechanism\n" ); +#ifdef HAVE_LIBSASL + skipnote: +#endif + if (skipped_login) + error( "Note: not using LOGIN because connection is not encrypted;\n" + " use 'AuthMechs LOGIN' explicitly to force it.\n" ); + + bail: + imap_open_store_bail( ctx, FAIL_FINAL ); +} + +static void +imap_open_store_authenticate2_p2( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) { if (response == RESP_NO) - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_FINAL ); else if (response == RESP_OK) + imap_open_store_compress( ctx ); +} + +static void +imap_open_store_compress( imap_store_t *ctx ) +{ +#ifdef HAVE_LIBZ + if (CAP(COMPRESS_DEFLATE)) { + imap_exec( ctx, 0, imap_open_store_compress_p2, "COMPRESS DEFLATE" ); + return; + } +#endif + imap_open_store_namespace( ctx ); +} + +#ifdef HAVE_LIBZ +static void +imap_open_store_compress_p2( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) +{ + if (response == RESP_NO) { + /* We already reported an error, but it's not fatal to us. */ imap_open_store_namespace( ctx ); + } else if (response == RESP_OK) { + socket_start_deflate( &ctx->conn ); + imap_open_store_namespace( ctx ); + } } +#endif static void imap_open_store_namespace( imap_store_t *ctx ) { imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf; + ctx->state = SST_HALF; ctx->prefix = cfg->gen.path; - ctx->delimiter = cfg->delimiter ? nfstrdup( cfg->delimiter ) : 0; - if (((!*ctx->prefix && cfg->use_namespace) || !cfg->delimiter) && CAP(NAMESPACE)) { + ctx->delimiter[0] = cfg->delimiter ? cfg->delimiter : 0; + if (((!ctx->prefix && cfg->use_namespace) || !cfg->delimiter) && CAP(NAMESPACE)) { /* get NAMESPACE info */ if (!ctx->got_namespace) imap_exec( ctx, 0, imap_open_store_namespace_p2, "NAMESPACE" ); @@ -1740,10 +2263,10 @@ } static void -imap_open_store_namespace_p2( imap_store_t *ctx, struct imap_cmd *cmd ATTR_UNUSED, int response ) +imap_open_store_namespace_p2( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response ) { if (response == RESP_NO) { - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_FINAL ); } else if (response == RESP_OK) { ctx->got_namespace = 1; imap_open_store_namespace2( ctx ); @@ -1754,18 +2277,18 @@ imap_open_store_namespace2( imap_store_t *ctx ) { imap_store_conf_t *cfg = (imap_store_conf_t *)ctx->gen.conf; - list_t *nsp, *nsp_1st, *nsp_1st_ns, *nsp_1st_dl; + list_t *nsp, *nsp_1st; /* XXX for now assume 1st personal namespace */ if (is_list( (nsp = ctx->ns_personal) ) && - is_list( (nsp_1st = nsp->child) ) && - is_atom( (nsp_1st_ns = nsp_1st->child) ) && - is_atom( (nsp_1st_dl = nsp_1st_ns->next) )) + is_list( (nsp_1st = nsp->child) )) { - if (!*ctx->prefix && cfg->use_namespace) + list_t *nsp_1st_ns = nsp_1st->child; + list_t *nsp_1st_dl = nsp_1st_ns->next; + if (!ctx->prefix && cfg->use_namespace) ctx->prefix = nsp_1st_ns->val; - if (!ctx->delimiter) - ctx->delimiter = nfstrdup( nsp_1st_dl->val ); + if (!ctx->delimiter[0] && is_atom( nsp_1st_dl )) + ctx->delimiter[0] = nsp_1st_dl->val[0]; } imap_open_store_finalize( ctx ); } @@ -1773,9 +2296,11 @@ static void imap_open_store_finalize( imap_store_t *ctx ) { - set_bad_callback( &ctx->gen, 0, 0 ); + ctx->state = SST_GOOD; + if (!ctx->prefix) + ctx->prefix = ""; ctx->trashnc = TrashUnknown; - ctx->callbacks.imap_open( &ctx->gen, ctx->callback_aux ); + ctx->callbacks.imap_open( DRV_OK, ctx->callback_aux ); } #ifdef HAVE_LIBSSL @@ -1784,143 +2309,339 @@ { /* This avoids that we try to send LOGOUT to an unusable socket. */ socket_close( &ctx->conn ); - imap_open_store_bail( ctx ); + imap_open_store_bail( ctx, FAIL_FINAL ); } #endif static void -imap_open_store_bail( imap_store_t *ctx ) +imap_open_store_bail( imap_store_t *ctx, int failed ) { - void (*cb)( store_t *srv, void *aux ) = ctx->callbacks.imap_open; - void *aux = ctx->callback_aux; - imap_cancel_store( &ctx->gen ); - cb( 0, aux ); + ((imap_store_conf_t *)ctx->gen.conf)->server->failed = failed; + ctx->callbacks.imap_open( DRV_STORE_BAD, ctx->callback_aux ); } -/******************* imap_prepare_opts *******************/ +/******************* imap_open_box *******************/ -static void -imap_prepare_opts( store_t *gctx, int opts ) +static int +imap_select_box( store_t *gctx, const char *name ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + free_generic_messages( ctx->msgs ); + ctx->msgs = 0; + ctx->msgapp = &ctx->msgs; + + ctx->name = name; + return DRV_OK; +} + +static const char * +imap_get_box_path( store_t *gctx ATTR_UNUSED ) { - gctx->opts = opts; + return 0; } -/******************* imap_select *******************/ +typedef struct { + imap_cmd_t gen; + void (*callback)( int sts, int uidvalidity, void *aux ); + void *callback_aux; +} imap_cmd_open_box_t; + +static void imap_open_box_p2( imap_store_t *, imap_cmd_t *, int ); +static void imap_open_box_p3( imap_store_t *, imap_cmd_t *, int ); +static void imap_open_box_p4( imap_store_t *, imap_cmd_open_box_t *, int ); static void -imap_select( store_t *gctx, int create, - void (*cb)( int sts, void *aux ), void *aux ) +imap_open_box( store_t *gctx, + void (*cb)( int sts, int uidvalidity, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; - struct imap_cmd_simple *cmd; + imap_cmd_open_box_t *cmd; char *buf; - free_generic_messages( gctx->msgs ); - gctx->msgs = 0; + if (prepare_box( &buf, ctx ) < 0) { + cb( DRV_BOX_BAD, UIDVAL_BAD, aux ); + return; + } + + ctx->uidvalidity = UIDVAL_BAD; + ctx->uidnext = 0; + + INIT_IMAP_CMD(imap_cmd_open_box_t, cmd, cb, aux) + cmd->gen.param.failok = 1; + imap_exec( ctx, &cmd->gen, imap_open_box_p2, + "SELECT \"%\\s\"", buf ); + free( buf ); +} + +static void +imap_open_box_p2( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) +{ + imap_cmd_open_box_t *cmdp = (imap_cmd_open_box_t *)gcmd; + imap_cmd_open_box_t *cmd; + + if (response != RESP_OK || ctx->uidnext) { + imap_open_box_p4( ctx, cmdp, response ); + return; + } + + INIT_IMAP_CMD(imap_cmd_open_box_t, cmd, cmdp->callback, cmdp->callback_aux) + cmd->gen.param.lastuid = 1; + imap_exec( ctx, &cmd->gen, imap_open_box_p3, + "UID FETCH *:* (UID)" ); +} + +static void +imap_open_box_p3( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) +{ + imap_cmd_open_box_t *cmdp = (imap_cmd_open_box_t *)gcmd; + + // This will happen if the box is empty. + if (!ctx->uidnext) + ctx->uidnext = 1; + + imap_open_box_p4( ctx, cmdp, response ); +} + +static void +imap_open_box_p4( imap_store_t *ctx, imap_cmd_open_box_t *cmdp, int response ) +{ + transform_box_response( &response ); + cmdp->callback( response, ctx->uidvalidity, cmdp->callback_aux ); +} + +static int +imap_get_uidnext( store_t *gctx ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + return ctx->uidnext; +} + +/******************* imap_create_box *******************/ + +static void +imap_create_box( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + imap_cmd_simple_t *cmd; + char *buf; if (prepare_box( &buf, ctx ) < 0) { cb( DRV_BOX_BAD, aux ); return; } - ctx->gen.uidnext = 0; + INIT_IMAP_CMD(imap_cmd_simple_t, cmd, cb, aux) + imap_exec( ctx, &cmd->gen, imap_done_simple_box, + "CREATE \"%\\s\"", buf ); + free( buf ); +} + +/******************* imap_delete_box *******************/ + +static int +imap_confirm_box_empty( store_t *gctx ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + return ctx->total_msgs ? DRV_BOX_BAD : DRV_OK; +} - INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux) - cmd->gen.param.create = create; - cmd->gen.param.trycreate = 1; +static void imap_delete_box_p2( imap_store_t *, imap_cmd_t *, int ); + +static void +imap_delete_box( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + imap_cmd_simple_t *cmd; + + INIT_IMAP_CMD(imap_cmd_simple_t, cmd, cb, aux) + imap_exec( ctx, &cmd->gen, imap_delete_box_p2, "CLOSE" ); +} + +static void +imap_delete_box_p2( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) +{ + imap_cmd_simple_t *cmdp = (imap_cmd_simple_t *)gcmd; + imap_cmd_simple_t *cmd; + char *buf; + + if (response != RESP_OK) { + imap_done_simple_box( ctx, &cmdp->gen, response ); + return; + } + + if (prepare_box( &buf, ctx ) < 0) { + imap_done_simple_box( ctx, &cmdp->gen, RESP_NO ); + return; + } + INIT_IMAP_CMD(imap_cmd_simple_t, cmd, cmdp->callback, cmdp->callback_aux) imap_exec( ctx, &cmd->gen, imap_done_simple_box, - "SELECT \"%\\s\"", buf ); + "DELETE \"%\\s\"", buf ); free( buf ); } -/******************* imap_load *******************/ +static int +imap_finish_delete_box( store_t *gctx ATTR_UNUSED ) +{ + return DRV_OK; +} + +/******************* imap_load_box *******************/ + +static int +imap_prepare_load_box( store_t *gctx, int opts ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + ctx->opts = opts; + return opts; +} + +enum { WantSize = 1, WantTuids = 2, WantMsgids = 4 }; +typedef struct { + int first, last, flags; +} imap_range_t; + +static void +imap_set_range( imap_range_t *ranges, int *nranges, int low_flags, int high_flags, int maxlow ) +{ + if (low_flags != high_flags) { + for (int r = 0; r < *nranges; r++) { + if (ranges[r].first > maxlow) + break; /* Range starts above split point; so do all subsequent ranges. */ + if (ranges[r].last < maxlow) + continue; /* Range ends below split point; try next one. */ + if (ranges[r].last != maxlow) { + /* Range does not end exactly at split point; need to split. */ + memmove( &ranges[r + 1], &ranges[r], ((*nranges)++ - r) * sizeof(*ranges) ); + ranges[r].last = maxlow; + ranges[r + 1].first = maxlow + 1; + } + break; + } + } + for (int r = 0; r < *nranges; r++) + ranges[r].flags |= (ranges[r].last <= maxlow) ? low_flags : high_flags; +} + +typedef struct { + imap_cmd_refcounted_state_t gen; + void (*callback)( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ); + void *callback_aux; +} imap_load_box_state_t; -static int imap_submit_load( imap_store_t *, const char *, int, struct imap_cmd_refcounted_state * ); +static void imap_submit_load( imap_store_t *, const char *, int, imap_load_box_state_t * ); +static void imap_submit_load_p3( imap_store_t *ctx, imap_load_box_state_t * ); static void -imap_load( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int nexcs, - void (*cb)( int sts, void *aux ), void *aux ) +imap_load_box( store_t *gctx, uint minuid, uint maxuid, uint newuid, uint seenuid, uint_array_t excs, + void (*cb)( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; int i, j, bl; char buf[1000]; - if (!ctx->gen.count) { - free( excs ); - cb( DRV_OK, aux ); + if (!ctx->total_msgs) { + free( excs.data ); + cb( DRV_OK, 0, 0, 0, aux ); } else { - struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux ); - - ctx->msgapp = &ctx->gen.msgs; - sort_ints( excs, nexcs ); - for (i = 0; i < nexcs; ) { - for (bl = 0; i < nexcs && bl < 960; i++) { + INIT_REFCOUNTED_STATE(imap_load_box_state_t, sts, cb, aux) + for (i = 0; i < excs.size; ) { + for (bl = 0; i < excs.size && bl < 960; i++) { if (bl) buf[bl++] = ','; - bl += sprintf( buf + bl, "%d", excs[i] ); + bl += sprintf( buf + bl, "%u", excs.data[i] ); j = i; - for (; i + 1 < nexcs && excs[i + 1] == excs[i] + 1; i++) {} + for (; i + 1 < excs.size && excs.data[i + 1] == excs.data[i] + 1; i++) {} if (i != j) - bl += sprintf( buf + bl, ":%d", excs[i] ); + bl += sprintf( buf + bl, ":%u", excs.data[i] ); } - if (imap_submit_load( ctx, buf, 0, sts ) < 0) - goto done; + imap_submit_load( ctx, buf, shifted_bit( ctx->opts, OPEN_OLD_IDS, WantMsgids ), sts ); } - if (maxuid == INT_MAX) - maxuid = ctx->gen.uidnext ? ctx->gen.uidnext - 1 : 1000000000; + if (maxuid == UINT_MAX) + maxuid = ctx->uidnext - 1; if (maxuid >= minuid) { - if ((ctx->gen.opts & OPEN_FIND) && minuid < newuid) { - sprintf( buf, "%d:%d", minuid, newuid - 1 ); - if (imap_submit_load( ctx, buf, 0, sts ) < 0) - goto done; - if (newuid > maxuid) - goto done; - sprintf( buf, "%d:%d", newuid, maxuid ); - } else { - sprintf( buf, "%d:%d", minuid, maxuid ); + imap_range_t ranges[3]; + ranges[0].first = minuid; + ranges[0].last = maxuid; + ranges[0].flags = 0; + int nranges = 1; + if (ctx->opts & (OPEN_OLD_SIZE | OPEN_NEW_SIZE)) + imap_set_range( ranges, &nranges, shifted_bit( ctx->opts, OPEN_OLD_SIZE, WantSize), + shifted_bit( ctx->opts, OPEN_NEW_SIZE, WantSize), seenuid ); + if (ctx->opts & OPEN_FIND) + imap_set_range( ranges, &nranges, 0, WantTuids, newuid - 1 ); + if (ctx->opts & OPEN_OLD_IDS) + imap_set_range( ranges, &nranges, WantMsgids, 0, seenuid ); + for (int r = 0; r < nranges; r++) { + sprintf( buf, "%u:%u", ranges[r].first, ranges[r].last ); + imap_submit_load( ctx, buf, ranges[r].flags, sts ); } - imap_submit_load( ctx, buf, (ctx->gen.opts & OPEN_FIND), sts ); } - done: - free( excs ); - imap_refcounted_done( sts ); + free( excs.data ); + imap_submit_load_p3( ctx, sts ); } } -static int -imap_submit_load( imap_store_t *ctx, const char *buf, int tuids, struct imap_cmd_refcounted_state *sts ) +static void imap_submit_load_p2( imap_store_t *, imap_cmd_t *, int ); + +static void +imap_submit_load( imap_store_t *ctx, const char *buf, int flags, imap_load_box_state_t *sts ) +{ + imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_submit_load_p2, + "UID FETCH %s (UID%s%s%s%s%s%s%s)", buf, + (ctx->opts & OPEN_FLAGS) ? " FLAGS" : "", + (flags & WantSize) ? " RFC822.SIZE" : "", + (flags & (WantTuids | WantMsgids)) ? " BODY.PEEK[HEADER.FIELDS (" : "", + (flags & WantTuids) ? "X-TUID" : "", + !(~flags & (WantTuids | WantMsgids)) ? " " : "", + (flags & WantMsgids) ? "MESSAGE-ID" : "", + (flags & (WantTuids | WantMsgids)) ? ")]" : ""); +} + +static void +imap_submit_load_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response ) { - return imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box, - "UID FETCH %s (UID%s%s%s)", buf, - (ctx->gen.opts & OPEN_FLAGS) ? " FLAGS" : "", - (ctx->gen.opts & OPEN_SIZE) ? " RFC822.SIZE" : "", - tuids ? " BODY.PEEK[HEADER.FIELDS (X-TUID)]" : ""); + imap_load_box_state_t *sts = (imap_load_box_state_t *)((imap_cmd_refcounted_t *)cmd)->state; + + transform_refcounted_box_response( &sts->gen, response ); + imap_submit_load_p3( ctx, sts ); +} + +static void +imap_submit_load_p3( imap_store_t *ctx, imap_load_box_state_t *sts ) +{ + DONE_REFCOUNTED_STATE_ARGS(sts, ctx->msgs, ctx->total_msgs, ctx->recent_msgs) } /******************* imap_fetch_msg *******************/ -static void imap_fetch_msg_p2( imap_store_t *ctx, struct imap_cmd *gcmd, int response ); +static void imap_fetch_msg_p2( imap_store_t *, imap_cmd_t *, int ); static void imap_fetch_msg( store_t *ctx, message_t *msg, msg_data_t *data, void (*cb)( int sts, void *aux ), void *aux ) { - struct imap_cmd_fetch_msg *cmd; + imap_cmd_fetch_msg_t *cmd; - INIT_IMAP_CMD_X(imap_cmd_fetch_msg, cmd, cb, aux) + INIT_IMAP_CMD_X(imap_cmd_fetch_msg_t, cmd, cb, aux) cmd->gen.gen.param.uid = msg->uid; cmd->msg_data = data; data->data = 0; imap_exec( (imap_store_t *)ctx, &cmd->gen.gen, imap_fetch_msg_p2, - "UID FETCH %d (%s%sBODY.PEEK[])", msg->uid, + "UID FETCH %u (%s%sBODY.PEEK[])", msg->uid, !(msg->status & M_FLAGS) ? "FLAGS " : "", (data->date== -1) ? "INTERNALDATE " : "" ); } static void -imap_fetch_msg_p2( imap_store_t *ctx, struct imap_cmd *gcmd, int response ) +imap_fetch_msg_p2( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) { - struct imap_cmd_fetch_msg *cmd = (struct imap_cmd_fetch_msg *)gcmd; + imap_cmd_fetch_msg_t *cmd = (imap_cmd_fetch_msg_t *)gcmd; if (response == RESP_OK && !cmd->msg_data->data) { /* The FETCH succeeded, but there is no message with this UID. */ @@ -1929,15 +2650,13 @@ imap_done_simple_msg( ctx, gcmd, response ); } -/******************* imap_set_flags *******************/ - -static void imap_set_flags_p2( imap_store_t *, struct imap_cmd *, int ); +/******************* imap_set_msg_flags *******************/ static int imap_make_flags( int flags, char *buf ) { const char *s; - unsigned i, d; + uint i, d; for (i = d = 0; i < as(Flags); i++) if (flags & (1 << i)) { @@ -1951,20 +2670,29 @@ return d; } -static int -imap_flags_helper( imap_store_t *ctx, int uid, char what, int flags, - struct imap_cmd_refcounted_state *sts ) +typedef struct { + imap_cmd_refcounted_state_t gen; + void (*callback)( int sts, void *aux ); + void *callback_aux; +} imap_set_msg_flags_state_t; + +static void imap_set_flags_p2( imap_store_t *, imap_cmd_t *, int ); +static void imap_set_flags_p3( imap_set_msg_flags_state_t * ); + +static void +imap_flags_helper( imap_store_t *ctx, uint uid, char what, int flags, + imap_set_msg_flags_state_t *sts ) { char buf[256]; buf[imap_make_flags( flags, buf )] = 0; - return imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_set_flags_p2, - "UID STORE %d %cFLAGS.SILENT %s", uid, what, buf ); + imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_set_flags_p2, + "UID STORE %u %cFLAGS.SILENT %s", uid, what, buf ); } static void -imap_set_flags( store_t *gctx, message_t *msg, int uid, int add, int del, - void (*cb)( int sts, void *aux ), void *aux ) +imap_set_msg_flags( store_t *gctx, message_t *msg, uint uid, int add, int del, + void (*cb)( int sts, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; @@ -1976,73 +2704,97 @@ msg->flags &= ~del; } if (add || del) { - struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux ); - if ((add && imap_flags_helper( ctx, uid, '+', add, sts ) < 0) || - (del && imap_flags_helper( ctx, uid, '-', del, sts ) < 0)) {} - imap_refcounted_done( sts ); + INIT_REFCOUNTED_STATE(imap_set_msg_flags_state_t, sts, cb, aux) + if (add) + imap_flags_helper( ctx, uid, '+', add, sts ); + if (del) + imap_flags_helper( ctx, uid, '-', del, sts ); + imap_set_flags_p3( sts ); } else { cb( DRV_OK, aux ); } } static void -imap_set_flags_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int response ) +imap_set_flags_p2( imap_store_t *ctx ATTR_UNUSED, imap_cmd_t *cmd, int response ) { - struct imap_cmd_refcounted_state *sts = ((struct imap_cmd_refcounted *)cmd)->state; - switch (response) { - case RESP_CANCEL: - sts->ret_val = DRV_CANCELED; - break; - case RESP_NO: - if (sts->ret_val == DRV_OK) /* Don't override cancelation. */ - sts->ret_val = DRV_MSG_BAD; - break; - } - imap_refcounted_done( sts ); + imap_set_msg_flags_state_t *sts = (imap_set_msg_flags_state_t *)((imap_cmd_refcounted_t *)cmd)->state; + + transform_refcounted_msg_response( &sts->gen, response); + imap_set_flags_p3( sts ); +} + +static void +imap_set_flags_p3( imap_set_msg_flags_state_t *sts ) +{ + DONE_REFCOUNTED_STATE(sts) } -/******************* imap_close *******************/ +/******************* imap_close_box *******************/ + +typedef struct { + imap_cmd_refcounted_state_t gen; + void (*callback)( int sts, void *aux ); + void *callback_aux; +} imap_expunge_state_t; + +static void imap_close_box_p2( imap_store_t *, imap_cmd_t *, int ); +static void imap_close_box_p3( imap_expunge_state_t * ); static void -imap_close( store_t *gctx, - void (*cb)( int sts, void *aux ), void *aux ) +imap_close_box( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; if (ctx->gen.conf->trash && CAP(UIDPLUS)) { - struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux ); + INIT_REFCOUNTED_STATE(imap_expunge_state_t, sts, cb, aux) message_t *msg, *fmsg, *nmsg; int bl; char buf[1000]; - for (msg = ctx->gen.msgs; ; ) { + for (msg = ctx->msgs; ; ) { for (bl = 0; msg && bl < 960; msg = msg->next) { if (!(msg->flags & F_DELETED)) continue; if (bl) buf[bl++] = ','; - bl += sprintf( buf + bl, "%d", msg->uid ); + bl += sprintf( buf + bl, "%u", msg->uid ); fmsg = msg; for (; (nmsg = msg->next) && (nmsg->flags & F_DELETED); msg = nmsg) {} if (msg != fmsg) - bl += sprintf( buf + bl, ":%d", msg->uid ); + bl += sprintf( buf + bl, ":%u", msg->uid ); } if (!bl) break; - if (imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box, - "UID EXPUNGE %s", buf ) < 0) - break; + imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_close_box_p2, + "UID EXPUNGE %s", buf ); } - imap_refcounted_done( sts ); + imap_close_box_p3( sts ); } else { /* This is inherently racy: it may cause messages which other clients * marked as deleted to be expunged without being trashed. */ - struct imap_cmd_simple *cmd; - INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux) + imap_cmd_simple_t *cmd; + INIT_IMAP_CMD(imap_cmd_simple_t, cmd, cb, aux) imap_exec( ctx, &cmd->gen, imap_done_simple_box, "CLOSE" ); } } +static void +imap_close_box_p2( imap_store_t *ctx ATTR_UNUSED, imap_cmd_t *cmd, int response ) +{ + imap_expunge_state_t *sts = (imap_expunge_state_t *)((imap_cmd_refcounted_t *)cmd)->state; + + transform_refcounted_box_response( &sts->gen, response ); + imap_close_box_p3( sts ); +} + +static void +imap_close_box_p3( imap_expunge_state_t *sts ) +{ + DONE_REFCOUNTED_STATE(sts) +} + /******************* imap_trash_msg *******************/ static void @@ -2050,10 +2802,10 @@ void (*cb)( int sts, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; - struct imap_cmd_simple *cmd; + imap_cmd_simple_t *cmd; char *buf; - INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux) + INIT_IMAP_CMD(imap_cmd_simple_t, cmd, cb, aux) cmd->gen.param.create = 1; cmd->gen.param.to_trash = 1; if (prepare_trash( &buf, ctx ) < 0) { @@ -2061,13 +2813,13 @@ return; } imap_exec( ctx, &cmd->gen, imap_done_simple_msg, - CAP(MOVE) ? "UID MOVE %d \"%\\s\"" : "UID COPY %d \"%\\s\"", msg->uid, buf ); + CAP(MOVE) ? "UID MOVE %u \"%\\s\"" : "UID COPY %u \"%\\s\"", msg->uid, buf ); free( buf ); } /******************* imap_store_msg *******************/ -static void imap_store_msg_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_store_msg_p2( imap_store_t *, imap_cmd_t *, int ); static size_t my_strftime( char *s, size_t max, const char *fmt, const struct tm *tm ) @@ -2077,10 +2829,10 @@ static void imap_store_msg( store_t *gctx, msg_data_t *data, int to_trash, - void (*cb)( int sts, int uid, void *aux ), void *aux ) + void (*cb)( int sts, uint uid, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; - struct imap_cmd_out_uid *cmd; + imap_cmd_out_uid_t *cmd; char *buf; int d; char flagstr[128], datestr[64]; @@ -2092,10 +2844,11 @@ } flagstr[d] = 0; - INIT_IMAP_CMD(imap_cmd_out_uid, cmd, cb, aux) + INIT_IMAP_CMD(imap_cmd_out_uid_t, cmd, cb, aux) + ctx->buffer_mem += data->len; cmd->gen.param.data_len = data->len; cmd->gen.param.data = data->data; - cmd->out_uid = -2; + cmd->out_uid = 0; if (to_trash) { cmd->gen.param.create = 1; @@ -2123,9 +2876,9 @@ } static void -imap_store_msg_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int response ) +imap_store_msg_p2( imap_store_t *ctx ATTR_UNUSED, imap_cmd_t *cmd, int response ) { - struct imap_cmd_out_uid *cmdp = (struct imap_cmd_out_uid *)cmd; + imap_cmd_out_uid_t *cmdp = (imap_cmd_out_uid_t *)cmd; transform_msg_response( &response ); cmdp->callback( response, cmdp->out_uid, cmdp->callback_aux ); @@ -2133,57 +2886,141 @@ /******************* imap_find_new_msgs *******************/ -static void imap_find_new_msgs_p2( imap_store_t *, struct imap_cmd *, int ); +static void imap_find_new_msgs_p2( imap_store_t *, imap_cmd_t *, int ); +static void imap_find_new_msgs_p3( imap_store_t *, imap_cmd_t *, int ); +static void imap_find_new_msgs_p4( imap_store_t *, imap_cmd_t *, int ); static void -imap_find_new_msgs( store_t *gctx, - void (*cb)( int sts, void *aux ), void *aux ) +imap_find_new_msgs( store_t *gctx, uint newuid, + void (*cb)( int sts, message_t *msgs, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; - struct imap_cmd_simple *cmd; + imap_cmd_find_new_t *cmd; - INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux) + INIT_IMAP_CMD(imap_cmd_find_new_t, cmd, cb, aux) + cmd->out_msgs = ctx->msgapp; + cmd->uid = newuid; + // Some servers fail to enumerate recently STOREd messages without syncing first. imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_find_new_msgs_p2, "CHECK" ); } static void -imap_find_new_msgs_p2( imap_store_t *ctx, struct imap_cmd *gcmd, int response ) +imap_find_new_msgs_p2( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) { - struct imap_cmd_simple *cmdp = (struct imap_cmd_simple *)gcmd, *cmd; + imap_cmd_find_new_t *cmdp = (imap_cmd_find_new_t *)gcmd; + imap_cmd_find_new_t *cmd; if (response != RESP_OK) { imap_done_simple_box( ctx, gcmd, response ); return; } - INIT_IMAP_CMD(imap_cmd_simple, cmd, cmdp->callback, cmdp->callback_aux) - imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_done_simple_box, - "UID FETCH %d:1000000000 (UID BODY.PEEK[HEADER.FIELDS (X-TUID)])", ctx->gen.uidnext ); + + ctx->uidnext = 0; + + INIT_IMAP_CMD(imap_cmd_find_new_t, cmd, cmdp->callback, cmdp->callback_aux) + cmd->out_msgs = cmdp->out_msgs; + cmd->uid = cmdp->uid; + cmd->gen.param.lastuid = 1; + imap_exec( ctx, &cmd->gen, imap_find_new_msgs_p3, + "UID FETCH *:* (UID)" ); } -/******************* imap_list *******************/ +static void +imap_find_new_msgs_p3( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) +{ + imap_cmd_find_new_t *cmdp = (imap_cmd_find_new_t *)gcmd; + imap_cmd_find_new_t *cmd; + + if (response != RESP_OK || ctx->uidnext <= cmdp->uid) { + imap_find_new_msgs_p4( ctx, gcmd, response ); + return; + } + INIT_IMAP_CMD(imap_cmd_find_new_t, cmd, cmdp->callback, cmdp->callback_aux) + cmd->out_msgs = cmdp->out_msgs; + imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_find_new_msgs_p4, + "UID FETCH %u:%u (UID BODY.PEEK[HEADER.FIELDS (X-TUID)])", cmdp->uid, ctx->uidnext - 1 ); +} static void -imap_list( store_t *gctx, int flags, - void (*cb)( int sts, void *aux ), void *aux ) +imap_find_new_msgs_p4( imap_store_t *ctx ATTR_UNUSED, imap_cmd_t *gcmd, int response ) +{ + imap_cmd_find_new_t *cmdp = (imap_cmd_find_new_t *)gcmd; + + transform_box_response( &response ); + cmdp->callback( response, *cmdp->out_msgs, cmdp->callback_aux ); +} + +/******************* imap_list_store *******************/ + +typedef struct { + imap_cmd_refcounted_state_t gen; + void (*callback)( int sts, string_list_t *, void *aux ); + void *callback_aux; +} imap_list_store_state_t; + +static void imap_list_store_p2( imap_store_t *, imap_cmd_t *, int ); +static void imap_list_store_p3( imap_store_t *, imap_list_store_state_t * ); + +static void +imap_list_store( store_t *gctx, int flags, + void (*cb)( int sts, string_list_t *boxes, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; - struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux ); + INIT_REFCOUNTED_STATE(imap_list_store_state_t, sts, cb, aux) + + // ctx->prefix may be empty, "INBOX.", or something else. + // 'flags' may be LIST_INBOX, LIST_PATH (or LIST_PATH_MAYBE), or both. 'listed' + // already containing a particular value effectively removes it from 'flags'. + // This matrix determines what to query, and what comes out as a side effect. + // The lowercase letters indicate unnecessary results; the queries are done + // this way to have non-overlapping result sets, so subsequent calls create + // no duplicates: + // + // qry \ pfx | empty | inbox | other + // ----------+-------+-------+------- + // inbox | p [I] | I [p] | I + // both | P [I] | I [P] | I + P + // path | P [i] | i [P] | P + // + int pfx_is_empty = !*ctx->prefix; + int pfx_is_inbox = !pfx_is_empty && is_inbox( ctx, ctx->prefix, -1 ); + if (((flags & (LIST_PATH | LIST_PATH_MAYBE)) || pfx_is_empty) && !pfx_is_inbox && !(ctx->listed & LIST_PATH)) { + ctx->listed |= LIST_PATH; + if (pfx_is_empty) + ctx->listed |= LIST_INBOX; + imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_list_store_p2, + "LIST \"\" \"%\\s*\"", ctx->prefix ); + } + if (((flags & LIST_INBOX) || pfx_is_inbox) && !pfx_is_empty && !(ctx->listed & LIST_INBOX)) { + ctx->listed |= LIST_INBOX; + if (pfx_is_inbox) + ctx->listed |= LIST_PATH; + imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_list_store_p2, + "LIST \"\" INBOX*" ); + } + imap_list_store_p3( ctx, sts ); +} + +static void +imap_list_store_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response ) +{ + imap_list_store_state_t *sts = (imap_list_store_state_t *)((imap_cmd_refcounted_t *)cmd)->state; + + transform_refcounted_box_response( &sts->gen, response ); + imap_list_store_p3( ctx, sts ); +} - if (((flags & LIST_PATH) && - imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box, - "LIST \"\" \"%\\s*\"", ctx->prefix ) < 0) || - ((flags & LIST_INBOX) && (!(flags & LIST_PATH) || *ctx->prefix) && - imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box, - "LIST \"\" INBOX*" ) < 0)) - {} - imap_refcounted_done( sts ); +static void +imap_list_store_p3( imap_store_t *ctx, imap_list_store_state_t *sts ) +{ + DONE_REFCOUNTED_STATE_ARGS(sts, ctx->boxes) } -/******************* imap_cancel *******************/ +/******************* imap_cancel_cmds *******************/ static void -imap_cancel( store_t *gctx, - void (*cb)( void *aux ), void *aux ) +imap_cancel_cmds( store_t *gctx, + void (*cb)( void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; @@ -2197,14 +3034,32 @@ } } -/******************* imap_commit *******************/ +/******************* imap_commit_cmds *******************/ static void -imap_commit( store_t *gctx ) +imap_commit_cmds( store_t *gctx ) { (void)gctx; } +/******************* imap_get_memory_usage *******************/ + +static int +imap_get_memory_usage( store_t *gctx ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + return ctx->buffer_mem + ctx->conn.buffer_mem; +} + +/******************* imap_get_fail_state *******************/ + +static int +imap_get_fail_state( store_conf_t *gconf ) +{ + return ((imap_store_conf_t *)gconf)->server->failed; +} + /******************* imap_parse_store *******************/ imap_server_conf_t *servers, **serverapp = &servers; @@ -2214,7 +3069,16 @@ { imap_store_conf_t *store; imap_server_conf_t *server, *srv, sserver; + const char *type, *name, *arg; + unsigned u; int acc_opt = 0; +#ifdef HAVE_LIBSSL + /* Legacy SSL options */ + int require_ssl = -1, use_imaps = -1; + int use_sslv2 = -1, use_sslv3 = -1, use_tlsv1 = -1, use_tlsv11 = -1, use_tlsv12 = -1; +#endif + /* Legacy SASL option */ + int require_cram = -1; if (!strcasecmp( "IMAPAccount", cfg->cmd )) { server = nfcalloc( sizeof(*server) ); @@ -2234,33 +3098,33 @@ } else return 0; + server->sconf.timeout = 20; #ifdef HAVE_LIBSSL - /* this will probably annoy people, but its the best default just in - * case people forget to turn it on - */ - server->require_ssl = 1; - server->sconf.use_tlsv1 = 1; + server->ssl_type = -1; + server->sconf.ssl_versions = -1; + server->sconf.system_certs = 1; #endif server->max_in_progress = INT_MAX; while (getcline( cfg ) && cfg->cmd) { if (!strcasecmp( "Host", cfg->cmd )) { /* The imap[s]: syntax is just a backwards compat hack. */ + arg = cfg->val; #ifdef HAVE_LIBSSL - if (!memcmp( "imaps:", cfg->val, 6 )) { - cfg->val += 6; - server->sconf.use_imaps = 1; - server->sconf.use_sslv2 = 1; - server->sconf.use_sslv3 = 1; + if (starts_with( arg, -1, "imaps:", 6 )) { + arg += 6; + server->ssl_type = SSL_IMAPS; + if (server->sconf.ssl_versions == -1) + server->sconf.ssl_versions = SSLv2 | SSLv3 | TLSv1; } else #endif - { - if (!memcmp( "imap:", cfg->val, 5 )) - cfg->val += 5; - } - if (!memcmp( "//", cfg->val, 2 )) - cfg->val += 2; - server->sconf.host = nfstrdup( cfg->val ); + if (starts_with( arg, -1, "imap:", 5 )) + arg += 5; + if (starts_with( arg, -1, "//", 2 )) + arg += 2; + if (arg != cfg->val) + warn( "%s:%d: Notice: URL notation is deprecated; use a plain host name and possibly 'SSLType IMAPS' instead\n", cfg->file, cfg->line ); + server->sconf.host = nfstrdup( arg ); } else if (!strcasecmp( "User", cfg->cmd )) server->user = nfstrdup( cfg->val ); @@ -2270,11 +3134,27 @@ server->pass_cmd = nfstrdup( cfg->val ); else if (!strcasecmp( "Port", cfg->cmd )) server->sconf.port = parse_int( cfg ); + else if (!strcasecmp( "Timeout", cfg->cmd )) + server->sconf.timeout = parse_int( cfg ); else if (!strcasecmp( "PipelineDepth", cfg->cmd )) { if ((server->max_in_progress = parse_int( cfg )) < 1) { error( "%s:%d: PipelineDepth must be at least 1\n", cfg->file, cfg->line ); cfg->err = 1; } + } else if (!strcasecmp( "DisableExtension", cfg->cmd ) || + !strcasecmp( "DisableExtensions", cfg->cmd )) { + arg = cfg->val; + do { + for (u = 0; u < as(cap_list); u++) { + if (!strcasecmp( cap_list[u], arg )) { + server->cap_mask |= 1 << u; + goto gotcap; + } + } + error( "%s:%d: Unrecognized IMAP extension '%s'\n", cfg->file, cfg->line, arg ); + cfg->err = 1; + gotcap: ; + } while ((arg = get_arg( cfg, ARG_OPTIONAL, 0 ))); } #ifdef HAVE_LIBSSL else if (!strcasecmp( "CertificateFile", cfg->cmd )) { @@ -2284,23 +3164,76 @@ cfg->file, cfg->line, server->sconf.cert_file ); cfg->err = 1; } + } else if (!strcasecmp( "SystemCertificates", cfg->cmd )) { + server->sconf.system_certs = parse_bool( cfg ); + } else if (!strcasecmp( "ClientCertificate", cfg->cmd )) { + server->sconf.client_certfile = expand_strdup( cfg->val ); + if (access( server->sconf.client_certfile, R_OK )) { + sys_error( "%s:%d: ClientCertificate '%s'", + cfg->file, cfg->line, server->sconf.client_certfile ); + cfg->err = 1; + } + } else if (!strcasecmp( "ClientKey", cfg->cmd )) { + server->sconf.client_keyfile = expand_strdup( cfg->val ); + if (access( server->sconf.client_keyfile, R_OK )) { + sys_error( "%s:%d: ClientKey '%s'", + cfg->file, cfg->line, server->sconf.client_keyfile ); + cfg->err = 1; + } + } else if (!strcasecmp( "SSLType", cfg->cmd )) { + if (!strcasecmp( "None", cfg->val )) { + server->ssl_type = SSL_None; + } else if (!strcasecmp( "STARTTLS", cfg->val )) { + server->ssl_type = SSL_STARTTLS; + } else if (!strcasecmp( "IMAPS", cfg->val )) { + server->ssl_type = SSL_IMAPS; + } else { + error( "%s:%d: Invalid SSL type\n", cfg->file, cfg->line ); + cfg->err = 1; + } + } else if (!strcasecmp( "SSLVersion", cfg->cmd ) || + !strcasecmp( "SSLVersions", cfg->cmd )) { + server->sconf.ssl_versions = 0; + arg = cfg->val; + do { + if (!strcasecmp( "SSLv2", arg )) { + server->sconf.ssl_versions |= SSLv2; + } else if (!strcasecmp( "SSLv3", arg )) { + server->sconf.ssl_versions |= SSLv3; + } else if (!strcasecmp( "TLSv1", arg )) { + server->sconf.ssl_versions |= TLSv1; + } else if (!strcasecmp( "TLSv1.1", arg )) { + server->sconf.ssl_versions |= TLSv1_1; + } else if (!strcasecmp( "TLSv1.2", arg )) { + server->sconf.ssl_versions |= TLSv1_2; + } else { + error( "%s:%d: Unrecognized SSL version\n", cfg->file, cfg->line ); + cfg->err = 1; + } + } while ((arg = get_arg( cfg, ARG_OPTIONAL, 0 ))); } else if (!strcasecmp( "RequireSSL", cfg->cmd )) - server->require_ssl = parse_bool( cfg ); + require_ssl = parse_bool( cfg ); else if (!strcasecmp( "UseIMAPS", cfg->cmd )) - server->sconf.use_imaps = parse_bool( cfg ); + use_imaps = parse_bool( cfg ); else if (!strcasecmp( "UseSSLv2", cfg->cmd )) - server->sconf.use_sslv2 = parse_bool( cfg ); + use_sslv2 = parse_bool( cfg ); else if (!strcasecmp( "UseSSLv3", cfg->cmd )) - server->sconf.use_sslv3 = parse_bool( cfg ); + use_sslv3 = parse_bool( cfg ); else if (!strcasecmp( "UseTLSv1", cfg->cmd )) - server->sconf.use_tlsv1 = parse_bool( cfg ); + use_tlsv1 = parse_bool( cfg ); else if (!strcasecmp( "UseTLSv1.1", cfg->cmd )) - server->sconf.use_tlsv11 = parse_bool( cfg ); + use_tlsv11 = parse_bool( cfg ); else if (!strcasecmp( "UseTLSv1.2", cfg->cmd )) - server->sconf.use_tlsv12 = parse_bool( cfg ); - else if (!strcasecmp( "RequireCRAM", cfg->cmd )) - server->require_cram = parse_bool( cfg ); + use_tlsv12 = parse_bool( cfg ); #endif + else if (!strcasecmp( "AuthMech", cfg->cmd ) || + !strcasecmp( "AuthMechs", cfg->cmd )) { + arg = cfg->val; + do + add_string_list( &server->auth_mechs, arg ); + while ((arg = get_arg( cfg, ARG_OPTIONAL, 0 ))); + } else if (!strcasecmp( "RequireCRAM", cfg->cmd )) + require_cram = parse_bool( cfg ); else if (!strcasecmp( "Tunnel", cfg->cmd )) server->sconf.tunnel = nfstrdup( cfg->val ); else if (store) { @@ -2317,9 +3250,14 @@ store->use_namespace = parse_bool( cfg ); else if (!strcasecmp( "Path", cfg->cmd )) store->gen.path = nfstrdup( cfg->val ); - else if (!strcasecmp( "PathDelimiter", cfg->cmd )) - store->delimiter = nfstrdup( cfg->val ); - else + else if (!strcasecmp( "PathDelimiter", cfg->cmd )) { + if (strlen( cfg->val ) != 1) { + error( "%s:%d: Path delimiter must be exactly one character long\n", cfg->file, cfg->line ); + cfg->err = 1; + continue; + } + store->delimiter = cfg->val[0]; + } else parse_generic_store( &store->gen, cfg ); continue; } else { @@ -2329,23 +3267,75 @@ } acc_opt = 1; } + if (store) + type = "IMAP store", name = store->gen.name; + else + type = "IMAP account", name = server->name; if (!store || !store->server) { if (!server->sconf.tunnel && !server->sconf.host) { - if (store) - error( "IMAP store '%s' has incomplete/missing connection details\n", store->gen.name ); - else - error( "IMAP account '%s' has incomplete/missing connection details\n", server->name ); + error( "%s '%s' has neither Tunnel nor Host\n", type, name ); cfg->err = 1; return 1; } if (server->pass && server->pass_cmd) { - if (store) - error( "IMAP store '%s' has both Pass and PassCmd\n", store->gen.name ); - else - error( "IMAP account '%s' has both Pass and PassCmd\n", server->name ); + error( "%s '%s' has both Pass and PassCmd\n", type, name ); cfg->err = 1; return 1; } +#ifdef HAVE_LIBSSL + if ((use_sslv2 & use_sslv3 & use_tlsv1 & use_tlsv11 & use_tlsv12) != -1 || use_imaps >= 0 || require_ssl >= 0) { + if (server->ssl_type >= 0 || server->sconf.ssl_versions >= 0) { + error( "%s '%s': The deprecated UseSSL*, UseTLS*, UseIMAPS, and RequireSSL options are mutually exlusive with SSLType and SSLVersions.\n", type, name ); + cfg->err = 1; + return 1; + } + warn( "Notice: %s '%s': UseSSL*, UseTLS*, UseIMAPS, and RequireSSL are deprecated. Use SSLType and SSLVersions instead.\n", type, name ); + server->sconf.ssl_versions = + (use_sslv2 != 1 ? 0 : SSLv2) | + (use_sslv3 != 1 ? 0 : SSLv3) | + (use_tlsv1 == 0 ? 0 : TLSv1) | + (use_tlsv11 != 1 ? 0 : TLSv1_1) | + (use_tlsv12 != 1 ? 0 : TLSv1_2); + if (use_imaps == 1) { + server->ssl_type = SSL_IMAPS; + } else if (require_ssl) { + server->ssl_type = SSL_STARTTLS; + } else if (!server->sconf.ssl_versions) { + server->ssl_type = SSL_None; + } else { + warn( "Notice: %s '%s': 'RequireSSL no' is being ignored\n", type, name ); + server->ssl_type = SSL_STARTTLS; + } + if (server->ssl_type != SSL_None && !server->sconf.ssl_versions) { + error( "%s '%s' requires SSL but no SSL versions enabled\n", type, name ); + cfg->err = 1; + return 1; + } + } else { + if (server->sconf.ssl_versions < 0) + server->sconf.ssl_versions = TLSv1; /* Most compatible and still reasonably secure. */ + if (server->ssl_type < 0) + server->ssl_type = server->sconf.tunnel ? SSL_None : SSL_STARTTLS; + } +#endif + if (require_cram >= 0) { + if (server->auth_mechs) { + error( "%s '%s': The deprecated RequireCRAM option is mutually exlusive with AuthMech.\n", type, name ); + cfg->err = 1; + return 1; + } + warn( "Notice: %s '%s': RequireCRAM is deprecated. Use AuthMech instead.\n", type, name ); + if (require_cram) + add_string_list(&server->auth_mechs, "CRAM-MD5"); + } + if (!server->auth_mechs) + add_string_list( &server->auth_mechs, "*" ); + if (!server->sconf.port) + server->sconf.port = +#ifdef HAVE_LIBSSL + server->ssl_type == SSL_IMAPS ? 993 : +#endif + 143; } if (store) { if (!store->server) { @@ -2353,30 +3343,47 @@ memcpy( store->server, &sserver, sizeof(sserver) ); store->server->name = store->gen.name; } else if (acc_opt) { - error( "IMAP store '%s' has both Account and account-specific options\n", store->gen.name ); + error( "%s '%s' has both Account and account-specific options\n", type, name ); cfg->err = 1; } } return 1; } +static int +imap_get_caps( store_t *gctx ATTR_UNUSED ) +{ + return DRV_CRLF | DRV_VERBOSE; +} + struct driver imap_driver = { - DRV_CRLF | DRV_VERBOSE, + imap_get_caps, imap_parse_store, imap_cleanup, - imap_open_store, - imap_disown_store, + imap_alloc_store, + imap_set_bad_callback, + imap_connect_store, + imap_free_store, imap_cancel_store, - imap_list, - imap_prepare_opts, - imap_select, - imap_load, + imap_list_store, + imap_select_box, + imap_get_box_path, + imap_create_box, + imap_open_box, + imap_get_uidnext, + imap_confirm_box_empty, + imap_delete_box, + imap_finish_delete_box, + imap_prepare_load_box, + imap_load_box, imap_fetch_msg, imap_store_msg, imap_find_new_msgs, - imap_set_flags, + imap_set_msg_flags, imap_trash_msg, - imap_close, - imap_cancel, - imap_commit, + imap_close_box, + imap_cancel_cmds, + imap_commit_cmds, + imap_get_memory_usage, + imap_get_fail_state, }; diff -Nru isync-1.1.0/src/drv_maildir.c isync-1.2.1-1.812.20170514/src/drv_maildir.c --- isync-1.1.0/src/drv_maildir.c 2013-12-18 17:58:26.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/drv_maildir.c 2017-05-26 14:36:31.000000000 +0000 @@ -33,17 +33,11 @@ #include #include #include -#include #include #include #include -#define USE_DB 1 -#ifdef __linux__ -# define LEGACY_FLOCK 1 -#endif - -#ifndef _POSIX_SYNCHRONIZED_IO +#if !defined(_POSIX_SYNCHRONIZED_IO) || _POSIX_SYNCHRONIZED_IO <= 0 # define fdatasync fsync #endif @@ -51,27 +45,50 @@ #include #endif /* USE_DB */ -typedef struct maildir_store_conf { +#define SUB_UNSET 0 +#define SUB_VERBATIM 1 +#define SUB_MAILDIRPP 2 +#define SUB_LEGACY 3 + +typedef struct { store_conf_t gen; char *inbox; #ifdef USE_DB int alt_map; #endif /* USE_DB */ + char info_delimiter; + char sub_style; + char failed; + char *info_prefix, *info_stop; /* precalculated from info_delimiter */ } maildir_store_conf_t; -typedef struct maildir_message { +typedef struct { message_t gen; char *base; } maildir_message_t; -typedef struct maildir_store { +typedef struct { store_t gen; - int uvfd, uvok, nuid, fresh; - int minuid, maxuid, newuid, nexcs, *excs; + uint opts; + int uvfd, uvok, is_inbox, fresh[3]; + uint minuid, maxuid, newuid, seenuid, uidvalidity, nuid; + uint_array_t excs; + char *path; /* own */ char *trash; #ifdef USE_DB DB *db; + char *usedb; #endif /* USE_DB */ + string_list_t *boxes; // _list results + char listed; // was _list already run with these flags? + // note that the message counts do _not_ reflect stats from msgs, + // but mailbox totals. also, don't trust them beyond the initial load. + int total_msgs, recent_msgs; + message_t *msgs; + wakeup_t lcktmr; + + void (*bad_callback)( void *aux ); + void *bad_callback_aux; } maildir_store_t; #ifdef USE_DB @@ -81,64 +98,157 @@ static int MaildirCount; +static void ATTR_PRINTFLIKE(1, 2) +debug( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vdebug( DEBUG_SYNC, msg, va ); + va_end( va ); +} + static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' }; -static unsigned char -maildir_parse_flags( const char *base ) +static uchar +maildir_parse_flags( const char *info_prefix, const char *base ) { const char *s; - unsigned i; - unsigned char flags; + uint i; + uchar flags; flags = 0; - if ((s = strstr( base, ":2," ))) + if ((s = strstr( base, info_prefix ))) for (s += 3, i = 0; i < as(Flags); i++) if (strchr( s, Flags[i] )) flags |= (1 << i); return flags; } +static int +maildir_ensure_path( maildir_store_conf_t *conf ) +{ + if (!conf->gen.path) { + error( "Maildir error: store '%s' has no Path\n", conf->gen.name ); + conf->failed = FAIL_FINAL; + return -1; + } + return 0; +} + +/* Subdirs of INBOX include a leading slash. */ +/* Path includes a trailing slash, Inbox does not. */ static char * -maildir_join_path( const char *prefix, const char *box ) +maildir_join_path( maildir_store_conf_t *conf, int in_inbox, const char *box ) { char *out, *p; + const char *prefix; int pl, bl, n; char c; + if (in_inbox || conf->sub_style == SUB_MAILDIRPP) { + prefix = conf->inbox; + } else { + if (maildir_ensure_path( conf ) < 0) + return 0; + prefix = conf->gen.path; + } pl = strlen( prefix ); for (bl = 0, n = 0; (c = box[bl]); bl++) - if (c == '/') + if (c == '/') { + if (conf->sub_style == SUB_UNSET) { + error( "Maildir error: accessing subfolder '%s', but store '%s' does not specify SubFolders style\n", + box, conf->gen.name ); + return 0; + } n++; + } else if (c == '.' && conf->sub_style == SUB_MAILDIRPP) { + error( "Maildir error: store '%s', folder '%s': SubFolders style Maildir++ does not support dots in mailbox names\n", + conf->gen.name, box ); + return 0; + } + switch (conf->sub_style) { + case SUB_VERBATIM: + n = 0; + break; + case SUB_MAILDIRPP: + n = 2; + break; + default: /* SUB_LEGACY and SUB_UNSET */ + break; + } out = nfmalloc( pl + bl + n + 1 ); memcpy( out, prefix, pl ); p = out + pl; + if (conf->sub_style == SUB_MAILDIRPP) { + *p++ = '/'; + *p++ = '.'; + } while ((c = *box++)) { - *p++ = c; - if (c == '/') - *p++ = '.'; + if (c == '/') { + switch (conf->sub_style) { + case SUB_VERBATIM: + *p++ = c; + break; + case SUB_LEGACY: + *p++ = c; + /* fallthrough */ + default: /* SUB_MAILDIRPP */ + *p++ = '.'; + break; + } + } else { + *p++ = c; + } } *p = 0; return out; } -static void -maildir_open_store( store_conf_t *conf, const char *label ATTR_UNUSED, - void (*cb)( store_t *ctx, void *aux ), void *aux ) +static int +maildir_validate_path( maildir_store_conf_t *conf ) { - maildir_store_t *ctx; struct stat st; - if (stat( conf->path, &st ) || !S_ISDIR(st.st_mode)) { - error( "Maildir error: cannot open store '%s'\n", conf->path ); - cb( 0, aux ); - return; + if (stat( conf->gen.path, &st ) || !S_ISDIR(st.st_mode)) { + error( "Maildir error: cannot open store '%s'\n", conf->gen.path ); + conf->failed = FAIL_FINAL; + return -1; } + return 0; +} + +static void lcktmr_timeout( void *aux ); + +static store_t * +maildir_alloc_store( store_conf_t *gconf, const char *label ATTR_UNUSED ) +{ + maildir_store_t *ctx; + ctx = nfcalloc( sizeof(*ctx) ); - ctx->gen.conf = conf; + ctx->gen.driver = &maildir_driver; + ctx->gen.conf = gconf; ctx->uvfd = -1; - if (conf->trash) - ctx->trash = maildir_join_path( conf->path, conf->trash ); - cb( &ctx->gen, aux ); + init_wakeup( &ctx->lcktmr, lcktmr_timeout, ctx ); + return &ctx->gen; +} + +static void +maildir_connect_store( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + maildir_store_conf_t *conf = (maildir_store_conf_t *)ctx->gen.conf; + + if (conf->gen.path && maildir_validate_path( conf ) < 0) { + cb( DRV_STORE_BAD, aux ); + return; + } + if (conf->gen.trash && !(ctx->trash = maildir_join_path( conf, 0, conf->gen.trash ))) { + cb( DRV_STORE_BAD, aux ); + return; + } + cb( DRV_OK, aux ); } static void @@ -158,23 +268,28 @@ { maildir_store_t *ctx = (maildir_store_t *)gctx; - free_maildir_messages( gctx->msgs ); + free_maildir_messages( ctx->msgs ); #ifdef USE_DB if (ctx->db) ctx->db->close( ctx->db, 0 ); + free( ctx->usedb ); #endif /* USE_DB */ - free( gctx->path ); - free( ctx->excs ); + free( ctx->path ); + free( ctx->excs.data ); if (ctx->uvfd >= 0) close( ctx->uvfd ); + conf_wakeup( &ctx->lcktmr, -1 ); } static void -maildir_disown_store( store_t *gctx ) +maildir_free_store( store_t *gctx ) { + maildir_store_t *ctx = (maildir_store_t *)gctx; + maildir_cleanup( gctx ); - free( ((maildir_store_t *)gctx)->trash ); - free_string_list( gctx->boxes ); + wipe_wakeup( &ctx->lcktmr ); + free( ctx->trash ); + free_string_list( ctx->boxes ); free( gctx ); } @@ -184,62 +299,160 @@ } static void -maildir_invoke_bad_callback( store_t *ctx ) +maildir_set_bad_callback( store_t *gctx, void (*cb)( void *aux ), void *aux ) { - ctx->bad_callback( ctx->bad_callback_aux ); + maildir_store_t *ctx = (maildir_store_t *)gctx; + + ctx->bad_callback = cb; + ctx->bad_callback_aux = aux; } -static int maildir_list_inbox( store_t *gctx, int *flags ); +static void +maildir_invoke_bad_callback( maildir_store_t *ctx ) +{ + ctx->bad_callback( ctx->bad_callback_aux ); +} static int -maildir_list_recurse( store_t *gctx, int isBox, int *flags, const char *inbox, - char *path, int pathLen, char *name, int nameLen ) +maildir_list_maildirpp( maildir_store_t *ctx, int flags, const char *inbox ) { DIR *dir; - int pl, nl, missing; struct dirent *de; + int warned = 0; struct stat st; - if (isBox) { - path[pathLen++] = '/'; - nfsnprintf( path + pathLen, _POSIX_PATH_MAX - pathLen, "cur" ); - missing = stat( path, &st ) || !S_ISDIR(st.st_mode); - if (!missing || isBox > 1) - add_string_list( &gctx->boxes, name ); - if (missing) + if (ctx->listed & LIST_PATH) // Implies LIST_INBOX + return 0; + + if (!(ctx->listed & LIST_INBOX)) + add_string_list( &ctx->boxes, "INBOX" ); + + char path[_POSIX_PATH_MAX]; + int pathLen = nfsnprintf( path, _POSIX_PATH_MAX, "%s/", inbox ); + if (!(dir = opendir( path ))) { + if (errno == ENOENT || errno == ENOTDIR) return 0; - path[pathLen] = 0; - name[nameLen++] = '/'; + sys_error( "Maildir error: cannot list %s", path ); + return -1; + } + while ((de = readdir( dir ))) { + const char *ent = de->d_name; + if (*ent++ != '.' || !*ent) + continue; + char name[_POSIX_PATH_MAX]; + char *effName = name; + if (*ent == '.') { + if (ctx->listed & LIST_INBOX) + continue; + if (!*++ent) + continue; + // The Maildir++ Inbox is technically not under Path (as there is none), so + // "*" would never match INBOX*, which is rather unintuitive. Matching INBOX* + // implicitly instead makes it consistent with an IMAP Store with an empty Path. + } else { + if (!(flags & (LIST_PATH | LIST_PATH_MAYBE))) + continue; + if (starts_with( ent, -1, "INBOX", 5 ) && (!ent[5] || ent[5] == '.')) { + if (!warned) { + warned = 1; + path[pathLen] = 0; + warn( "Maildir warning: ignoring INBOX in %s\n", path ); + } + continue; + } + effName += 6; + } + nfsnprintf( path + pathLen, _POSIX_PATH_MAX - pathLen, "%s/cur", de->d_name ); + if (!stat( path, &st ) && S_ISDIR(st.st_mode)) { + int nl = nfsnprintf( name, _POSIX_PATH_MAX, "INBOX/%s", ent ); + for (int i = 6; i < nl; i++) { + if (name[i] == '.') + name[i] = '/'; + } + add_string_list( &ctx->boxes, effName ); + } } + closedir (dir); + + if (flags & (LIST_PATH | LIST_PATH_MAYBE)) + ctx->listed |= LIST_PATH; + ctx->listed |= LIST_INBOX; + return 0; +} + +static int maildir_list_inbox( maildir_store_t *ctx, int flags, const char *basePath ); +static int maildir_list_path( maildir_store_t *ctx, int flags, const char *inbox ); + +static int +maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags, + const char *inbox, int inboxLen, const char *basePath, int basePathLen, + char *path, int pathLen, char *name, int nameLen ) +{ + DIR *dir; + int style = ((maildir_store_conf_t *)ctx->gen.conf)->sub_style; + int pl, nl; + struct dirent *de; + struct stat st; + if (!(dir = opendir( path ))) { + if (isBox && (errno == ENOENT || errno == ENOTDIR)) + return 0; sys_error( "Maildir error: cannot list %s", path ); return -1; } + if (isBox > 1 && style == SUB_UNSET) { + error( "Maildir error: found subfolder '%.*s', but store '%s' does not specify SubFolders style\n", + nameLen - 1, name, ctx->gen.conf->name ); + closedir( dir ); + return -1; + } while ((de = readdir( dir ))) { const char *ent = de->d_name; - pl = pathLen + nfsnprintf( path + pathLen, _POSIX_PATH_MAX - pathLen, "%s", ent ); - if (inbox && !memcmp( path, inbox, pl ) && !inbox[pl]) { - if (maildir_list_inbox( gctx, flags ) < 0) + if (ent[0] == '.' && (!ent[1] || (ent[1] == '.' && !ent[2]))) + continue; + pl = nfsnprintf( path + pathLen, _POSIX_PATH_MAX - pathLen, "%s", ent ); + if (pl == 3 && (!memcmp( ent, "cur", 3 ) || !memcmp( ent, "new", 3 ) || !memcmp( ent, "tmp", 3 ))) + continue; + pl += pathLen; + if (inbox && equals( path, pl, inbox, inboxLen )) { + // Inbox nested into Path. + if (maildir_list_inbox( ctx, flags, 0 ) < 0) { + closedir( dir ); + return -1; + } + } else if (basePath && equals( path, pl, basePath, basePathLen )) { + // Path nested into Inbox. + if (maildir_list_path( ctx, flags, 0 ) < 0) { + closedir( dir ); return -1; + } } else { - if (*ent == '.') { - if (!isBox) - continue; - if (!ent[1] || ent[1] == '.') - continue; - ent++; - } else { - if (isBox) - continue; - if (!memcmp( ent, "INBOX", 6 )) { - path[pathLen] = 0; - warn( "Maildir warning: ignoring INBOX in %s\n", path ); - continue; + if (style == SUB_LEGACY) { + if (*ent == '.') { + if (!isBox) + continue; + ent++; + } else { + if (isBox) + continue; } } + if (!nameLen && equals( ent, -1, "INBOX", 5 )) { + path[pathLen] = 0; + warn( "Maildir warning: ignoring INBOX in %s\n", path ); + continue; + } nl = nameLen + nfsnprintf( name + nameLen, _POSIX_PATH_MAX - nameLen, "%s", ent ); - if (maildir_list_recurse( gctx, 1, flags, inbox, path, pl, name, nl ) < 0) + path[pl++] = '/'; + nfsnprintf( path + pl, _POSIX_PATH_MAX - pl, "cur" ); + if (!stat( path, &st ) && S_ISDIR(st.st_mode)) + add_string_list( &ctx->boxes, name ); + path[pl] = 0; + name[nl++] = '/'; + if (maildir_list_recurse( ctx, isBox + 1, flags, inbox, inboxLen, basePath, basePathLen, path, pl, name, nl ) < 0) { + closedir( dir ); return -1; + } } } closedir (dir); @@ -247,38 +460,55 @@ } static int -maildir_list_inbox( store_t *gctx, int *flags ) +maildir_list_inbox( maildir_store_t *ctx, int flags, const char *basePath ) { char path[_POSIX_PATH_MAX], name[_POSIX_PATH_MAX]; - *flags &= ~LIST_INBOX; + if (ctx->listed & LIST_INBOX) + return 0; + ctx->listed |= LIST_INBOX; + + add_string_list( &ctx->boxes, "INBOX" ); return maildir_list_recurse( - gctx, 2, flags, 0, - path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", ((maildir_store_conf_t *)gctx->conf)->inbox ), - name, nfsnprintf( name, _POSIX_PATH_MAX, "INBOX" ) ); + ctx, 1, flags, 0, 0, basePath, basePath ? strlen( basePath ) - 1 : 0, + path, nfsnprintf( path, _POSIX_PATH_MAX, "%s/", ((maildir_store_conf_t *)ctx->gen.conf)->inbox ), + name, nfsnprintf( name, _POSIX_PATH_MAX, "INBOX/" ) ); } static int -maildir_list_path( store_t *gctx, int *flags ) +maildir_list_path( maildir_store_t *ctx, int flags, const char *inbox ) { char path[_POSIX_PATH_MAX], name[_POSIX_PATH_MAX]; + if (ctx->listed & LIST_PATH) + return 0; + ctx->listed |= LIST_PATH; + + if (maildir_ensure_path( (maildir_store_conf_t *)ctx->gen.conf ) < 0) + return -1; return maildir_list_recurse( - gctx, 0, flags, ((maildir_store_conf_t *)gctx->conf)->inbox, - path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", gctx->conf->path ), + ctx, 0, flags, inbox, inbox ? strlen( inbox ) : 0, 0, 0, + path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", ctx->gen.conf->path ), name, 0 ); } static void -maildir_list( store_t *gctx, int flags, - void (*cb)( int sts, void *aux ), void *aux ) +maildir_list_store( store_t *gctx, int flags, + void (*cb)( int sts, string_list_t *boxes, void *aux ), void *aux ) { - if (((flags & LIST_PATH) && maildir_list_path( gctx, &flags ) < 0) || - ((flags & LIST_INBOX) && maildir_list_inbox( gctx, &flags ) < 0)) { - maildir_invoke_bad_callback( gctx ); - cb( DRV_CANCELED, aux ); + maildir_store_t *ctx = (maildir_store_t *)gctx; + maildir_store_conf_t *conf = (maildir_store_conf_t *)gctx->conf; + + if (conf->sub_style == SUB_MAILDIRPP + ? maildir_list_maildirpp( ctx, flags, conf->inbox ) < 0 + : ((((flags & LIST_PATH) || ((flags & LIST_PATH_MAYBE) && gctx->conf->path)) + && maildir_list_path( ctx, flags, conf->inbox ) < 0) || + ((flags & LIST_INBOX) + && maildir_list_inbox( ctx, flags, gctx->conf->path ) < 0))) { + maildir_invoke_bad_callback( ctx ); + cb( DRV_CANCELED, 0, aux ); } else { - cb( DRV_OK, aux ); + cb( DRV_OK, ctx->boxes, aux ); } } @@ -286,201 +516,212 @@ typedef struct { char *base; + char *msgid; int size; - unsigned uid:31, recent:1; + uint uid; + uchar recent; char tuid[TUIDL]; } msg_t; -typedef struct { - msg_t *ents; - int nents, nalloc; -} msglist_t; +DEFINE_ARRAY_TYPE(msg_t) static void -maildir_free_scan( msglist_t *msglist ) +maildir_free_scan( msg_t_array_alloc_t *msglist ) { int i; - if (msglist->ents) { - for (i = 0; i < msglist->nents; i++) - free( msglist->ents[i].base ); - free( msglist->ents ); + if (msglist->array.data) { + for (i = 0; i < msglist->array.size; i++) + free( msglist->array.data[i].base ); + free( msglist->array.data ); } } #define _24_HOURS (3600 * 24) static int -maildir_validate( const char *box, int create, maildir_store_t *ctx ) +maildir_clear_tmp( char *buf, int bufsz, int bl ) { DIR *dirp; struct dirent *entry; - char *p; time_t now; + struct stat st; + + memcpy( buf + bl, "tmp/", 5 ); + bl += 4; + if (!(dirp = opendir( buf ))) { + sys_error( "Maildir error: cannot list %s", buf ); + return DRV_BOX_BAD; + } + time( &now ); + while ((entry = readdir( dirp ))) { + nfsnprintf( buf + bl, bufsz - bl, "%s", entry->d_name ); + if (stat( buf, &st )) { + if (errno != ENOENT) + sys_error( "Maildir error: cannot access %s", buf ); + } else if (S_ISREG(st.st_mode) && now - st.st_ctime >= _24_HOURS) { + /* This should happen infrequently enough that it won't be + * bothersome to the user to display when it occurs. + */ + notice( "Maildir notice: removing stale file %s\n", buf ); + if (unlink( buf ) && errno != ENOENT) + sys_error( "Maildir error: cannot remove %s", buf ); + } + } + closedir( dirp ); + return DRV_OK; +} + +static int +make_box_dir( char *buf, int bl ) +{ + char *p; + + if (!mkdir( buf, 0700 ) || errno == EEXIST) + return 0; + p = memrchr( buf, '/', bl - 1 ); + *p = 0; + if (make_box_dir( buf, (int)(p - buf) )) + return -1; + *p = '/'; + return mkdir( buf, 0700 ); +} + +static int +maildir_validate( const char *box, int create, maildir_store_t *ctx ) +{ int i, bl, ret; struct stat st; char buf[_POSIX_PATH_MAX]; bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", box ); if (stat( buf, &st )) { - if (errno == ENOENT) { - if (create) { - p = memrchr( buf, '/', bl - 1 ); - if (*(p + 1) == '.') { - *p = 0; - if ((ret = maildir_validate( buf, 1, ctx )) != DRV_OK) - return ret; - *p = '/'; - } - if (mkdir( buf, 0700 )) { - sys_error( "Maildir error: cannot create mailbox '%s'", buf ); - maildir_invoke_bad_callback( &ctx->gen ); - return DRV_CANCELED; - } - for (i = 0; i < 3; i++) { - memcpy( buf + bl, subdirs[i], 4 ); - if (mkdir( buf, 0700 )) { - sys_error( "Maildir error: cannot create directory %s", buf ); - return DRV_BOX_BAD; - } - } - } else { - error( "Maildir error: mailbox '%s' does not exist\n", buf ); - return DRV_BOX_BAD; - } - } else { - sys_error( "Maildir error: cannot access mailbox '%s'", buf ); + if (errno != ENOENT) { + sys_error( "Maildir error: cannot access mailbox '%s'", box ); return DRV_BOX_BAD; } - ctx->fresh = 1; - } else { - for (i = 0; i < 3; i++) { - memcpy( buf + bl, subdirs[i], 4 ); - if (stat( buf, &st ) || !S_ISDIR(st.st_mode)) { - error( "Maildir error: '%.*s' is no valid mailbox\n", bl, buf ); + if (!create) + return DRV_BOX_BAD; + if (make_box_dir( buf, bl )) { + sys_error( "Maildir error: cannot create mailbox '%s'", box ); + ((maildir_store_conf_t *)ctx->gen.conf)->failed = FAIL_FINAL; + maildir_invoke_bad_callback( ctx ); + return DRV_CANCELED; + } + } else if (!S_ISDIR(st.st_mode)) { + notdir: + error( "Maildir error: '%s' is no valid mailbox\n", box ); + return DRV_BOX_BAD; + } + for (i = 0; i < 3; i++) { + memcpy( buf + bl, subdirs[i], 4 ); + if (stat( buf, &st )) { + /* We always create new/ and tmp/ if they are missing. cur/ is the presence indicator. */ + if (!i && !create) + return DRV_BOX_BAD; + if (mkdir( buf, 0700 )) { + sys_error( "Maildir error: cannot create directory %s", buf ); return DRV_BOX_BAD; } - } - memcpy( buf + bl, "tmp/", 5 ); - bl += 4; - if (!(dirp = opendir( buf ))) { - sys_error( "Maildir error: cannot list %s", buf ); - return DRV_BOX_BAD; - } - time( &now ); - while ((entry = readdir( dirp ))) { - nfsnprintf( buf + bl, sizeof(buf) - bl, "%s", entry->d_name ); - if (stat( buf, &st )) { - if (errno != ENOENT) - sys_error( "Maildir error: cannot access %s", buf ); - } else if (S_ISREG(st.st_mode) && now - st.st_ctime >= _24_HOURS) { - /* this should happen infrequently enough that it won't be - * bothersome to the user to display when it occurs. - */ - info( "Maildir notice: removing stale file %s\n", buf ); - if (unlink( buf ) && errno != ENOENT) - sys_error( "Maildir error: cannot remove %s", buf ); + ctx->fresh[i] = 1; + } else if (!S_ISDIR(st.st_mode)) { + goto notdir; + } else { + if (i == 2) { + if ((ret = maildir_clear_tmp( buf, sizeof(buf), bl )) != DRV_OK) + return ret; } } - closedir( dirp ); - ctx->fresh = 0; } return DRV_OK; } #ifdef USE_DB static void -make_key( DBT *tkey, char *name ) +make_key( const char *info_stop, DBT *tkey, char *name ) { - char *u = strpbrk( name, ":," ); + char *u = strpbrk( name, info_stop ); tkey->data = name; tkey->size = u ? (size_t)(u - name) : strlen( name ); } - -static int -maildir_set_uid( maildir_store_t *ctx, const char *name, int *uid ) -{ - int ret, uv[2]; - - if (uid) - *uid = ++ctx->nuid; - key.data = (void *)"UIDVALIDITY"; - key.size = 11; - uv[0] = ctx->gen.uidvalidity; - uv[1] = ctx->nuid; - value.data = uv; - value.size = sizeof(uv); - if ((ret = ctx->db->put( ctx->db, 0, &key, &value, 0 ))) { - tbork: - ctx->db->err( ctx->db, ret, "Maildir error: db->put()" ); - return DRV_BOX_BAD; - } - if (uid) { - make_key( &key, (char *)name ); - value.data = uid; - value.size = sizeof(*uid); - if ((ret = ctx->db->put( ctx->db, 0, &key, &value, 0 ))) - goto tbork; - } - if ((ret = ctx->db->sync( ctx->db, 0 ))) { - ctx->db->err( ctx->db, ret, "Maildir error: db->sync()" ); - return DRV_BOX_BAD; - } - return DRV_OK; -} #endif /* USE_DB */ static int -maildir_store_uid( maildir_store_t *ctx ) +maildir_store_uidval( maildir_store_t *ctx ) { int n; +#ifdef USE_DB + int ret; + uint uv[2]; +#endif char buf[128]; - n = sprintf( buf, "%d\n%d\n", ctx->gen.uidvalidity, ctx->nuid ); - lseek( ctx->uvfd, 0, SEEK_SET ); - if (write( ctx->uvfd, buf, n ) != n || ftruncate( ctx->uvfd, n ) || (UseFSync && fdatasync( ctx->uvfd ))) { - error( "Maildir error: cannot write UIDVALIDITY.\n" ); - return DRV_BOX_BAD; +#ifdef USE_DB + if (ctx->db) { + key.data = (void *)"UIDVALIDITY"; + key.size = 11; + uv[0] = ctx->uidvalidity; + uv[1] = ctx->nuid; + value.data = uv; + value.size = sizeof(uv); + if ((ret = ctx->db->put( ctx->db, 0, &key, &value, 0 ))) { + ctx->db->err( ctx->db, ret, "Maildir error: db->put()" ); + return DRV_BOX_BAD; + } + if ((ret = ctx->db->sync( ctx->db, 0 ))) { + ctx->db->err( ctx->db, ret, "Maildir error: db->sync()" ); + return DRV_BOX_BAD; + } + } else +#endif /* USE_DB */ + { + n = sprintf( buf, "%u\n%u\n", ctx->uidvalidity, ctx->nuid ); + lseek( ctx->uvfd, 0, SEEK_SET ); + if (write( ctx->uvfd, buf, n ) != n || ftruncate( ctx->uvfd, n ) || (UseFSync && fdatasync( ctx->uvfd ))) { + error( "Maildir error: cannot write UIDVALIDITY.\n" ); + return DRV_BOX_BAD; + } } + conf_wakeup( &ctx->lcktmr, 2 ); return DRV_OK; } static int -maildir_init_uid( maildir_store_t *ctx ) +maildir_init_uidval( maildir_store_t *ctx ) { - ctx->gen.uidvalidity = time( 0 ); + ctx->uidvalidity = time( 0 ); ctx->nuid = 0; ctx->uvok = 0; #ifdef USE_DB if (ctx->db) { u_int32_t count; ctx->db->truncate( ctx->db, 0, &count, 0 ); - return maildir_set_uid( ctx, 0, 0 ); } #endif /* USE_DB */ - return maildir_store_uid( ctx ); + return maildir_store_uidval( ctx ); } static int -maildir_init_uid_new( maildir_store_t *ctx ) +maildir_init_uidval_new( maildir_store_t *ctx ) { - info( "Maildir notice: no UIDVALIDITY, creating new.\n" ); - return maildir_init_uid( ctx ); + notice( "Maildir notice: no UIDVALIDITY, creating new.\n" ); + return maildir_init_uidval( ctx ); } static int maildir_uidval_lock( maildir_store_t *ctx ) { int n; +#ifdef USE_DB + int ret; + struct stat st; +#endif char buf[128]; -#ifdef LEGACY_FLOCK - /* This is legacy only */ - if (flock( ctx->uvfd, LOCK_EX ) < 0) { - error( "Maildir error: cannot flock UIDVALIDITY.\n" ); - return DRV_BOX_BAD; + if (pending_wakeup( &ctx->lcktmr )) { + /* The unlock timer is active, so we are obviously already locked. */ + return DRV_OK; } -#endif /* This (theoretically) works over NFS. Let's hope nobody else did the same in the opposite order, as we'd deadlock then. */ #if SEEK_SET != 0 @@ -491,42 +732,107 @@ error( "Maildir error: cannot fcntl lock UIDVALIDITY.\n" ); return DRV_BOX_BAD; } - lseek( ctx->uvfd, 0, SEEK_SET ); - if ((n = read( ctx->uvfd, buf, sizeof(buf) )) <= 0 || - (buf[n] = 0, sscanf( buf, "%d\n%d", &ctx->gen.uidvalidity, &ctx->nuid ) != 2)) { -#if 1 - /* In a generic driver, resetting the UID validity would be the right thing. - * But this would mess up the sync state completely. So better bail out and - * give the user a chance to fix the mailbox. */ - if (n) { - error( "Maildir error: cannot read UIDVALIDITY.\n" ); + +#ifdef USE_DB + if (ctx->usedb) { + if (fstat( ctx->uvfd, &st )) { + sys_error( "Maildir error: cannot fstat UID database" ); return DRV_BOX_BAD; } -#endif - return maildir_init_uid_new( ctx ); + if (db_create( &ctx->db, 0, 0 )) { + fputs( "Maildir error: db_create() failed\n", stderr ); + return DRV_BOX_BAD; + } + if ((ret = (ctx->db->open)( ctx->db, 0, ctx->usedb, 0, DB_HASH, + st.st_size ? 0 : DB_CREATE | DB_TRUNCATE, 0 ))) { + ctx->db->err( ctx->db, ret, "Maildir error: db->open(%s)", ctx->usedb ); + return DRV_BOX_BAD; + } + key.data = (void *)"UIDVALIDITY"; + key.size = 11; + if ((ret = ctx->db->get( ctx->db, 0, &key, &value, 0 ))) { + if (ret != DB_NOTFOUND) { + ctx->db->err( ctx->db, ret, "Maildir error: db->get()" ); + return DRV_BOX_BAD; + } + return maildir_init_uidval_new( ctx ); + } + ctx->uidvalidity = ((uint *)value.data)[0]; + ctx->nuid = ((uint *)value.data)[1]; } else - ctx->uvok = 1; +#endif + { + lseek( ctx->uvfd, 0, SEEK_SET ); + if ((n = read( ctx->uvfd, buf, sizeof(buf) - 1 )) <= 0 || + (buf[n] = 0, sscanf( buf, "%u\n%u", &ctx->uidvalidity, &ctx->nuid ) != 2)) { +#if 1 + /* In a generic driver, resetting the UID validity would be the right thing. + * But this would mess up the sync state completely. So better bail out and + * give the user a chance to fix the mailbox. */ + if (n) { + error( "Maildir error: cannot read UIDVALIDITY.\n" ); + return DRV_BOX_BAD; + } +#endif + return maildir_init_uidval_new( ctx ); + } + } + ctx->uvok = 1; + conf_wakeup( &ctx->lcktmr, 2 ); return DRV_OK; } static void maildir_uidval_unlock( maildir_store_t *ctx ) { +#ifdef USE_DB + if (ctx->db) { + ctx->db->close( ctx->db, 0 ); + ctx->db = 0; + } +#endif /* USE_DB */ lck.l_type = F_UNLCK; fcntl( ctx->uvfd, F_SETLK, &lck ); -#ifdef LEGACY_FLOCK - /* This is legacy only */ - flock( ctx->uvfd, LOCK_UN ); -#endif +} + +static void +lcktmr_timeout( void *aux ) +{ + maildir_uidval_unlock( (maildir_store_t *)aux ); } static int -maildir_obtain_uid( maildir_store_t *ctx, int *uid ) +maildir_obtain_uid( maildir_store_t *ctx, uint *uid ) { + int ret; + + if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) + return ret; *uid = ++ctx->nuid; - return maildir_store_uid( ctx ); + return maildir_store_uidval( ctx ); } +#ifdef USE_DB +static int +maildir_set_uid( maildir_store_t *ctx, const char *name, uint *uid ) +{ + int ret; + + if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) + return ret; + *uid = ++ctx->nuid; + + make_key( ((maildir_store_conf_t *)ctx->gen.conf)->info_stop, &key, (char *)name ); + value.data = uid; + value.size = sizeof(*uid); + if ((ret = ctx->db->put( ctx->db, 0, &key, &value, 0 ))) { + ctx->db->err( ctx->db, ret, "Maildir error: db->put()" ); + return DRV_BOX_BAD; + } + return maildir_store_uidval( ctx ); +} +#endif + static int maildir_compare( const void *l, const void *r ) { @@ -590,8 +896,9 @@ } static int -maildir_scan( maildir_store_t *ctx, msglist_t *msglist ) +maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t *msglist ) { + maildir_store_conf_t *conf = (maildir_store_conf_t *)ctx->gen.conf; DIR *d; FILE *f; struct dirent *e; @@ -601,24 +908,18 @@ DBC *dbc; #endif /* USE_DB */ msg_t *entry; - int i, j, uid, bl, fnl, ret; + int i, bl, fnl, ret; + uint uid; time_t now, stamps[2]; struct stat st; char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX]; -#ifdef USE_DB - if (!ctx->db) -#endif /* USE_DB */ - if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) - return ret; - again: - msglist->ents = 0; - msglist->nents = msglist->nalloc = 0; - ctx->gen.count = ctx->gen.recent = 0; - if (ctx->uvok || ctx->maxuid == INT_MAX) { + ARRAY_INIT( msglist ); + ctx->total_msgs = ctx->recent_msgs = 0; + if (ctx->uvok || ctx->maxuid == UINT_MAX) { #ifdef USE_DB - if (ctx->db) { + if (ctx->usedb) { if (db_create( &tdb, 0, 0 )) { fputs( "Maildir error: db_create() failed\n", stderr ); return DRV_BOX_BAD; @@ -631,7 +932,7 @@ } } #endif /* USE_DB */ - bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", ctx->gen.path ); + bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", ctx->path ); restat: now = time( 0 ); for (i = 0; i < 2; i++) { @@ -640,12 +941,12 @@ sys_error( "Maildir error: cannot stat %s", buf ); goto dfail; } - if (st.st_mtime == now && !(DFlags & ZERODELAY)) { + if (st.st_mtime == now && !(DFlags & ZERODELAY) && !ctx->fresh[i]) { /* If the modification happened during this second, we wouldn't be able to * tell if there were further modifications during this second. So wait. * This has the nice side effect that we wait for "batches" of changes to * complete. On the downside, it can potentially block indefinitely. */ - info( "Maildir notice: sleeping due to recent directory modification.\n" ); + notice( "Maildir notice: sleeping due to recent directory modification.\n" ); sleep( 1 ); /* FIXME: should make this async */ goto restat; } @@ -659,7 +960,7 @@ maildir_free_scan( msglist ); dfail: #ifdef USE_DB - if (ctx->db) + if (ctx->usedb) tdb->close( tdb, 0 ); #endif /* USE_DB */ return DRV_BOX_BAD; @@ -667,48 +968,43 @@ while ((e = readdir( d ))) { if (*e->d_name == '.') continue; - ctx->gen.count++; - ctx->gen.recent += i; + ctx->total_msgs++; + ctx->recent_msgs += i; #ifdef USE_DB - if (ctx->db) { - make_key( &key, e->d_name ); + if (ctx->usedb) { + if (maildir_uidval_lock( ctx ) != DRV_OK) + goto mbork; + make_key( conf->info_stop, &key, e->d_name ); if ((ret = ctx->db->get( ctx->db, 0, &key, &value, 0 ))) { if (ret != DB_NOTFOUND) { ctx->db->err( ctx->db, ret, "Maildir error: db->get()" ); mbork: maildir_free_scan( msglist ); + closedir( d ); goto bork; } - uid = INT_MAX; + uid = UINT_MAX; } else { value.size = 0; if ((ret = tdb->put( tdb, 0, &key, &value, 0 ))) { tdb->err( tdb, ret, "Maildir error: tdb->put()" ); goto mbork; } - uid = *(int *)value.data; + uid = *(uint *)value.data; } } else #endif /* USE_DB */ { - uid = (ctx->uvok && (u = strstr( e->d_name, ",U=" ))) ? atoi( u + 3 ) : 0; + uid = (ctx->uvok && (u = strstr( e->d_name, ",U=" ))) ? strtoul( u + 3, NULL, 10 ) : 0; if (!uid) - uid = INT_MAX; + uid = UINT_MAX; } if (uid <= ctx->maxuid) { - if (uid < ctx->minuid) { - for (j = 0; j < ctx->nexcs; j++) - if (ctx->excs[j] == uid) - goto oke; + if (uid < ctx->minuid && !find_uint_array( ctx->excs, uid )) continue; - oke: ; - } - if (msglist->nalloc == msglist->nents) { - msglist->nalloc = msglist->nalloc * 2 + 100; - msglist->ents = nfrealloc( msglist->ents, msglist->nalloc * sizeof(msg_t) ); - } - entry = &msglist->ents[msglist->nents++]; + entry = msg_t_array_append( msglist ); entry->base = nfstrdup( e->d_name ); + entry->msgid = 0; entry->uid = uid; entry->recent = i; entry->size = 0; @@ -726,7 +1022,7 @@ if (st.st_mtime != stamps[i]) { /* Somebody messed with the mailbox since we started listing it. */ #ifdef USE_DB - if (ctx->db) + if (ctx->usedb) tdb->close( tdb, 0 ); #endif /* USE_DB */ maildir_free_scan( msglist ); @@ -734,8 +1030,10 @@ } } #ifdef USE_DB - if (ctx->db) { - if ((ret = ctx->db->cursor( ctx->db, 0, &dbc, 0 ))) + if (ctx->usedb) { + if (maildir_uidval_lock( ctx ) != DRV_OK) + ; + else if ((ret = ctx->db->cursor( ctx->db, 0, &dbc, 0 ))) ctx->db->err( ctx->db, ret, "Maildir error: db->cursor()" ); else { for (;;) { @@ -744,7 +1042,7 @@ ctx->db->err( ctx->db, ret, "Maildir error: db->c_get()" ); break; } - if ((key.size != 11 || memcmp( key.data, "UIDVALIDITY", 11 )) && + if (!equals( key.data, key.size, "UIDVALIDITY", 11 ) && (ret = tdb->get( tdb, 0, &key, &value, 0 ))) { if (ret != DB_NOTFOUND) { tdb->err( tdb, ret, "Maildir error: tdb->get()" ); @@ -761,18 +1059,18 @@ tdb->close( tdb, 0 ); } #endif /* USE_DB */ - qsort( msglist->ents, msglist->nents, sizeof(msg_t), maildir_compare ); - for (uid = i = 0; i < msglist->nents; i++) { - entry = &msglist->ents[i]; - if (entry->uid != INT_MAX) { + qsort( msglist->array.data, msglist->array.size, sizeof(msg_t), maildir_compare ); + for (uid = i = 0; i < msglist->array.size; i++) { + entry = &msglist->array.data[i]; + if (entry->uid != UINT_MAX) { if (uid == entry->uid) { #if 1 /* See comment in maildir_uidval_lock() why this is fatal. */ - error( "Maildir error: duplicate UID %d.\n", uid ); + error( "Maildir error: duplicate UID %u.\n", uid ); maildir_free_scan( msglist ); return DRV_BOX_BAD; #else - info( "Maildir notice: duplicate UID; changing UIDVALIDITY.\n"); + notice( "Maildir notice: duplicate UID; changing UIDVALIDITY.\n"); if ((ret = maildir_init_uid( ctx )) != DRV_OK) { maildir_free_scan( msglist ); return ret; @@ -782,17 +1080,22 @@ #endif } uid = entry->uid; - if ((ctx->gen.opts & OPEN_SIZE) || ((ctx->gen.opts & OPEN_FIND) && uid >= ctx->newuid)) - nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s", subdirs[entry->recent], entry->base ); + if (uid > ctx->nuid) { + /* In principle, we could just warn and top up nuid. However, getting into this + * situation might indicate some serious trouble, so let's not make it worse. */ + error( "Maildir error: UID %u is beyond highest assigned UID %u.\n", uid, ctx->nuid ); + maildir_free_scan( msglist ); + return DRV_BOX_BAD; + } + fnl = 0; #ifdef USE_DB - } else if (ctx->db) { + } else if (ctx->usedb) { if ((ret = maildir_set_uid( ctx, entry->base, &uid )) != DRV_OK) { maildir_free_scan( msglist ); return ret; } entry->uid = uid; - if ((ctx->gen.opts & OPEN_SIZE) || ((ctx->gen.opts & OPEN_FIND) && uid >= ctx->newuid)) - nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s", subdirs[entry->recent], entry->base ); + fnl = 0; #endif /* USE_DB */ } else { if ((ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK) { @@ -801,13 +1104,13 @@ } entry->uid = uid; if ((u = strstr( entry->base, ",U=" ))) - for (ru = u + 3; isdigit( (unsigned char)*ru ); ru++); + for (ru = u + 3; isdigit( (uchar)*ru ); ru++); else - u = ru = strchr( entry->base, ':' ); + u = ru = strchr( entry->base, conf->info_delimiter ); fnl = (u ? - nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%.*s,U=%d%s", subdirs[entry->recent], (int)(u - entry->base), entry->base, uid, ru ) : - nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s,U=%d", subdirs[entry->recent], entry->base, uid )) - + 1 - 4; + nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%.*s,U=%u%s", subdirs[entry->recent], (int)(u - entry->base), entry->base, uid, ru ) : + nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s,U=%u", subdirs[entry->recent], entry->base, uid )) + - 4; memcpy( nbuf, buf, bl + 4 ); nfsnprintf( nbuf + bl + 4, sizeof(nbuf) - bl - 4, "%s", entry->base ); if (rename( nbuf, buf )) { @@ -822,10 +1125,16 @@ goto again; } free( entry->base ); - entry->base = nfmalloc( fnl ); - memcpy( entry->base, buf + bl + 4, fnl ); + entry->base = nfstrndup( buf + bl + 4, fnl ); } - if (ctx->gen.opts & OPEN_SIZE) { + int want_size = (uid > ctx->seenuid) ? (ctx->opts & OPEN_NEW_SIZE) : (ctx->opts & OPEN_OLD_SIZE); + int want_tuid = ((ctx->opts & OPEN_FIND) && uid >= ctx->newuid); + int want_msgid = ((ctx->opts & OPEN_OLD_IDS) && uid <= ctx->seenuid); + if (!want_size && !want_tuid && !want_msgid) + continue; + if (!fnl) + nfsnprintf( buf + bl, sizeof(buf) - bl, "%s/%s", subdirs[entry->recent], entry->base ); + if (want_size) { if (stat( buf, &st )) { if (errno != ENOENT) { sys_error( "Maildir error: cannot stat %s", buf ); @@ -835,7 +1144,7 @@ } entry->size = st.st_size; } - if ((ctx->gen.opts & OPEN_FIND) && uid >= ctx->newuid) { + if (want_tuid || want_msgid) { if (!(f = fopen( buf, "r" ))) { if (errno != ENOENT) { sys_error( "Maildir error: cannot open %s", buf ); @@ -843,23 +1152,51 @@ } goto retry; } - while (fgets( nbuf, sizeof(nbuf), f )) { - if (!nbuf[0] || nbuf[0] == '\n') + int off, in_msgid = 0; + while ((want_tuid || want_msgid) && fgets( nbuf, sizeof(nbuf), f )) { + int bufl = strlen( nbuf ); + if (bufl && nbuf[bufl - 1] == '\n') + --bufl; + if (bufl && nbuf[bufl - 1] == '\r') + --bufl; + if (!bufl) break; - if (!memcmp( nbuf, "X-TUID: ", 8 ) && nbuf[8 + TUIDL] == '\n') { + if (want_tuid && starts_with( nbuf, bufl, "X-TUID: ", 8 )) { + if (bufl < 8 + TUIDL) { + error( "Maildir error: malformed X-TUID header (UID %u)\n", uid ); + continue; + } memcpy( entry->tuid, nbuf + 8, TUIDL ); - break; + want_tuid = 0; + in_msgid = 0; + continue; + } + if (want_msgid && starts_with_upper( nbuf, bufl, "MESSAGE-ID:", 11 )) { + off = 11; + } else if (in_msgid) { + if (!isspace( nbuf[0] )) { + in_msgid = 0; + continue; + } + off = 1; + } else { + continue; + } + while (off < bufl && isspace( nbuf[off] )) + off++; + if (off == bufl) { + in_msgid = 1; + continue; } + entry->msgid = nfstrndup( nbuf + off, bufl - off ); + want_msgid = 0; + in_msgid = 0; } fclose( f ); } } ctx->uvok = 1; } -#ifdef USE_DB - if (!ctx->db) -#endif /* ! USE_DB */ - maildir_uidval_unlock( ctx ); return DRV_OK; } @@ -868,14 +1205,16 @@ { msg->base = entry->base; entry->base = 0; /* prevent deletion */ + msg->gen.msgid = entry->msgid; + entry->msgid = 0; /* prevent deletion */ msg->gen.size = entry->size; msg->gen.srec = 0; - strncpy( msg->gen.tuid, entry->tuid, TUIDL ); + memcpy( msg->gen.tuid, entry->tuid, TUIDL ); if (entry->recent) msg->gen.status |= M_RECENT; - if (ctx->gen.opts & OPEN_FLAGS) { + if (ctx->opts & OPEN_FLAGS) { msg->gen.status |= M_FLAGS; - msg->gen.flags = maildir_parse_flags( msg->base ); + msg->gen.flags = maildir_parse_flags( ((maildir_store_conf_t *)ctx->gen.conf)->info_prefix, msg->base ); } else msg->gen.flags = 0; } @@ -892,153 +1231,214 @@ maildir_init_msg( ctx, msg, entry ); } -static void -maildir_select( store_t *gctx, int create, - void (*cb)( int sts, void *aux ), void *aux ) +static int +maildir_select_box( store_t *gctx, const char *name ) { + maildir_store_conf_t *conf = (maildir_store_conf_t *)gctx->conf; maildir_store_t *ctx = (maildir_store_t *)gctx; - int ret; -#ifdef USE_DB - struct stat st; -#endif /* USE_DB */ - char uvpath[_POSIX_PATH_MAX]; maildir_cleanup( gctx ); - gctx->msgs = 0; - ctx->excs = 0; + ctx->msgs = 0; + ctx->excs.data = 0; ctx->uvfd = -1; #ifdef USE_DB ctx->db = 0; + ctx->usedb = 0; #endif /* USE_DB */ - gctx->path = - (!memcmp( gctx->name, "INBOX", 5 ) && (!gctx->name[5] || gctx->name[5] == '/')) ? - maildir_join_path( ((maildir_store_conf_t *)gctx->conf)->inbox, gctx->name + 5 ) : - maildir_join_path( gctx->conf->path, gctx->name ); - - if ((ret = maildir_validate( gctx->path, create, ctx )) != DRV_OK) { - cb( ret, aux ); - return; + ctx->fresh[0] = ctx->fresh[1] = 0; + if (starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == '/')) { + if (!name[5]) { + ctx->path = nfstrdup( conf->inbox ); + ctx->is_inbox = 1; + } else { + ctx->path = maildir_join_path( conf, 1, name + 5 ); + ctx->is_inbox = 0; + } + } else { + if (!(ctx->path = maildir_join_path( conf, 0, name ))) + return DRV_CANCELED; + ctx->is_inbox = 0; } + return ctx->path ? DRV_OK : DRV_BOX_BAD; +} - nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", gctx->path ); +static const char * +maildir_get_box_path( store_t *gctx ) +{ + return ((maildir_store_t *)gctx)->path; +} + +static void +maildir_open_box( store_t *gctx, + void (*cb)( int sts, int uidvalidity, void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + int ret; + char uvpath[_POSIX_PATH_MAX]; + + if ((ret = maildir_validate( ctx->path, ctx->is_inbox, ctx )) != DRV_OK) + goto bail; + + nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", ctx->path ); #ifndef USE_DB if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) < 0) { sys_error( "Maildir error: cannot write %s", uvpath ); - cb( DRV_BOX_BAD, aux ); + cb( DRV_BOX_BAD, UIDVAL_BAD, aux ); return; } #else + ctx->usedb = 0; if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) { - nfsnprintf( uvpath, sizeof(uvpath), "%s/.isyncuidmap.db", gctx->path ); + nfsnprintf( uvpath, sizeof(uvpath), "%s/.isyncuidmap.db", ctx->path ); if ((ctx->uvfd = open( uvpath, O_RDWR, 0600 )) < 0) { if (((maildir_store_conf_t *)gctx->conf)->alt_map) { if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) >= 0) goto dbok; } else { - nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", gctx->path ); + nfsnprintf( uvpath, sizeof(uvpath), "%s/.uidvalidity", ctx->path ); if ((ctx->uvfd = open( uvpath, O_RDWR|O_CREAT, 0600 )) >= 0) goto fnok; } sys_error( "Maildir error: cannot write %s", uvpath ); - cb( DRV_BOX_BAD, aux ); + cb( DRV_BOX_BAD, UIDVAL_BAD, aux ); return; - } - dbok: -#if SEEK_SET != 0 - lck.l_whence = SEEK_SET; -#endif - lck.l_type = F_WRLCK; - if (fcntl( ctx->uvfd, F_SETLKW, &lck )) { - sys_error( "Maildir error: cannot lock %s", uvpath ); - cb( DRV_BOX_BAD, aux ); - return; - } - if (fstat( ctx->uvfd, &st )) { - sys_error( "Maildir error: cannot stat %s", uvpath ); - cb( DRV_BOX_BAD, aux ); - return; - } - if (db_create( &ctx->db, 0, 0 )) { - fputs( "Maildir error: db_create() failed\n", stderr ); - cb( DRV_BOX_BAD, aux ); - return; - } - if ((ret = (ctx->db->open)( ctx->db, 0, uvpath, 0, DB_HASH, - st.st_size ? 0 : DB_CREATE | DB_TRUNCATE, 0 ))) { - ctx->db->err( ctx->db, ret, "Maildir error: db->open(%s)", uvpath ); - cb( DRV_BOX_BAD, aux ); - return; - } - key.data = (void *)"UIDVALIDITY"; - key.size = 11; - if ((ret = ctx->db->get( ctx->db, 0, &key, &value, 0 ))) { - if (ret != DB_NOTFOUND) { - ctx->db->err( ctx->db, ret, "Maildir error: db->get()" ); - cb( DRV_BOX_BAD, aux ); - return; - } - if (maildir_init_uid_new( ctx ) != DRV_OK) { - cb( DRV_BOX_BAD, aux ); - return; - } } else { - ctx->gen.uidvalidity = ((int *)value.data)[0]; - ctx->nuid = ((int *)value.data)[1]; - ctx->uvok = 1; + dbok: + ctx->usedb = nfstrdup( uvpath ); } - cb( DRV_OK, aux ); - return; } fnok: #endif /* USE_DB */ - if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) { - cb( ret, aux ); - return; - } - maildir_uidval_unlock( ctx ); + ret = maildir_uidval_lock( ctx ); - cb( DRV_OK, aux ); + bail: + cb( ret, ctx->uidvalidity, aux ); +} + +static int +maildir_get_uidnext( store_t *gctx ATTR_UNUSED ) +{ + return 0; } static void -maildir_prepare_opts( store_t *gctx, int opts ) +maildir_create_box( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + + cb( maildir_validate( ctx->path, 1, ctx ), aux ); +} + +static int +maildir_confirm_box_empty( store_t *gctx ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + msg_t_array_alloc_t msglist; + + ctx->excs.size = ctx->minuid = ctx->maxuid = ctx->newuid = 0; + + if (maildir_scan( ctx, &msglist ) != DRV_OK) + return DRV_BOX_BAD; + maildir_free_scan( &msglist ); + return ctx->total_msgs ? DRV_BOX_BAD : DRV_OK; +} + +static void +maildir_delete_box( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + int i, bl, ret = DRV_OK; + struct stat st; + char buf[_POSIX_PATH_MAX]; + + bl = nfsnprintf( buf, sizeof(buf) - 4, "%s/", ctx->path ); + if (stat( buf, &st )) { + if (errno != ENOENT) { + sys_error( "Maildir error: cannot access mailbox '%s'", ctx->path ); + ret = DRV_BOX_BAD; + } + } else if (!S_ISDIR(st.st_mode)) { + error( "Maildir error: '%s' is no valid mailbox\n", ctx->path ); + ret = DRV_BOX_BAD; + } else if ((ret = maildir_clear_tmp( buf, sizeof(buf), bl )) == DRV_OK) { + nfsnprintf( buf + bl, sizeof(buf) - bl, ".uidvalidity" ); + if (unlink( buf ) && errno != ENOENT) + goto badrm; +#ifdef USE_DB + nfsnprintf( buf + bl, sizeof(buf) - bl, ".isyncuidmap.db" ); + if (unlink( buf ) && errno != ENOENT) + goto badrm; +#endif + /* We delete cur/ last, as it is the indicator for a present mailbox. + * That way an interrupted operation can be resumed. */ + for (i = 3; --i >= 0; ) { + memcpy( buf + bl, subdirs[i], 4 ); + if (rmdir( buf ) && errno != ENOENT) { + badrm: + sys_error( "Maildir error: cannot remove '%s'", buf ); + ret = DRV_BOX_BAD; + break; + } + } + } + cb( ret, aux ); +} + +static int +maildir_finish_delete_box( store_t *gctx ) { + maildir_store_t *ctx = (maildir_store_t *)gctx; + + /* Subfolders are not deleted; the deleted folder is only "stripped of its mailboxness". + * Consequently, the rmdir may legitimately fail. This behavior follows the IMAP spec. */ + if (rmdir( ctx->path ) && errno != ENOENT && errno != ENOTEMPTY) { + sys_error( "Maildir warning: cannot remove '%s'", ctx->path ); + return DRV_BOX_BAD; + } + return DRV_OK; +} + +static int +maildir_prepare_load_box( store_t *gctx, int opts ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + if (opts & OPEN_SETFLAGS) opts |= OPEN_OLD; if (opts & OPEN_EXPUNGE) opts |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; - gctx->opts = opts; + ctx->opts = opts; + return opts; } static void -maildir_load( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int nexcs, - void (*cb)( int sts, void *aux ), void *aux ) +maildir_load_box( store_t *gctx, uint minuid, uint maxuid, uint newuid, uint seenuid, uint_array_t excs, + void (*cb)( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ), void *aux ) { maildir_store_t *ctx = (maildir_store_t *)gctx; message_t **msgapp; - msglist_t msglist; + msg_t_array_alloc_t msglist; int i; ctx->minuid = minuid; ctx->maxuid = maxuid; ctx->newuid = newuid; - ctx->excs = nfrealloc( excs, nexcs * sizeof(int) ); - ctx->nexcs = nexcs; - - if (ctx->fresh) - goto dontscan; + ctx->seenuid = seenuid; + ARRAY_SQUEEZE( &excs ); + ctx->excs = excs; if (maildir_scan( ctx, &msglist ) != DRV_OK) { - cb( DRV_BOX_BAD, aux ); + cb( DRV_BOX_BAD, 0, 0, 0, aux ); return; } - msgapp = &ctx->gen.msgs; - for (i = 0; i < msglist.nents; i++) - maildir_app_msg( ctx, &msgapp, msglist.ents + i ); + msgapp = &ctx->msgs; + for (i = 0; i < msglist.array.size; i++) + maildir_app_msg( ctx, &msgapp, msglist.array.data + i ); maildir_free_scan( &msglist ); - dontscan: - cb( DRV_OK, aux ); + cb( DRV_OK, ctx->msgs, ctx->total_msgs, ctx->recent_msgs, aux ); } static int @@ -1046,45 +1446,46 @@ { message_t **msgapp; maildir_message_t *msg; - msglist_t msglist; + msg_t_array_alloc_t msglist; int i; + ctx->fresh[0] = ctx->fresh[1] = 0; if (maildir_scan( ctx, &msglist ) != DRV_OK) return DRV_BOX_BAD; - ctx->gen.recent = 0; - for (msgapp = &ctx->gen.msgs, i = 0; - (msg = (maildir_message_t *)*msgapp) || i < msglist.nents; ) + for (msgapp = &ctx->msgs, i = 0; + (msg = (maildir_message_t *)*msgapp) || i < msglist.array.size; ) { if (!msg) { #if 0 - debug( "adding new message %d\n", msglist.ents[i].uid ); - maildir_app_msg( ctx, &msgapp, msglist.ents + i ); + debug( "adding new message %u\n", msglist.array.data[i].uid ); + maildir_app_msg( ctx, &msgapp, msglist.array.data + i ); #else - debug( "ignoring new message %d\n", msglist.ents[i].uid ); + debug( "ignoring new message %u\n", msglist.array.data[i].uid ); #endif i++; - } else if (i >= msglist.nents) { - debug( "purging deleted message %d\n", msg->gen.uid ); + } else if (i >= msglist.array.size) { + debug( "purging deleted message %u\n", msg->gen.uid ); msg->gen.status = M_DEAD; msgapp = &msg->gen.next; - } else if (msglist.ents[i].uid < msg->gen.uid) { + } else if (msglist.array.data[i].uid < msg->gen.uid) { /* this should not happen, actually */ #if 0 - debug( "adding new message %d\n", msglist.ents[i].uid ); - maildir_app_msg( ctx, &msgapp, msglist.ents + i ); + debug( "adding new message %u\n", msglist.array.data[i].uid ); + maildir_app_msg( ctx, &msgapp, msglist.array.data + i ); #else - debug( "ignoring new message %d\n", msglist.ents[i].uid ); + debug( "ignoring new message %u\n", msglist.array.data[i].uid ); #endif i++; - } else if (msglist.ents[i].uid > msg->gen.uid) { - debug( "purging deleted message %d\n", msg->gen.uid ); + } else if (msglist.array.data[i].uid > msg->gen.uid) { + debug( "purging deleted message %u\n", msg->gen.uid ); msg->gen.status = M_DEAD; msgapp = &msg->gen.next; } else { - debug( "updating message %d\n", msg->gen.uid ); + debug( "updating message %u\n", msg->gen.uid ); msg->gen.status &= ~(M_FLAGS|M_RECENT); free( msg->base ); - maildir_init_msg( ctx, msg, msglist.ents + i ); + free( msg->gen.msgid ); + maildir_init_msg( ctx, msg, msglist.array.data + i ); i++, msgapp = &msg->gen.next; } } @@ -1118,7 +1519,7 @@ char buf[_POSIX_PATH_MAX]; for (;;) { - nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, subdirs[gmsg->status & M_RECENT], msg->base ); + nfsnprintf( buf, sizeof(buf), "%s/%s/%s", ctx->path, subdirs[gmsg->status & M_RECENT], msg->base ); if ((fd = open( buf, O_RDONLY )) >= 0) break; if ((ret = maildir_again( ctx, msg, "Cannot open %s", buf, 0 )) != DRV_OK) { @@ -1139,16 +1540,16 @@ } close( fd ); if (!(gmsg->status & M_FLAGS)) - data->flags = maildir_parse_flags( msg->base ); + data->flags = maildir_parse_flags( ((maildir_store_conf_t *)gctx->conf)->info_prefix, msg->base ); cb( DRV_OK, aux ); } static int -maildir_make_flags( int flags, char *buf ) +maildir_make_flags( char info_delimiter, int flags, char *buf ) { - unsigned i, d; + uint i, d; - buf[0] = ':'; + buf[0] = info_delimiter; buf[1] = '2'; buf[2] = ','; for (d = 3, i = 0; i < as(Flags); i++) @@ -1160,17 +1561,18 @@ static void maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash, - void (*cb)( int sts, int uid, void *aux ), void *aux ) + void (*cb)( int sts, uint uid, void *aux ), void *aux ) { maildir_store_t *ctx = (maildir_store_t *)gctx; const char *box; - int ret, fd, bl, uid; + int ret, fd, bl; + uint uid; char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX], fbuf[NUM_FLAGS + 3], base[128]; bl = nfsnprintf( base, sizeof(base), "%ld.%d_%d.%s", (long)time( 0 ), Pid, ++MaildirCount, Hostname ); if (!to_trash) { #ifdef USE_DB - if (ctx->db) { + if (ctx->usedb) { if ((ret = maildir_set_uid( ctx, base, &uid )) != DRV_OK) { free( data->data ); cb( ret, 0, aux ); @@ -1179,21 +1581,20 @@ } else #endif /* USE_DB */ { - if ((ret = maildir_uidval_lock( ctx )) != DRV_OK || - (ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK) { + if ((ret = maildir_obtain_uid( ctx, &uid )) != DRV_OK) { free( data->data ); cb( ret, 0, aux ); return; } - maildir_uidval_unlock( ctx ); - nfsnprintf( base + bl, sizeof(base) - bl, ",U=%d", uid ); + nfsnprintf( base + bl, sizeof(base) - bl, ",U=%u", uid ); } - box = gctx->path; + box = ctx->path; } else { + uid = 0; box = ctx->trash; } - maildir_make_flags( data->flags, fbuf ); + maildir_make_flags( ((maildir_store_conf_t *)gctx->conf)->info_delimiter, data->flags, fbuf ); nfsnprintf( buf, sizeof(buf), "%s/tmp/%s%s", box, base, fbuf ); if ((fd = open( buf, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) { if (errno != ENOENT || !to_trash) { @@ -1254,25 +1655,26 @@ } static void -maildir_find_new_msgs( store_t *gctx ATTR_UNUSED, - void (*cb)( int sts, void *aux ) ATTR_UNUSED, void *aux ATTR_UNUSED ) +maildir_find_new_msgs( store_t *gctx ATTR_UNUSED, uint newuid ATTR_UNUSED, + void (*cb)( int sts, message_t *msgs, void *aux ) ATTR_UNUSED, void *aux ATTR_UNUSED ) { assert( !"maildir_find_new_msgs is not supposed to be called" ); } static void -maildir_set_flags( store_t *gctx, message_t *gmsg, int uid ATTR_UNUSED, int add, int del, - void (*cb)( int sts, void *aux ), void *aux ) +maildir_set_msg_flags( store_t *gctx, message_t *gmsg, uint uid ATTR_UNUSED, int add, int del, + void (*cb)( int sts, void *aux ), void *aux ) { + maildir_store_conf_t *conf = (maildir_store_conf_t *)gctx->conf; maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_message_t *msg = (maildir_message_t *)gmsg; char *s, *p; - unsigned i; + uint i; int j, ret, ol, fl, bbl, bl, tl; char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX]; - bbl = nfsnprintf( buf, sizeof(buf), "%s/", gctx->path ); - memcpy( nbuf, gctx->path, bbl - 1 ); + bbl = nfsnprintf( buf, sizeof(buf), "%s/", ctx->path ); + memcpy( nbuf, ctx->path, bbl - 1 ); memcpy( nbuf + bbl - 1, "/cur/", 5 ); for (;;) { bl = bbl + nfsnprintf( buf + bbl, sizeof(buf) - bbl, "%s/", subdirs[gmsg->status & M_RECENT] ); @@ -1281,13 +1683,13 @@ oob(); memcpy( buf + bl, msg->base, ol + 1 ); memcpy( nbuf + bl, msg->base, ol + 1 ); - if ((s = strstr( nbuf + bl, ":2," ))) { + if ((s = strstr( nbuf + bl, conf->info_prefix ))) { s += 3; fl = ol - (s - (nbuf + bl)); for (i = 0; i < as(Flags); i++) { if ((p = strchr( s, Flags[i] ))) { if (del & (1 << i)) { - memcpy( p, p + 1, fl - (p - s) ); + memmove( p, p + 1, fl - (p - s) ); fl--; } } else if (add & (1 << i)) { @@ -1299,7 +1701,7 @@ } tl = ol + 3 + fl; } else { - tl = ol + maildir_make_flags( msg->gen.flags, nbuf + bl + ol ); + tl = ol + maildir_make_flags( conf->info_delimiter, msg->gen.flags, nbuf + bl + ol ); } if (!rename( buf, nbuf )) break; @@ -1309,8 +1711,7 @@ } } free( msg->base ); - msg->base = nfmalloc( tl + 1 ); - memcpy( msg->base, nbuf + bl, tl + 1 ); + msg->base = nfstrndup( nbuf + bl, tl ); msg->gen.flags |= add; msg->gen.flags &= ~del; gmsg->status &= ~M_RECENT; @@ -1324,7 +1725,9 @@ { int ret; - make_key( &key, (char *)name ); + if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) + return ret; + make_key( ((maildir_store_conf_t *)ctx->gen.conf)->info_stop, &key, (char *)name ); if ((ret = ctx->db->del( ctx->db, 0, &key, 0 ))) { ctx->db->err( ctx->db, ret, "Maildir error: db->del()" ); return DRV_BOX_BAD; @@ -1345,8 +1748,8 @@ char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX]; for (;;) { - nfsnprintf( buf, sizeof(buf), "%s/%s/%s", gctx->path, subdirs[gmsg->status & M_RECENT], msg->base ); - s = strstr( msg->base, ":2," ); + nfsnprintf( buf, sizeof(buf), "%s/%s/%s", ctx->path, subdirs[gmsg->status & M_RECENT], msg->base ); + s = strstr( msg->base, ((maildir_store_conf_t *)gctx->conf)->info_prefix ); nfsnprintf( nbuf, sizeof(nbuf), "%s/%s/%ld.%d_%d.%s%s", ctx->trash, subdirs[gmsg->status & M_RECENT], (long)time( 0 ), Pid, ++MaildirCount, Hostname, s ? s : "" ); if (!rename( buf, nbuf )) @@ -1370,10 +1773,10 @@ } } gmsg->status |= M_DEAD; - gctx->count--; + ctx->total_msgs--; #ifdef USE_DB - if (ctx->db) { + if (ctx->usedb) { cb( maildir_purge_msg( ctx, msg->base ), aux ); return; } @@ -1382,20 +1785,18 @@ } static void -maildir_close( store_t *gctx, - void (*cb)( int sts, void *aux ), void *aux ) +maildir_close_box( store_t *gctx, + void (*cb)( int sts, void *aux ), void *aux ) { -#ifdef USE_DB maildir_store_t *ctx = (maildir_store_t *)gctx; -#endif /* USE_DB */ message_t *msg; int basel, retry, ret; char buf[_POSIX_PATH_MAX]; for (;;) { retry = 0; - basel = nfsnprintf( buf, sizeof(buf), "%s/", gctx->path ); - for (msg = gctx->msgs; msg; msg = msg->next) + basel = nfsnprintf( buf, sizeof(buf), "%s/", ctx->path ); + for (msg = ctx->msgs; msg; msg = msg->next) if (!(msg->status & M_DEAD) && (msg->flags & F_DELETED)) { nfsnprintf( buf + basel, sizeof(buf) - basel, "%s/%s", subdirs[msg->status & M_RECENT], ((maildir_message_t *)msg)->base ); if (unlink( buf )) { @@ -1405,7 +1806,7 @@ sys_error( "Maildir error: cannot remove %s", buf ); } else { msg->status |= M_DEAD; - gctx->count--; + ctx->total_msgs--; #ifdef USE_DB if (ctx->db && (ret = maildir_purge_msg( ctx, ((maildir_message_t *)msg)->base )) != DRV_OK) { cb( ret, aux ); @@ -1426,19 +1827,31 @@ } static void -maildir_cancel( store_t *gctx ATTR_UNUSED, - void (*cb)( void *aux ), void *aux ) +maildir_cancel_cmds( store_t *gctx ATTR_UNUSED, + void (*cb)( void *aux ), void *aux ) { cb( aux ); } static void -maildir_commit( store_t *gctx ) +maildir_commit_cmds( store_t *gctx ) { (void) gctx; } static int +maildir_get_memory_usage( store_t *gctx ATTR_UNUSED ) +{ + return 0; +} + +static int +maildir_get_fail_state( store_conf_t *gconf ) +{ + return ((maildir_store_conf_t *)gconf)->failed; +} + +static int maildir_parse_store( conffile_t *cfg, store_conf_t **storep ) { maildir_store_conf_t *store; @@ -1446,6 +1859,7 @@ if (strcasecmp( "MaildirStore", cfg->cmd )) return 0; store = nfcalloc( sizeof(*store) ); + store->info_delimiter = FieldDelimiter; store->gen.driver = &maildir_driver; store->gen.name = nfstrdup( cfg->val ); @@ -1458,31 +1872,77 @@ else if (!strcasecmp( "AltMap", cfg->cmd )) store->alt_map = parse_bool( cfg ); #endif /* USE_DB */ - else + else if (!strcasecmp( "InfoDelimiter", cfg->cmd )) { + if (strlen( cfg->val ) != 1) { + error( "%s:%d: Info delimiter must be exactly one character long\n", cfg->file, cfg->line ); + cfg->err = 1; + continue; + } + store->info_delimiter = cfg->val[0]; + if (!ispunct( store->info_delimiter )) { + error( "%s:%d: Info delimiter must be a punctuation character\n", cfg->file, cfg->line ); + cfg->err = 1; + continue; + } + } else if (!strcasecmp( "SubFolders", cfg->cmd )) { + if (!strcasecmp( "Verbatim", cfg->val )) { + store->sub_style = SUB_VERBATIM; + } else if (!strcasecmp( "Maildir++", cfg->val )) { + store->sub_style = SUB_MAILDIRPP; + } else if (!strcasecmp( "Legacy", cfg->val )) { + store->sub_style = SUB_LEGACY; + } else { + error( "%s:%d: Unrecognized SubFolders style\n", cfg->file, cfg->line ); + cfg->err = 1; + } + } else parse_generic_store( &store->gen, cfg ); if (!store->inbox) store->inbox = expand_strdup( "~/Maildir" ); + if (store->sub_style == SUB_MAILDIRPP && store->gen.path) { + error( "Maildir store '%s': Setting Path is incompatible with 'SubFolders Maildir++'\n", store->gen.name ); + cfg->err = 1; + } + nfasprintf( &store->info_prefix, "%c2,", store->info_delimiter ); + nfasprintf( &store->info_stop, "%c,", store->info_delimiter ); *storep = &store->gen; return 1; } +static int +maildir_get_caps( store_t *gctx ATTR_UNUSED ) +{ + return 0; /* XXX DRV_CRLF? */ +} + struct driver maildir_driver = { - 0, /* XXX DRV_CRLF? */ + maildir_get_caps, maildir_parse_store, maildir_cleanup_drv, - maildir_open_store, - maildir_disown_store, - maildir_disown_store, /* _cancel_, but it's the same */ - maildir_list, - maildir_prepare_opts, - maildir_select, - maildir_load, + maildir_alloc_store, + maildir_set_bad_callback, + maildir_connect_store, + maildir_free_store, + maildir_free_store, /* _cancel_, but it's the same */ + maildir_list_store, + maildir_select_box, + maildir_get_box_path, + maildir_create_box, + maildir_open_box, + maildir_get_uidnext, + maildir_confirm_box_empty, + maildir_delete_box, + maildir_finish_delete_box, + maildir_prepare_load_box, + maildir_load_box, maildir_fetch_msg, maildir_store_msg, maildir_find_new_msgs, - maildir_set_flags, + maildir_set_msg_flags, maildir_trash_msg, - maildir_close, - maildir_cancel, - maildir_commit, + maildir_close_box, + maildir_cancel_cmds, + maildir_commit_cmds, + maildir_get_memory_usage, + maildir_get_fail_state, }; diff -Nru isync-1.1.0/src/drv_proxy.c isync-1.2.1-1.812.20170514/src/drv_proxy.c --- isync-1.1.0/src/drv_proxy.c 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/drv_proxy.c 2017-05-26 14:36:31.000000000 +0000 @@ -0,0 +1,335 @@ +/* + * mbsync - mailbox synchronizer + * Copyright (C) 2017 Oswald Buddenhagen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception, mbsync may be linked with the OpenSSL library, + * despite that library's more restrictive license. + */ + +#include "driver.h" + +#include +#include + +typedef struct { + store_t gen; + const char *label; // foreign + int ref_count; + driver_t *real_driver; + store_t *real_store; + + void (*bad_callback)( void *aux ); + void *bad_callback_aux; +} proxy_store_t; + +static void ATTR_PRINTFLIKE(1, 2) +debug( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vdebug( DEBUG_DRV, msg, va ); + va_end( va ); +} + +static void ATTR_PRINTFLIKE(1, 2) +debugn( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vdebugn( DEBUG_DRV, msg, va ); + va_end( va ); +} + +static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' }; + +static char * +proxy_make_flags( int flags, char *buf ) +{ + uint i, d; + + for (d = 0, i = 0; i < as(Flags); i++) + if (flags & (1 << i)) + buf[d++] = Flags[i]; + buf[d] = 0; + return buf; +} + +static void +proxy_store_deref( proxy_store_t *ctx ) +{ + if (!--ctx->ref_count) + free( ctx ); +} + +static int curr_tag; + +typedef struct { + int ref_count; + int tag; + proxy_store_t *ctx; +} gen_cmd_t; + +static gen_cmd_t * +proxy_cmd_new( proxy_store_t *ctx, int sz ) +{ + gen_cmd_t *cmd = nfmalloc( sz ); + cmd->ref_count = 2; + cmd->tag = ++curr_tag; + cmd->ctx = ctx; + ctx->ref_count++; + return cmd; +} + +static void +proxy_cmd_done( gen_cmd_t *cmd ) +{ + if (!--cmd->ref_count) { + proxy_store_deref( cmd->ctx ); + free( cmd ); + } +} + +#if 0 +//# TEMPLATE GETTER +static @type@proxy_@name@( store_t *gctx ) +{ + proxy_store_t *ctx = (proxy_store_t *)gctx; + + @type@rv = ctx->real_driver->@name@( ctx->real_store ); + debug( "%sCalled @name@, ret=@fmt@\n", ctx->label, rv ); + return rv; +} +//# END + +//# TEMPLATE REGULAR +static @type@proxy_@name@( store_t *gctx@decl_args@ ) +{ + proxy_store_t *ctx = (proxy_store_t *)gctx; + + @pre_print_args@ + debug( "%sEnter @name@@print_fmt_args@\n", ctx->label@print_pass_args@ ); + @print_args@ + @type@rv = ctx->real_driver->@name@( ctx->real_store@pass_args@ ); + debug( "%sLeave @name@, ret=@fmt@\n", ctx->label, rv ); + return rv; +} +//# END + +//# TEMPLATE REGULAR_VOID +static void proxy_@name@( store_t *gctx@decl_args@ ) +{ + proxy_store_t *ctx = (proxy_store_t *)gctx; + + @pre_print_args@ + debug( "%sEnter @name@@print_fmt_args@\n", ctx->label@print_pass_args@ ); + @print_args@ + ctx->real_driver->@name@( ctx->real_store@pass_args@ ); + debug( "%sLeave @name@\n", ctx->label ); + @action@ +} +//# END + +//# TEMPLATE CALLBACK +typedef struct { + gen_cmd_t gen; + void (*callback)( @decl_cb_args@void *aux ); + void *callback_aux; + @decl_state@ +} @name@_cmd_t; + +static void +proxy_@name@_cb( @decl_cb_args@void *aux ) +{ + @name@_cmd_t *cmd = (@name@_cmd_t *)aux; + + @pre_print_cb_args@ + debug( "%s[% 2d] Callback enter @name@@print_fmt_cb_args@\n", cmd->gen.ctx->label, cmd->gen.tag@print_pass_cb_args@ ); + @print_cb_args@ + cmd->callback( @pass_cb_args@cmd->callback_aux ); + debug( "%s[% 2d] Callback leave @name@\n", cmd->gen.ctx->label, cmd->gen.tag ); + proxy_cmd_done( &cmd->gen ); +} + +static void +proxy_@name@( store_t *gctx@decl_args@, void (*cb)( @decl_cb_args@void *aux ), void *aux ) +{ + proxy_store_t *ctx = (proxy_store_t *)gctx; + + @name@_cmd_t *cmd = (@name@_cmd_t *)proxy_cmd_new( ctx, sizeof(@name@_cmd_t) ); + cmd->callback = cb; + cmd->callback_aux = aux; + @assign_state@ + @pre_print_args@ + debug( "%s[% 2d] Enter @name@@print_fmt_args@\n", ctx->label, cmd->gen.tag@print_pass_args@ ); + @print_args@ + ctx->real_driver->@name@( ctx->real_store@pass_args@, proxy_@name@_cb, cmd ); + debug( "%s[% 2d] Leave @name@\n", ctx->label, cmd->gen.tag ); + proxy_cmd_done( &cmd->gen ); +} +//# END + +//# UNDEFINE list_store_print_fmt_cb_args +//# UNDEFINE list_store_print_pass_cb_args +//# DEFINE list_store_print_cb_args + if (sts == DRV_OK) { + for (string_list_t *box = boxes; box; box = box->next) + debug( " %s\n", box->string ); + } +//# END + +//# DEFINE load_box_pre_print_args + static char ubuf[12]; +//# END +//# DEFINE load_box_print_fmt_args , [%u,%s] (new >= %u, seen <= %u) +//# DEFINE load_box_print_pass_args , minuid, (maxuid == UINT_MAX) ? "inf" : (nfsnprintf( ubuf, sizeof(ubuf), "%u", maxuid ), ubuf), newuid, seenuid +//# DEFINE load_box_print_args + if (excs.size) { + debugn( " excs:" ); + for (int t = 0; t < excs.size; t++) + debugn( " %d", excs.data[t] ); + debug( "\n" ); + } +//# END +//# DEFINE load_box_pre_print_cb_args + static char fbuf[as(Flags) + 1]; +//# END +//# DEFINE load_box_print_fmt_cb_args , sts=%d, total=%d, recent=%d +//# DEFINE load_box_print_pass_cb_args , sts, total_msgs, recent_msgs +//# DEFINE load_box_print_cb_args + if (sts == DRV_OK) { + for (message_t *msg = msgs; msg; msg = msg->next) + debug( " uid=%5u, flags=%4s, size=%6d, tuid=%." stringify(TUIDL) "s\n", + msg->uid, (msg->status & M_FLAGS) ? (proxy_make_flags( msg->flags, fbuf ), fbuf) : "?", msg->size, *msg->tuid ? msg->tuid : "?" ); + } +//# END + +//# DEFINE find_new_msgs_print_fmt_cb_args , sts=%d +//# DEFINE find_new_msgs_print_pass_cb_args , sts +//# DEFINE find_new_msgs_print_cb_args + if (sts == DRV_OK) { + for (message_t *msg = msgs; msg; msg = msg->next) + debug( " uid=%5u, tuid=%." stringify(TUIDL) "s\n", msg->uid, msg->tuid ); + } +//# END + +//# DEFINE fetch_msg_decl_state + msg_data_t *data; +//# END +//# DEFINE fetch_msg_assign_state + cmd->data = data; +//# END +//# DEFINE fetch_msg_print_fmt_args , uid=%u, want_flags=%s, want_date=%s +//# DEFINE fetch_msg_print_pass_args , msg->uid, !(msg->status & M_FLAGS) ? "yes" : "no", data->date ? "yes" : "no" +//# DEFINE fetch_msg_pre_print_cb_args + static char fbuf[as(Flags) + 1]; + proxy_make_flags( cmd->data->flags, fbuf ); +//# END +//# DEFINE fetch_msg_print_fmt_cb_args , flags=%s, date=%ld, size=%d +//# DEFINE fetch_msg_print_pass_cb_args , fbuf, cmd->data->date, cmd->data->len +//# DEFINE fetch_msg_print_cb_args + if (sts == DRV_OK && (DFlags & DEBUG_DRV_ALL)) { + printf( "%s=========\n", cmd->gen.ctx->label ); + fwrite( cmd->data->data, cmd->data->len, 1, stdout ); + printf( "%s=========\n", cmd->gen.ctx->label ); + fflush( stdout ); + } +//# END + +//# DEFINE store_msg_pre_print_args + static char fbuf[as(Flags) + 1]; + proxy_make_flags( data->flags, fbuf ); +//# END +//# DEFINE store_msg_print_fmt_args , flags=%s, date=%ld, size=%d, to_trash=%s +//# DEFINE store_msg_print_pass_args , fbuf, data->date, data->len, to_trash ? "yes" : "no" +//# DEFINE store_msg_print_args + if (DFlags & DEBUG_DRV_ALL) { + printf( "%s>>>>>>>>>\n", ctx->label ); + fwrite( data->data, data->len, 1, stdout ); + printf( "%s>>>>>>>>>\n", ctx->label ); + fflush( stdout ); + } +//# END + +//# DEFINE set_msg_flags_pre_print_args + static char fbuf1[as(Flags) + 1], fbuf2[as(Flags) + 1]; + proxy_make_flags( add, fbuf1 ); + proxy_make_flags( del, fbuf2 ); +//# END +//# DEFINE set_msg_flags_print_fmt_args , uid=%u, add=%s, del=%s +//# DEFINE set_msg_flags_print_pass_args , uid, fbuf1, fbuf2 + +//# DEFINE trash_msg_print_fmt_args , uid=%u +//# DEFINE trash_msg_print_pass_args , msg->uid + +//# DEFINE free_store_action + proxy_store_deref( ctx ); +//# END + +//# DEFINE cancel_store_action + proxy_store_deref( ctx ); +//# END +#endif + +//# SPECIAL commit_cmds +static void +proxy_commit_cmds( store_t *gctx ) +{ + // Currently a dummy in all real drivers. + (void) gctx; +} + +//# SPECIAL set_bad_callback +static void +proxy_set_bad_callback( store_t *gctx, void (*cb)( void *aux ), void *aux ) +{ + proxy_store_t *ctx = (proxy_store_t *)gctx; + + ctx->bad_callback = cb; + ctx->bad_callback_aux = aux; +} + +static void +proxy_invoke_bad_callback( proxy_store_t *ctx ) +{ + debug( "%sCallback enter bad store\n", ctx->label ); + ctx->bad_callback( ctx->bad_callback_aux ); + debug( "%sCallback leave bad store\n", ctx->label ); \ +} + +//# EXCLUDE alloc_store +store_t * +proxy_alloc_store( store_t *real_ctx, const char *label ) +{ + proxy_store_t *ctx; + + ctx = nfcalloc( sizeof(*ctx) ); + ctx->gen.driver = &proxy_driver; + ctx->gen.conf = real_ctx->conf; + ctx->ref_count = 1; + ctx->label = label; + ctx->real_driver = real_ctx->driver; + ctx->real_store = real_ctx; + ctx->real_driver->set_bad_callback( ctx->real_store, (void (*)(void *))proxy_invoke_bad_callback, ctx ); + return &ctx->gen; +} + +//# EXCLUDE parse_store +//# EXCLUDE cleanup +//# EXCLUDE get_fail_state + +#include "drv_proxy.inc" diff -Nru isync-1.1.0/src/drv_proxy_gen.pl isync-1.2.1-1.812.20170514/src/drv_proxy_gen.pl --- isync-1.1.0/src/drv_proxy_gen.pl 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/drv_proxy_gen.pl 2017-05-26 14:36:31.000000000 +0000 @@ -0,0 +1,169 @@ +#!/usr/bin/perl +# +# mbsync - mailbox synchronizer +# Copyright (C) 2017 Oswald Buddenhagen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# As a special exception, mbsync may be linked with the OpenSSL library, +# despite that library's more restrictive license. +# + +use strict; +use warnings; + +die("Usage: $0 driver.h drv_proxy.c drv_proxy.inc\n") + if ($#ARGV != 2); + +my ($in_header, $in_source, $out_source) = @ARGV; + +my %templates; +my %defines; +my %excluded; +my %special; + +open(my $ins, $in_source) or die("Cannot open $in_source: $!\n"); +my $template; +my $define; +my $conts; +while (<$ins>) { + if ($template) { + if (/^\/\/\# END$/) { + $templates{$template} = $conts; + $template = undef; + } else { + $conts .= $_; + } + } elsif ($define) { + if (/^\/\/\# END$/) { + $defines{$define} = $conts; + $define = undef; + } else { + $conts .= $_; + } + } else { + if (/^\/\/\# TEMPLATE (\w+)$/) { + $template = $1; + $conts = ""; + } elsif (/^\/\/\# DEFINE (\w+)$/) { + $define = $1; + $conts = ""; + } elsif (/^\/\/\# DEFINE (\w+) (.*)$/) { + $defines{$1} = $2; + } elsif (/^\/\/\# UNDEFINE (\w+)$/) { + $defines{$1} = ""; + } elsif (/^\/\/\# EXCLUDE (\w+)$/) { + $excluded{$1} = 1; + } elsif (/^\/\/\# SPECIAL (\w+)$/) { + $special{$1} = 1; + } + } +} +close($ins); + +open(my $inh, $in_header) or die("Cannot open $in_header: $!\n"); +my $sts = 0; +my $cont = ""; +while (<$inh>) { + if ($sts == 0) { + if (/^struct driver \{$/) { + $sts = 1; + } + } elsif ($sts == 1) { + if (/^\};$/) { + $sts = 0; + } else { + $cont .= $_; + } + } +} +close($inh); + +$cont =~ s,\n, ,g; +$cont =~ s,/\*.*?\*/, ,g; +$cont =~ s,\h+, ,g; +my @ptypes = map { s,^ ,,r } split(/;/, $cont); +pop @ptypes; # last one is empty + +my @cmd_table; + +sub make_args($) +{ + $_ = shift; + s/(?:^|(?<=, ))(?:const )?\w+ \*?//g; + return $_; +} + +sub type_to_format($) +{ + $_ = shift; + s/xint /\%\#x/g; + s/int /\%d/g; + s/const char \*/\%s/g; + return $_; +} + +sub make_format($) +{ + $_ = type_to_format(shift); + s/, (\%\#?.)(\w+)/, $2=$1/g; + return $_; +} + +open(my $outh, ">".$out_source) or die("Cannot create $out_source: $!\n"); + +for (@ptypes) { + /^([\w* ]+)\(\*(\w+)\)\( (.*) \)$/ or die("Cannot parse prototype '$_'\n"); + my ($cmd_type, $cmd_name, $cmd_args) = ($1, $2, $3); + if (defined($excluded{$cmd_name})) { + push @cmd_table, "0"; + next; + } + push @cmd_table, "proxy_$cmd_name"; + next if (defined($special{$cmd_name})); + my %replace; + $replace{'name'} = $cmd_name; + $replace{'type'} = $cmd_type; + $cmd_args =~ s/^store_t \*ctx// or die("Arguments '$cmd_args' don't start with 'store_t *ctx'\n"); + if ($cmd_type eq "void " && $cmd_args =~ s/, void \(\*cb\)\( (.*)void \*aux \), void \*aux$//) { + my $cmd_cb_args = $1; + $replace{'decl_cb_args'} = $cmd_cb_args; + $replace{'pass_cb_args'} = make_args($cmd_cb_args); + my $cmd_print_cb_args = $cmd_cb_args =~ s/(.*), $/, $1/r; + $replace{'print_pass_cb_args'} = make_args($cmd_print_cb_args); + $replace{'print_fmt_cb_args'} = make_format($cmd_print_cb_args); + $template = "CALLBACK"; + } elsif ($cmd_name =~ /^get_/) { + $template = "GETTER"; + $replace{'fmt'} = type_to_format($cmd_type); + } elsif ($cmd_type eq "void ") { + $template = "REGULAR_VOID"; + } else { + $template = "REGULAR"; + $replace{'fmt'} = type_to_format($cmd_type); + } + $replace{'decl_args'} = $cmd_args; + $replace{'print_pass_args'} = $replace{'pass_args'} = make_args($cmd_args); + $replace{'print_fmt_args'} = make_format($cmd_args); + for (keys %defines) { + $replace{$1} = $defines{$_} if (/^${cmd_name}_(.*)$/); + } + my $text = $templates{$template}; + $text =~ s/^\h*\@(\w+)\@\n/$replace{$1} \/\/ ""/smeg; + $text =~ s/\@(\w+)\@/$replace{$1} \/\/ ""/eg; + print $outh $text."\n"; +} + +print $outh "struct driver proxy_driver = {\n".join("", map { "\t$_,\n" } @cmd_table)."};\n"; +close $outh; diff -Nru isync-1.1.0/src/main.c isync-1.2.1-1.812.20170514/src/main.c --- isync-1.1.0/src/main.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/main.c 2017-05-26 14:36:31.000000000 +0000 @@ -1,7 +1,7 @@ /* * mbsync - mailbox synchronizer * Copyright (C) 2000-2002 Michael R. Elkins - * Copyright (C) 2002-2006,2010-2012 Oswald Buddenhagen + * Copyright (C) 2002-2006,2010-2017 Oswald Buddenhagen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,12 +32,26 @@ #include int DFlags; +int JLimit; int UseFSync = 1; +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) +char FieldDelimiter = ';'; +#else +char FieldDelimiter = ':'; +#endif int Pid; /* for maildir and imap */ char Hostname[256]; /* for maildir */ const char *Home; /* for config */ +int BufferLimit = 10 * 1024 * 1024; + +int chans_total, chans_done; +int boxes_total, boxes_done; +int new_total[2], new_done[2]; +int flags_total[2], flags_done[2]; +int trash_total[2], trash_done[2]; + static void version( void ) { @@ -51,7 +65,7 @@ fputs( PACKAGE " " VERSION " - mailbox synchronizer\n" "Copyright (C) 2000-2002 Michael R. Elkins \n" -"Copyright (C) 2002-2006,2008,2010-2012 Oswald Buddenhagen \n" +"Copyright (C) 2002-2006,2008,2010-2017 Oswald Buddenhagen \n" "Copyright (C) 2004 Theodore Ts'o \n" "usage:\n" " " EXE " [flags] {{channel[:box,...]|group} ...|-a}\n" @@ -66,9 +80,9 @@ " -C, --create create mailboxes if nonexistent\n" " -X, --expunge expunge deleted messages\n" " -c, --config CONFIG read an alternate config file (default: ~/." EXE "rc)\n" -" -D, --debug print debugging messages\n" -" -V, --verbose verbose mode (display network traffic)\n" -" -q, --quiet don't display progress info\n" +" -D, --debug debugging modes (see manual)\n" +" -V, --verbose display what is happening\n" +" -q, --quiet don't display progress counters\n" " -v, --version display version\n" " -h, --help display this help message\n" "\nIf neither --pull nor --push are specified, both are active.\n" @@ -78,14 +92,44 @@ "\nSupported mailbox formats are: IMAP4rev1, Maildir\n" "\nCompile time options:\n" #ifdef HAVE_LIBSSL -" +HAVE_LIBSSL\n" +" +HAVE_LIBSSL" +#else +" -HAVE_LIBSSL" +#endif +#ifdef HAVE_LIBSASL +" +HAVE_LIBSASL" +#else +" -HAVE_LIBSASL" +#endif +#ifdef HAVE_LIBZ +" +HAVE_LIBZ" +#else +" -HAVE_LIBZ" +#endif +#ifdef USE_DB +" +USE_DB" +#else +" -USE_DB" +#endif +#ifdef HAVE_IPV6 +" +HAVE_IPV6\n" #else -" -HAVE_LIBSSL\n" +" -HAVE_IPV6\n" #endif , code ? stderr : stdout ); exit( code ); } +static void ATTR_PRINTFLIKE(1, 2) +debug( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vdebug( DEBUG_MAIN, msg, va ); + va_end( va ); +} + #ifdef __linux__ static void crashHandler( int n ) @@ -116,6 +160,32 @@ } #endif +void +stats( void ) +{ + char buf[3][64]; + char *cs; + int t, l, ll, cls; + static int cols = -1; + + if (!(DFlags & PROGRESS)) + return; + + if (cols < 0 && (!(cs = getenv( "COLUMNS" )) || !(cols = atoi( cs )))) + cols = 80; + ll = sprintf( buf[2], "C: %d/%d B: %d/%d", chans_done, chans_total, boxes_done, boxes_total ); + cls = (cols - ll - 10) / 2; + for (t = 0; t < 2; t++) { + l = sprintf( buf[t], "+%d/%d *%d/%d #%d/%d", + new_done[t], new_total[t], + flags_done[t], flags_total[t], + trash_done[t], trash_total[t] ); + if (l > cls) + buf[t][cls - 1] = '~'; + } + progress( "\r%s M: %.*s S: %.*s", buf[2], cls, buf[0], cls, buf[1] ); +} + static int matches( const char *t, const char *p ) { @@ -146,16 +216,37 @@ } } -static string_list_t * + +static int +is_inbox( const char *name ) +{ + return starts_with( name, -1, "INBOX", 5 ) && (!name[5] || name[5] == '/'); +} + +static int +cmp_box_names( const void *a, const void *b ) +{ + const char *as = *(const char **)a; + const char *bs = *(const char **)b; + int ai = is_inbox( as ); + int bi = is_inbox( bs ); + int di = bi - ai; + if (di) + return di; + return strcmp( as, bs ); +} + +static char ** filter_boxes( string_list_t *boxes, const char *prefix, string_list_t *patterns ) { - string_list_t *nboxes = 0, *cpat; + string_list_t *cpat; + char **boxarr = 0; const char *ps; - int not, fnot, pfxl; + int not, fnot, pfxl, num = 0, rnum = 0; pfxl = prefix ? strlen( prefix ) : 0; for (; boxes; boxes = boxes->next) { - if (memcmp( boxes->string, prefix, pfxl )) + if (!starts_with( boxes->string, -1, prefix, pfxl )) continue; fnot = 1; for (cpat = patterns; cpat; cpat = cpat->next) { @@ -170,10 +261,15 @@ break; } } - if (!fnot) - add_string_list( &nboxes, boxes->string + pfxl ); + if (!fnot) { + if (num + 1 >= rnum) + boxarr = nfrealloc( boxarr, (rnum = (rnum + 10) * 2) * sizeof(*boxarr) ); + boxarr[num++] = nfstrdup( boxes->string + pfxl ); + boxarr[num] = 0; + } } - return nboxes; + qsort( boxarr, num, sizeof(*boxarr), cmp_box_names ); + return boxarr; } static void @@ -195,16 +291,101 @@ } } +typedef struct box_ent { + struct box_ent *next; + char *name; + int present[2]; +} box_ent_t; + +typedef struct chan_ent { + struct chan_ent *next; + channel_conf_t *conf; + box_ent_t *boxes; + char boxlist; +} chan_ent_t; + +static chan_ent_t * +add_channel( chan_ent_t ***chanapp, channel_conf_t *chan, int ops[] ) +{ + chan_ent_t *ce = nfcalloc( sizeof(*ce) ); + ce->conf = chan; + + merge_actions( chan, ops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE ); + merge_actions( chan, ops, XOP_HAVE_CREATE, OP_CREATE, 0 ); + merge_actions( chan, ops, XOP_HAVE_REMOVE, OP_REMOVE, 0 ); + merge_actions( chan, ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 ); + + **chanapp = ce; + *chanapp = &ce->next; + chans_total++; + return ce; +} + +static chan_ent_t * +add_named_channel( chan_ent_t ***chanapp, char *channame, int ops[] ) +{ + channel_conf_t *chan; + chan_ent_t *ce; + box_ent_t *boxes = 0, **mboxapp = &boxes, *mbox; + char *boxp, *nboxp; + int boxl, boxlist = 0; + + if ((boxp = strchr( channame, ':' ))) + *boxp++ = 0; + for (chan = channels; chan; chan = chan->next) + if (!strcmp( chan->name, channame )) + goto gotchan; + error( "No channel or group named '%s' defined.\n", channame ); + return 0; + gotchan: + if (boxp) { + if (!chan->patterns) { + error( "Cannot override mailbox in channel '%s' - no Patterns.\n", channame ); + return 0; + } + boxlist = 1; + do { + nboxp = strpbrk( boxp, ",\n" ); + if (nboxp) { + boxl = nboxp - boxp; + *nboxp++ = 0; + } else { + boxl = strlen( boxp ); + } + mbox = nfmalloc( sizeof(*mbox) ); + if (boxl) + mbox->name = nfstrndup( boxp, boxl ); + else + mbox->name = nfstrndup( "INBOX", 5 ); + mbox->present[M] = mbox->present[S] = BOX_POSSIBLE; + mbox->next = 0; + *mboxapp = mbox; + mboxapp = &mbox->next; + boxes_total++; + boxp = nboxp; + } while (boxp); + } else { + if (!chan->patterns) + boxes_total++; + } + + ce = add_channel( chanapp, chan, ops ); + ce->boxes = boxes; + ce->boxlist = boxlist; + return ce; +} + typedef struct { int t[2]; channel_conf_t *chan; driver_t *drv[2]; store_t *ctx[2]; - string_list_t *boxes[2], *cboxes, *chanptr; + chan_ent_t *chanptr; + box_ent_t *boxptr; + string_list_t *boxes[2]; char *names[2]; - char **argv; - int oind, ret, multiple, all, list, ops[2], state[2]; - char done, skip, cben, boxlist; + int ret, all, list, state[2]; + char done, skip, cben; } main_vars_t; #define AUX &mvars->t[t] @@ -222,9 +403,12 @@ main( int argc, char **argv ) { main_vars_t mvars[1]; + chan_ent_t *chans = 0, **chanapp = &chans; group_conf_t *group; + channel_conf_t *chan; + string_list_t *channame; char *config = 0, *opt, *ochar; - int cops = 0, op, pseudo = 0; + int oind, cops = 0, op, ops[2] = { 0, 0 }, pseudo = 0; tzset(); gethostname( Hostname, sizeof(Hostname) ); @@ -240,23 +424,23 @@ memset( mvars, 0, sizeof(*mvars) ); mvars->t[1] = 1; - for (mvars->oind = 1, ochar = 0; ; ) { + for (oind = 1, ochar = 0; ; ) { if (!ochar || !*ochar) { - if (mvars->oind >= argc) + if (oind >= argc) break; - if (argv[mvars->oind][0] != '-') + if (argv[oind][0] != '-') break; - if (argv[mvars->oind][1] == '-') { - opt = argv[mvars->oind++] + 2; + if (argv[oind][1] == '-') { + opt = argv[oind++] + 2; if (!*opt) break; if (!strcmp( opt, "config" )) { - if (mvars->oind >= argc) { + if (oind >= argc) { error( "--config requires an argument.\n" ); return 1; } - config = argv[mvars->oind++]; - } else if (!memcmp( opt, "config=", 7 )) + config = argv[oind++]; + } else if (starts_with( opt, -1, "config=", 7 )) config = opt + 7; else if (!strcmp( opt, "all" )) mvars->all = 1; @@ -272,42 +456,66 @@ else DFlags |= QUIET; } else if (!strcmp( opt, "verbose" )) { - if (DFlags & VERBOSE) - DFlags |= XVERBOSE; + DFlags |= VERBOSE; + } else if (starts_with( opt, -1, "debug", 5 )) { + opt += 5; + if (!*opt) + op = VERBOSE | DEBUG_ALL; + else if (!strcmp( opt, "-crash" )) + op = DEBUG_CRASH; + else if (!strcmp( opt, "-driver" )) + op = VERBOSE | DEBUG_DRV; + else if (!strcmp( opt, "-driver-all" )) + op = VERBOSE | DEBUG_DRV | DEBUG_DRV_ALL; + else if (!strcmp( opt, "-maildir" )) + op = VERBOSE | DEBUG_MAILDIR; + else if (!strcmp( opt, "-main" )) + op = VERBOSE | DEBUG_MAIN; + else if (!strcmp( opt, "-net" )) + op = VERBOSE | DEBUG_NET; + else if (!strcmp( opt, "-net-all" )) + op = VERBOSE | DEBUG_NET | DEBUG_NET_ALL; + else if (!strcmp( opt, "-sync" )) + op = VERBOSE | DEBUG_SYNC; else - DFlags |= VERBOSE | QUIET; - } else if (!strcmp( opt, "debug" )) - DFlags |= DEBUG | QUIET; - else if (!strcmp( opt, "pull" )) - cops |= XOP_PULL, mvars->ops[M] |= XOP_HAVE_TYPE; + goto badopt; + DFlags |= op; + } else if (!strcmp( opt, "pull" )) + cops |= XOP_PULL, ops[M] |= XOP_HAVE_TYPE; else if (!strcmp( opt, "push" )) - cops |= XOP_PUSH, mvars->ops[M] |= XOP_HAVE_TYPE; - else if (!memcmp( opt, "create", 6 )) { + cops |= XOP_PUSH, ops[M] |= XOP_HAVE_TYPE; + else if (starts_with( opt, -1, "create", 6 )) { opt += 6; op = OP_CREATE|XOP_HAVE_CREATE; lcop: if (!*opt) cops |= op; else if (!strcmp( opt, "-master" )) - mvars->ops[M] |= op, ochar++; + ops[M] |= op; else if (!strcmp( opt, "-slave" )) - mvars->ops[S] |= op, ochar++; + ops[S] |= op; else goto badopt; - mvars->ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_EXPUNGE); - } else if (!memcmp( opt, "expunge", 7 )) { + ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_REMOVE|XOP_HAVE_EXPUNGE); + } else if (starts_with( opt, -1, "remove", 6 )) { + opt += 6; + op = OP_REMOVE|XOP_HAVE_REMOVE; + goto lcop; + } else if (starts_with( opt, -1, "expunge", 7 )) { opt += 7; op = OP_EXPUNGE|XOP_HAVE_EXPUNGE; goto lcop; } else if (!strcmp( opt, "no-expunge" )) - mvars->ops[M] |= XOP_HAVE_EXPUNGE; + ops[M] |= XOP_HAVE_EXPUNGE; else if (!strcmp( opt, "no-create" )) - mvars->ops[M] |= XOP_HAVE_CREATE; + ops[M] |= XOP_HAVE_CREATE; + else if (!strcmp( opt, "no-remove" )) + ops[M] |= XOP_HAVE_REMOVE; else if (!strcmp( opt, "full" )) - mvars->ops[M] |= XOP_HAVE_TYPE|XOP_PULL|XOP_PUSH; + ops[M] |= XOP_HAVE_TYPE|XOP_PULL|XOP_PUSH; else if (!strcmp( opt, "noop" )) - mvars->ops[M] |= XOP_HAVE_TYPE; - else if (!memcmp( opt, "pull", 4 )) { + ops[M] |= XOP_HAVE_TYPE; + else if (starts_with( opt, -1, "pull", 4 )) { op = XOP_PULL; lcac: opt += 4; @@ -318,7 +526,7 @@ goto rlcac; } else goto badopt; - } else if (!memcmp( opt, "push", 4 )) { + } else if (starts_with( opt, -1, "push", 4 )) { op = XOP_PUSH; goto lcac; } else { @@ -334,19 +542,19 @@ op |= OP_FLAGS; else { badopt: - error( "Unknown option '%s'\n", argv[mvars->oind - 1] ); + error( "Unknown option '%s'\n", argv[oind - 1] ); return 1; } switch (op & XOP_MASK_DIR) { - case XOP_PULL: mvars->ops[S] |= op & OP_MASK_TYPE; break; - case XOP_PUSH: mvars->ops[M] |= op & OP_MASK_TYPE; break; + case XOP_PULL: ops[S] |= op & OP_MASK_TYPE; break; + case XOP_PUSH: ops[M] |= op & OP_MASK_TYPE; break; default: cops |= op; break; } - mvars->ops[M] |= XOP_HAVE_TYPE; + ops[M] |= XOP_HAVE_TYPE; } continue; } - ochar = argv[mvars->oind++] + 1; + ochar = argv[oind++] + 1; if (!*ochar) { error( "Invalid option '-'\n" ); return 1; @@ -364,25 +572,28 @@ ochar++; pseudo = 1; } - if (mvars->oind >= argc) { + if (oind >= argc) { error( "-c requires an argument.\n" ); return 1; } - config = argv[mvars->oind++]; + config = argv[oind++]; break; case 'C': op = OP_CREATE|XOP_HAVE_CREATE; cop: if (*ochar == 'm') - mvars->ops[M] |= op, ochar++; + ops[M] |= op, ochar++; else if (*ochar == 's') - mvars->ops[S] |= op, ochar++; + ops[S] |= op, ochar++; else if (*ochar == '-') ochar++; else cops |= op; - mvars->ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_EXPUNGE); + ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_REMOVE|XOP_HAVE_EXPUNGE); break; + case 'R': + op = OP_REMOVE|XOP_HAVE_REMOVE; + goto cop; case 'X': op = OP_EXPUNGE|XOP_HAVE_EXPUNGE; goto cop; @@ -390,7 +601,7 @@ cops |= XOP_PULL|XOP_PUSH; /* fallthrough */ case '0': - mvars->ops[M] |= XOP_HAVE_TYPE; + ops[M] |= XOP_HAVE_TYPE; break; case 'n': case 'd': @@ -413,13 +624,13 @@ } if (op & OP_MASK_TYPE) switch (op & XOP_MASK_DIR) { - case XOP_PULL: mvars->ops[S] |= op & OP_MASK_TYPE; break; - case XOP_PUSH: mvars->ops[M] |= op & OP_MASK_TYPE; break; + case XOP_PULL: ops[S] |= op & OP_MASK_TYPE; break; + case XOP_PUSH: ops[M] |= op & OP_MASK_TYPE; break; default: cops |= op; break; } else cops |= op; - mvars->ops[M] |= XOP_HAVE_TYPE; + ops[M] |= XOP_HAVE_TYPE; break; case 'L': op = XOP_PULL; @@ -434,19 +645,47 @@ DFlags |= QUIET; break; case 'V': - if (DFlags & VERBOSE) - DFlags |= XVERBOSE; - else - DFlags |= VERBOSE | QUIET; + DFlags |= VERBOSE; break; case 'D': - if (*ochar == 'C') - DFlags |= CRASHDEBUG, ochar++; - else - DFlags |= CRASHDEBUG | DEBUG | QUIET; + for (op = 0; *ochar; ochar++) { + switch (*ochar) { + case 'C': + op |= DEBUG_CRASH; + break; + case 'd': + op |= DEBUG_DRV | VERBOSE; + break; + case 'D': + op |= DEBUG_DRV | DEBUG_DRV_ALL | VERBOSE; + break; + case 'm': + op |= DEBUG_MAILDIR | VERBOSE; + break; + case 'M': + op |= DEBUG_MAIN | VERBOSE; + break; + case 'n': + op |= DEBUG_NET | VERBOSE; + break; + case 'N': + op |= DEBUG_NET | DEBUG_NET_ALL | VERBOSE; + break; + case 's': + op |= DEBUG_SYNC | VERBOSE; + break; + default: + error( "Unknown -D flag '%c'\n", *ochar ); + return 1; + } + } + if (!op) + op = DEBUG_ALL | VERBOSE; + DFlags |= op; break; case 'J': DFlags |= KEEPJOURNAL; + JLimit = strtol( ochar, &ochar, 10 ); break; case 'Z': DFlags |= ZERODELAY; @@ -461,55 +700,95 @@ } } + if (!(DFlags & (QUIET | DEBUG_ALL)) && isatty( 1 )) + DFlags |= PROGRESS; + #ifdef __linux__ - if (DFlags & CRASHDEBUG) { + if (DFlags & DEBUG_CRASH) { signal( SIGSEGV, crashHandler ); signal( SIGBUS, crashHandler ); signal( SIGILL, crashHandler ); } #endif - if (merge_ops( cops, mvars->ops )) + if (merge_ops( cops, ops )) return 1; if (load_config( config, pseudo )) return 1; - if (!mvars->all && !argv[mvars->oind]) { - fputs( "No channel specified. Try '" EXE " -h'\n", stderr ); - return 1; - } if (!channels) { fputs( "No channels defined. Try 'man " EXE "'\n", stderr ); return 1; } - mvars->chan = channels; - if (mvars->all) - mvars->multiple = channels->next != 0; - else if (argv[mvars->oind + 1]) - mvars->multiple = 1; - else - for (group = groups; group; group = group->next) - if (!strcmp( group->name, argv[mvars->oind] )) { - mvars->multiple = 1; - break; + if (mvars->all) { + for (chan = channels; chan; chan = chan->next) { + add_channel( &chanapp, chan, ops ); + if (!chan->patterns) + boxes_total++; + } + } else { + for (; argv[oind]; oind++) { + for (group = groups; group; group = group->next) { + if (!strcmp( group->name, argv[oind] )) { + for (channame = group->channels; channame; channame = channame->next) + if (!add_named_channel( &chanapp, channame->string, ops )) + mvars->ret = 1; + goto gotgrp; + } } - mvars->argv = argv; + if (!add_named_channel( &chanapp, argv[oind], ops )) + mvars->ret = 1; + gotgrp: ; + } + } + if (!chans) { + fputs( "No channel specified. Try '" EXE " -h'\n", stderr ); + return 1; + } + mvars->chanptr = chans; + + if (!mvars->list) + stats(); mvars->cben = 1; sync_chans( mvars, E_START ); main_loop(); + if (!mvars->list) + flushn(); return mvars->ret; } #define ST_FRESH 0 -#define ST_OPEN 1 -#define ST_CLOSED 2 +#define ST_CONNECTED 1 +#define ST_OPEN 2 +#define ST_CANCELING 3 +#define ST_CLOSED 4 + +static void +cancel_prep_done( void *aux ) +{ + MVARS(aux) + + mvars->drv[t]->free_store( mvars->ctx[t] ); + mvars->state[t] = ST_CLOSED; + sync_chans( mvars, E_OPEN ); +} + +static void +store_bad( void *aux ) +{ + MVARS(aux) -static void store_opened( store_t *ctx, void *aux ); -static void store_listed( int sts, void *aux ); -static int sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox ); -static void done_sync_dyn( int sts, void *aux ); + mvars->drv[t]->cancel_store( mvars->ctx[t] ); + mvars->state[t] = ST_CLOSED; + mvars->ret = mvars->skip = 1; + sync_chans( mvars, E_OPEN ); +} + +static void store_connected( int sts, void *aux ); +static void store_listed( int sts, string_list_t *boxes, void *aux ); +static int sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox ); static void done_sync_2_dyn( int sts, void *aux ); static void done_sync( int sts, void *aux ); @@ -518,12 +797,10 @@ static void sync_chans( main_vars_t *mvars, int ent ) { - group_conf_t *group; - channel_conf_t *chan; - string_list_t *mbox, *sbox, **mboxp, **sboxp; - char *channame, *boxp, *nboxp; + box_ent_t *mbox, *nmbox, **mboxapp; + char **boxes[2]; const char *labels[2]; - int t; + int t, mb, sb, cmp; if (!mvars->cben) return; @@ -531,75 +808,43 @@ case E_OPEN: goto opened; case E_SYNC: goto syncone; } - for (;;) { - mvars->boxlist = 0; - mvars->boxes[M] = mvars->boxes[S] = mvars->cboxes = 0; - if (!mvars->all) { - if (mvars->chanptr) - channame = mvars->chanptr->string; - else { - for (group = groups; group; group = group->next) - if (!strcmp( group->name, mvars->argv[mvars->oind] )) { - mvars->chanptr = group->channels; - channame = mvars->chanptr->string; - goto gotgrp; - } - channame = mvars->argv[mvars->oind]; - gotgrp: ; - } - if ((boxp = strchr( channame, ':' ))) - *boxp++ = 0; - for (chan = channels; chan; chan = chan->next) - if (!strcmp( chan->name, channame )) - goto gotchan; - error( "No channel or group named '%s' defined.\n", channame ); - mvars->ret = 1; - goto gotnone; - gotchan: - mvars->chan = chan; - if (boxp) { - if (!chan->patterns) { - error( "Cannot override mailbox in channel '%s' - no Patterns.\n", channame ); - mvars->ret = 1; - goto gotnone; - } - mvars->boxlist = 1; - for (;;) { - nboxp = strpbrk( boxp, ",\n" ); - if (nboxp) { - t = nboxp - boxp; - *nboxp++ = 0; - } else { - t = strlen( boxp ); - } - if (t) - add_string_list_n( &mvars->cboxes, boxp, t ); - else - add_string_list_n( &mvars->cboxes, "INBOX", 5 ); - if (!nboxp) - break; - boxp = nboxp; - } + do { + mvars->chan = mvars->chanptr->conf; + info( "Channel %s\n", mvars->chan->name ); + mvars->skip = mvars->cben = 0; + for (t = 0; t < 2; t++) { + int st = mvars->chan->stores[t]->driver->get_fail_state( mvars->chan->stores[t] ); + if (st != FAIL_TEMP) { + info( "Skipping due to %sfailed %s store %s.\n", + (st == FAIL_WAIT) ? "temporarily " : "", str_ms[t], mvars->chan->stores[t]->name ); + mvars->skip = 1; } } - merge_actions( mvars->chan, mvars->ops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE ); - merge_actions( mvars->chan, mvars->ops, XOP_HAVE_CREATE, OP_CREATE, 0 ); - merge_actions( mvars->chan, mvars->ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 ); - + if (mvars->skip) + goto next2; mvars->state[M] = mvars->state[S] = ST_FRESH; - info( "Channel %s\n", mvars->chan->name ); - mvars->skip = mvars->cben = 0; - if (mvars->chan->stores[M]->driver->flags & mvars->chan->stores[S]->driver->flags & DRV_VERBOSE) + if ((DFlags & DEBUG_DRV) || (mvars->chan->stores[M]->driver->get_caps( 0 ) & mvars->chan->stores[S]->driver->get_caps( 0 ) & DRV_VERBOSE)) labels[M] = "M: ", labels[S] = "S: "; else labels[M] = labels[S] = ""; for (t = 0; t < 2; t++) { - info( "Opening %s %s...\n", str_ms[t], mvars->chan->stores[t]->name ); - mvars->drv[t] = mvars->chan->stores[t]->driver; - mvars->drv[t]->open_store( mvars->chan->stores[t], labels[t], store_opened, AUX ); - if (mvars->skip) + driver_t *drv = mvars->chan->stores[t]->driver; + store_t *ctx = drv->alloc_store( mvars->chan->stores[t], labels[t] ); + if (DFlags & DEBUG_DRV) { + drv = &proxy_driver; + ctx = proxy_alloc_store( ctx, labels[t] ); + } + mvars->drv[t] = drv; + mvars->ctx[t] = ctx; + drv->set_bad_callback( ctx, store_bad, AUX ); + } + for (t = 0; ; t++) { + info( "Opening %s store %s...\n", str_ms[t], mvars->chan->stores[t]->name ); + mvars->drv[t]->connect_store( mvars->ctx[t], store_connected, AUX ); + if (t || mvars->skip) break; } + mvars->cben = 1; opened: if (mvars->skip) @@ -607,48 +852,60 @@ if (mvars->state[M] != ST_OPEN || mvars->state[S] != ST_OPEN) return; - if (!mvars->boxlist && mvars->chan->patterns) { - mvars->boxlist = 1; - mvars->boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->boxes[M], mvars->chan->patterns ); - mvars->boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->boxes[S], mvars->chan->patterns ); - for (mboxp = &mvars->boxes[M]; (mbox = *mboxp); ) { - for (sboxp = &mvars->boxes[S]; (sbox = *sboxp); sboxp = &sbox->next) - if (!strcmp( sbox->string, mbox->string )) { - *sboxp = sbox->next; - free( sbox ); - *mboxp = mbox->next; - mbox->next = mvars->cboxes; - mvars->cboxes = mbox; - goto gotdupe; - } - mboxp = &mbox->next; - gotdupe: ; + if (!mvars->chanptr->boxlist && mvars->chan->patterns) { + mvars->chanptr->boxlist = 2; + boxes[M] = filter_boxes( mvars->boxes[M], mvars->chan->boxes[M], mvars->chan->patterns ); + boxes[S] = filter_boxes( mvars->boxes[S], mvars->chan->boxes[S], mvars->chan->patterns ); + mboxapp = &mvars->chanptr->boxes; + for (mb = sb = 0; ; ) { + char *mname = boxes[M] ? boxes[M][mb] : 0; + char *sname = boxes[S] ? boxes[S][sb] : 0; + if (!mname && !sname) + break; + mbox = nfmalloc( sizeof(*mbox) ); + if (!(cmp = !mname - !sname) && !(cmp = cmp_box_names( &mname, &sname ))) { + mbox->name = mname; + free( sname ); + mbox->present[M] = mbox->present[S] = BOX_PRESENT; + mb++; + sb++; + } else if (cmp < 0) { + mbox->name = mname; + mbox->present[M] = BOX_PRESENT; + mbox->present[S] = (!mb && !strcmp( mbox->name, "INBOX" )) ? BOX_PRESENT : BOX_ABSENT; + mb++; + } else { + mbox->name = sname; + mbox->present[M] = (!sb && !strcmp( mbox->name, "INBOX" )) ? BOX_PRESENT : BOX_ABSENT; + mbox->present[S] = BOX_PRESENT; + sb++; + } + mbox->next = 0; + *mboxapp = mbox; + mboxapp = &mbox->next; + boxes_total++; } + free( boxes[M] ); + free( boxes[S] ); + if (!mvars->list) + stats(); } + mvars->boxptr = mvars->chanptr->boxes; - if (mvars->list && mvars->multiple) + if (mvars->list && chans_total > 1) printf( "%s:\n", mvars->chan->name ); syncml: mvars->done = mvars->cben = 0; - if (mvars->boxlist) { - while ((mbox = mvars->cboxes)) { - mvars->cboxes = mbox->next; + if (mvars->chanptr->boxlist) { + while ((mbox = mvars->boxptr)) { + mvars->boxptr = mbox->next; if (sync_listed_boxes( mvars, mbox )) goto syncw; } - for (t = 0; t < 2; t++) - while ((mbox = mvars->boxes[t])) { - mvars->boxes[t] = mbox->next; - if ((mvars->chan->ops[1-t] & OP_MASK_TYPE) && (mvars->chan->ops[1-t] & OP_CREATE)) { - if (sync_listed_boxes( mvars, mbox )) - goto syncw; - } else { - free( mbox ); - } - } } else { if (!mvars->list) { - sync_boxes( mvars->ctx, mvars->chan->boxes, mvars->chan, done_sync, mvars ); + int present[] = { BOX_POSSIBLE, BOX_POSSIBLE }; + sync_boxes( mvars->ctx, mvars->chan->boxes, present, mvars->chan, done_sync, mvars ); mvars->skip = 1; syncw: mvars->cben = 1; @@ -662,124 +919,131 @@ } next: - for (t = 0; t < 2; t++) - if (mvars->state[t] == ST_OPEN) { - mvars->drv[t]->disown_store( mvars->ctx[t] ); + mvars->cben = 0; + for (t = 0; t < 2; t++) { + free_string_list( mvars->boxes[t] ); + mvars->boxes[t] = 0; + if (mvars->state[t] == ST_FRESH) { + /* An unconnected store may be only cancelled. */ mvars->state[t] = ST_CLOSED; + mvars->drv[t]->cancel_store( mvars->ctx[t] ); + } else if (mvars->state[t] == ST_CONNECTED || mvars->state[t] == ST_OPEN) { + mvars->state[t] = ST_CANCELING; + mvars->drv[t]->cancel_cmds( mvars->ctx[t], cancel_prep_done, AUX ); } + } + mvars->cben = 1; if (mvars->state[M] != ST_CLOSED || mvars->state[S] != ST_CLOSED) { - mvars->skip = mvars->cben = 1; + mvars->skip = 1; return; } - free_string_list( mvars->cboxes ); - free_string_list( mvars->boxes[M] ); - free_string_list( mvars->boxes[S] ); - if (mvars->all) { - if (!(mvars->chan = mvars->chan->next)) - break; - } else { - if (mvars->chanptr && (mvars->chanptr = mvars->chanptr->next)) - continue; - gotnone: - if (!mvars->argv[++mvars->oind]) - break; + if (mvars->chanptr->boxlist == 2) { + for (nmbox = mvars->chanptr->boxes; (mbox = nmbox); ) { + nmbox = mbox->next; + free( mbox->name ); + free( mbox ); + } + mvars->chanptr->boxes = 0; + mvars->chanptr->boxlist = 0; } - } + next2: + if (!mvars->list) { + chans_done++; + stats(); + } + } while ((mvars->chanptr = mvars->chanptr->next)); for (t = 0; t < N_DRIVERS; t++) drivers[t]->cleanup(); } static void -store_bad( void *aux ) -{ - MVARS(aux) - - mvars->drv[t]->cancel_store( mvars->ctx[t] ); - mvars->ret = mvars->skip = 1; - mvars->state[t] = ST_CLOSED; - sync_chans( mvars, E_OPEN ); -} - -static void -store_opened( store_t *ctx, void *aux ) +store_connected( int sts, void *aux ) { MVARS(aux) string_list_t *cpat; - int flags; + int cflags; - if (!ctx) { - mvars->ret = mvars->skip = 1; - mvars->state[t] = ST_CLOSED; - sync_chans( mvars, E_OPEN ); + switch (sts) { + case DRV_CANCELED: return; - } - mvars->ctx[t] = ctx; - if (!mvars->skip && !mvars->boxlist && mvars->chan->patterns && !ctx->listed) { - for (flags = 0, cpat = mvars->chan->patterns; cpat; cpat = cpat->next) { - const char *pat = cpat->string; - if (*pat != '!') { - char buf[8]; - snprintf( buf, sizeof(buf), "%s%s", mvars->chan->boxes[t], pat ); - /* Partial matches like "INB*" or even "*" are not considered, - * except implicity when the INBOX lives under Path. */ - if (!memcmp( buf, "INBOX", 5 )) { - char c = buf[5]; - if (!c) { - /* User really wants the INBOX. */ - flags |= LIST_INBOX; - } else if (c == '/') { - /* Flattened sub-folders of INBOX actually end up in Path. */ - if (ctx->conf->flat_delim) - flags |= LIST_PATH; - else + case DRV_OK: + if (!mvars->skip && !mvars->chanptr->boxlist && mvars->chan->patterns) { + for (cflags = 0, cpat = mvars->chan->patterns; cpat; cpat = cpat->next) { + const char *pat = cpat->string; + if (*pat != '!') { + char buf[8]; + int bufl = snprintf( buf, sizeof(buf), "%s%s", nz( mvars->chan->boxes[t], "" ), pat ); + int flags = 0; + /* Partial matches like "INB*" or even "*" are not considered, + * except implicity when the INBOX lives under Path. */ + if (starts_with( buf, bufl, "INBOX", 5 )) { + char c = buf[5]; + if (!c) { + /* User really wants the INBOX. */ flags |= LIST_INBOX; + } else if (c == '/') { + /* Flattened sub-folders of INBOX actually end up in Path. */ + if (mvars->ctx[t]->conf->flat_delim) + flags |= LIST_PATH; + else + flags |= LIST_INBOX; + } else if (c == '*' || c == '%') { + /* It can be both INBOX and Path, but don't require Path to be configured. */ + flags |= LIST_INBOX | LIST_PATH_MAYBE; + } else { + /* It's definitely not the INBOX. */ + flags |= LIST_PATH; + } } else { - /* User may not want the INBOX after all ... */ flags |= LIST_PATH; - /* ... but maybe he does. - * The flattened sub-folder case is implicitly covered by the previous line. */ - if (c == '*' || c == '%') - flags |= LIST_INBOX; } - } else { - flags |= LIST_PATH; + debug( "pattern '%s' (effective '%s'): %sPath, %sINBOX\n", + pat, buf, (flags & LIST_PATH) ? "" : "no ", (flags & LIST_INBOX) ? "" : "no "); + cflags |= flags; } } + mvars->state[t] = ST_CONNECTED; + mvars->drv[t]->list_store( mvars->ctx[t], cflags, store_listed, AUX ); + return; } - set_bad_callback( ctx, store_bad, AUX ); - mvars->drv[t]->list( ctx, flags, store_listed, AUX ); - } else { mvars->state[t] = ST_OPEN; - sync_chans( mvars, E_OPEN ); + break; + default: + mvars->ret = mvars->skip = 1; + mvars->state[t] = ST_OPEN; + break; } + sync_chans( mvars, E_OPEN ); } static void -store_listed( int sts, void *aux ) +store_listed( int sts, string_list_t *boxes, void *aux ) { MVARS(aux) - string_list_t **box; + string_list_t *box; switch (sts) { case DRV_CANCELED: return; case DRV_OK: - mvars->ctx[t]->listed = 1; - if (mvars->ctx[t]->conf->flat_delim) { - for (box = &mvars->ctx[t]->boxes; *box; box = &(*box)->next) { + for (box = boxes; box; box = box->next) { + if (mvars->ctx[t]->conf->flat_delim) { string_list_t *nbox; - if (map_name( (*box)->string, (char **)&nbox, offsetof(string_list_t, string), mvars->ctx[t]->conf->flat_delim, "/" ) < 0) { - error( "Error: flattened mailbox name '%s' contains canonical hierarchy delimiter\n", (*box)->string ); + if (map_name( box->string, (char **)&nbox, offsetof(string_list_t, string), mvars->ctx[t]->conf->flat_delim, "/" ) < 0) { + error( "Error: flattened mailbox name '%s' contains canonical hierarchy delimiter\n", box->string ); mvars->ret = mvars->skip = 1; } else { - nbox->next = (*box)->next; - free( *box ); - *box = nbox; + nbox->next = mvars->boxes[t]; + mvars->boxes[t] = nbox; } + } else { + add_string_list( &mvars->boxes[t], box->string ); } } - if (mvars->ctx[t]->conf->map_inbox) - add_string_list( &mvars->ctx[t]->boxes, mvars->ctx[t]->conf->map_inbox ); + if (mvars->ctx[t]->conf->map_inbox) { + debug( "adding mapped inbox to %s: %s\n", str_ms[t], mvars->ctx[t]->conf->map_inbox ); + add_string_list( &mvars->boxes[t], mvars->ctx[t]->conf->map_inbox ); + } break; default: mvars->ret = mvars->skip = 1; @@ -790,41 +1054,30 @@ } static int -sync_listed_boxes( main_vars_t *mvars, string_list_t *mbox ) +sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox ) { if (mvars->chan->boxes[M] || mvars->chan->boxes[S]) { const char *mpfx = nz( mvars->chan->boxes[M], "" ); const char *spfx = nz( mvars->chan->boxes[S], "" ); if (!mvars->list) { - nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->string ); - nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->string ); - free( mbox ); - sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_2_dyn, mvars ); + nfasprintf( &mvars->names[M], "%s%s", mpfx, mbox->name ); + nfasprintf( &mvars->names[S], "%s%s", spfx, mbox->name ); + sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync_2_dyn, mvars ); return 1; } - printf( "%s%s <=> %s%s\n", mpfx, mbox->string, spfx, mbox->string ); + printf( "%s%s <=> %s%s\n", mpfx, mbox->name, spfx, mbox->name ); } else { if (!mvars->list) { - mvars->names[M] = mvars->names[S] = mbox->string; - sync_boxes( mvars->ctx, (const char **)mvars->names, mvars->chan, done_sync_dyn, mvars ); + mvars->names[M] = mvars->names[S] = mbox->name; + sync_boxes( mvars->ctx, (const char **)mvars->names, mbox->present, mvars->chan, done_sync, mvars ); return 1; } - puts( mbox->string ); + puts( mbox->name ); } - free( mbox ); return 0; } static void -done_sync_dyn( int sts, void *aux ) -{ - main_vars_t *mvars = (main_vars_t *)aux; - - free( ((char *)mvars->names[S]) - offsetof(string_list_t, string) ); - done_sync( sts, aux ); -} - -static void done_sync_2_dyn( int sts, void *aux ) { main_vars_t *mvars = (main_vars_t *)aux; @@ -840,6 +1093,8 @@ main_vars_t *mvars = (main_vars_t *)aux; mvars->done = 1; + boxes_done++; + stats(); if (sts) { mvars->ret = 1; if (sts & (SYNC_BAD(M) | SYNC_BAD(S))) { @@ -848,8 +1103,6 @@ if (sts & SYNC_BAD(S)) mvars->state[S] = ST_CLOSED; mvars->skip = 1; - } else if (sts & SYNC_FAIL_ALL) { - mvars->skip = 1; } } sync_chans( mvars, E_SYNC ); diff -Nru isync-1.1.0/src/Makefile.am isync-1.2.1-1.812.20170514/src/Makefile.am --- isync-1.1.0/src/Makefile.am 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/Makefile.am 2017-05-26 14:36:31.000000000 +0000 @@ -3,18 +3,31 @@ endif SUBDIRS = $(compat_dir) -bin_PROGRAMS = mbsync mdconvert - -mbsync_SOURCES = main.c sync.c config.c util.c socket.c driver.c drv_imap.c drv_maildir.c -mbsync_LDADD = -ldb $(SSL_LIBS) $(SOCK_LIBS) +mbsync_SOURCES = main.c sync.c config.c util.c socket.c driver.c drv_imap.c drv_maildir.c drv_proxy.c +mbsync_LDADD = $(DB_LIBS) $(SSL_LIBS) $(SOCK_LIBS) $(SASL_LIBS) $(Z_LIBS) noinst_HEADERS = common.h config.h driver.h sync.h socket.h +drv_proxy.$(OBJEXT): drv_proxy.inc +drv_proxy.inc: $(srcdir)/driver.h $(srcdir)/drv_proxy.c $(srcdir)/drv_proxy_gen.pl + perl $(srcdir)/drv_proxy_gen.pl $(srcdir)/driver.h $(srcdir)/drv_proxy.c drv_proxy.inc + mdconvert_SOURCES = mdconvert.c -mdconvert_LDADD = -ldb +mdconvert_LDADD = $(DB_LIBS) +if with_mdconvert +mdconvert_prog = mdconvert +mdconvert_man = mdconvert.1 +endif -man_MANS = mbsync.1 mdconvert.1 +EXTRA_PROGRAMS = tst_timers + +tst_timers_SOURCES = tst_timers.c util.c + +bin_PROGRAMS = mbsync $(mdconvert_prog) +man_MANS = mbsync.1 $(mdconvert_man) exampledir = $(docdir)/examples example_DATA = mbsyncrc.sample -EXTRA_DIST = run-tests.pl $(example_DATA) $(man_MANS) +EXTRA_DIST = drv_proxy_gen.pl run-tests.pl $(example_DATA) $(man_MANS) + +CLEANFILES = drv_proxy.inc diff -Nru isync-1.1.0/src/Makefile.in isync-1.2.1-1.812.20170514/src/Makefile.in --- isync-1.1.0/src/Makefile.in 2013-12-18 21:09:58.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,801 +0,0 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -bin_PROGRAMS = mbsync$(EXEEXT) mdconvert$(EXEEXT) -subdir = src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/depcomp $(noinst_HEADERS) -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/autodefs.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(exampledir)" -PROGRAMS = $(bin_PROGRAMS) -am_mbsync_OBJECTS = main.$(OBJEXT) sync.$(OBJEXT) config.$(OBJEXT) \ - util.$(OBJEXT) socket.$(OBJEXT) driver.$(OBJEXT) \ - drv_imap.$(OBJEXT) drv_maildir.$(OBJEXT) -mbsync_OBJECTS = $(am_mbsync_OBJECTS) -am__DEPENDENCIES_1 = -mbsync_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_mdconvert_OBJECTS = mdconvert.$(OBJEXT) -mdconvert_OBJECTS = $(am_mdconvert_OBJECTS) -mdconvert_DEPENDENCIES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(mbsync_SOURCES) $(mdconvert_SOURCES) -DIST_SOURCES = $(mbsync_SOURCES) $(mdconvert_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -man1dir = $(mandir)/man1 -NROFF = nroff -MANS = $(man_MANS) -DATA = $(example_DATA) -HEADERS = $(noinst_HEADERS) -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = compat -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKGCONFIG = @PKGCONFIG@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SOCK_LIBS = @SOCK_LIBS@ -SSL_LIBS = @SSL_LIBS@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -@with_compat_TRUE@compat_dir = compat -SUBDIRS = $(compat_dir) -mbsync_SOURCES = main.c sync.c config.c util.c socket.c driver.c drv_imap.c drv_maildir.c -mbsync_LDADD = -ldb $(SSL_LIBS) $(SOCK_LIBS) -noinst_HEADERS = common.h config.h driver.h sync.h socket.h -mdconvert_SOURCES = mdconvert.c -mdconvert_LDADD = -ldb -man_MANS = mbsync.1 mdconvert.1 -exampledir = $(docdir)/examples -example_DATA = mbsyncrc.sample -EXTRA_DIST = run-tests.pl $(example_DATA) $(man_MANS) -all: all-recursive - -.SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) - -mbsync$(EXEEXT): $(mbsync_OBJECTS) $(mbsync_DEPENDENCIES) $(EXTRA_mbsync_DEPENDENCIES) - @rm -f mbsync$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(mbsync_OBJECTS) $(mbsync_LDADD) $(LIBS) - -mdconvert$(EXEEXT): $(mdconvert_OBJECTS) $(mdconvert_DEPENDENCIES) $(EXTRA_mdconvert_DEPENDENCIES) - @rm -f mdconvert$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(mdconvert_OBJECTS) $(mdconvert_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_imap.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_maildir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdconvert.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sync.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -install-man1: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man1dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.1[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -install-exampleDATA: $(example_DATA) - @$(NORMAL_INSTALL) - @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exampledir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(exampledir)" || exit $$?; \ - done - -uninstall-exampleDATA: - @$(NORMAL_UNINSTALL) - @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(exampledir)'; $(am__uninstall_files_from_dir) - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) -installdirs: installdirs-recursive -installdirs-am: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(exampledir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am - -distclean: distclean-recursive - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: install-exampleDATA install-man - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: install-man1 - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-exampleDATA \ - uninstall-man - -uninstall-man: uninstall-man1 - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-binPROGRAMS clean-generic cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exampleDATA \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-man1 \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-exampleDATA uninstall-man \ - uninstall-man1 - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff -Nru isync-1.1.0/src/mbsync.1 isync-1.2.1-1.812.20170514/src/mbsync.1 --- isync-1.1.0/src/mbsync.1 2013-12-15 12:46:25.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/mbsync.1 2017-05-26 14:36:31.000000000 +0000 @@ -1,7 +1,7 @@ .ig \" mbsync - mailbox synchronizer \" Copyright (C) 2000-2002 Michael R. Elkins -\" Copyright (C) 2002-2004,2011-2013 Oswald Buddenhagen +\" Copyright (C) 2002-2004,2011-2015 Oswald Buddenhagen \" Copyright (C) 2004 Theodore Y. Ts'o \" \" This program is free software; you can redistribute it and/or modify @@ -20,7 +20,7 @@ \" As a special exception, mbsync may be linked with the OpenSSL library, \" despite that library's more restrictive license. .. -.TH mbsync 1 "2013 Dec 14" +.TH mbsync 1 "2015 Mar 22" .. .SH NAME mbsync - synchronize IMAP4 and Maildir mailboxes @@ -35,11 +35,14 @@ the operation set can be selected in a fine-grained manner. .br Synchronization is based on unique message identifiers (UIDs), so no -identification conflicts can occur (as opposed to some other mail synchronizers). -OTOH, \fBmbsync\fR is susceptible to UID validity changes (that \fIshould\fR -never happen, but see "Compatibility" in the README). +identification conflicts can occur (unlike with some other mail synchronizers). +OTOH, \fBmbsync\fR is susceptible to UID validity changes (but will recover +just fine if the change is unfounded). Synchronization state is kept in one local text file per mailbox pair; -multiple replicas of a mailbox can be maintained. +these files are protected against concurrent \fBmbsync\fR processes. +Mailboxes can be safely modified while \fBmbsync\fR operates +(see \fBINHERENT PROBLEMS\fR below for a minor exception). +Multiple replicas of each mailbox can be maintained. .. .SH OPTIONS .TP @@ -58,6 +61,9 @@ \fB-C\fR[\fBm\fR][\fBs\fR], \fB--create\fR[\fB-master\fR|\fB-slave\fR] Override any \fBCreate\fR options from the config file. See below. .TP +\fB-R\fR[\fBm\fR][\fBs\fR], \fB--remove\fR[\fB-master\fR|\fB-slave\fR] +Override any \fBRemove\fR options from the config file. See below. +.TP \fB-X\fR[\fBm\fR][\fBs\fR], \fB--expunge\fR[\fB-master\fR|\fB-slave\fR] Override any \fBExpunge\fR options from the config file. See below. .TP @@ -75,13 +81,34 @@ Display version information. .TP \fB-V\fR, \fB--verbose\fR -Enable \fIverbose\fR mode, which displays the IMAP4 network traffic. +Enable \fIverbose\fR mode, which displays what is currently happening. .TP -\fB-D\fR, \fB--debug\fR -Enable printing \fIdebug\fR information. +\fB-D\fR[\fBC\fR][\fBd\fR|\fBD\fR][\fBm\fR][\fBM\fR][\fBn\fR|\fBN\fR][\fBs\fR]\fR]\fR,\ + \fB--debug\fR[\fB-crash\fR|\fB-driver\fR|\fB-driver-all\fR|\fB-maildir\fR|\fB-main\fR|\fB-net\fR|\fB-net-all\fR|\fB-sync\fR] +Enable debugging categories: +.in +4 +\fBC\fR, \fBcrash\fR - use built-in crash handler +.br +\fBd\fR, \fBdriver\fR - print driver calls (metadata only) +.br +\fBD\fR, \fBdriver-all\fR - print driver calls (including messages) +.br +\fBm\fR, \fBmaildir\fR - print maildir debug info +.br +\fBM\fR, \fBmain\fR - print main debug info +.br +\fBn\fR, \fBnet\fR - print network traffic (protocol only) +.br +\fBN\fR, \fBnet-all\fR - print network traffic (including payloads) +.br +\fBs\fR, \fBsync\fR - print synchronization debug info +.in -4 +All categories except \fBcrash\fR implictly enable \fIverbose\fR mode. +Without category specification, all categories except net-all are enabled. .TP \fB-q\fR, \fB--quiet\fR -Suppress informational messages. +Suppress progress counters (this is implicit if stdout is no TTY, +or any debugging categories are enabled) and notices. If specified twice, suppress warning messages as well. .. .SH CONFIGURATION @@ -133,7 +160,7 @@ in the Channels section. Note that you \fBmust\fR append a slash if you want to specify an entire directory. -(Default: \fI""\fR) +(Default: none) .. .TP \fBMaxSize\fR \fIsize\fR[\fBk\fR|\fBm\fR][\fBb\fR] @@ -172,17 +199,17 @@ (Default: none) .. .TP -\fBTrashNewOnly\fR \fIyes\fR|\fIno\fR +\fBTrashNewOnly\fR \fByes\fR|\fBno\fR When trashing, copy only not yet propagated messages. This makes sense if the -remote Store has a \fBTrash\fR as well (with \fBTrashNewOnly\fR \fIno\fR). -(Default: \fIno\fR) +remote Store has a \fBTrash\fR as well (with \fBTrashNewOnly\fR \fBno\fR). +(Default: \fBno\fR) .. .TP -\fBTrashRemoteNew\fR \fIyes\fR|\fIno\fR +\fBTrashRemoteNew\fR \fByes\fR|\fBno\fR When expunging the remote Store, copy not yet propagated messages to this Store's \fBTrash\fR. When using this, the remote Store does not need an own \fBTrash\fR at all, yet all messages are archived. -(Default: \fIno\fR) +(Default: \fBno\fR) .. .SS Maildir Stores The reference point for relative \fBPath\fRs is the current working directory. @@ -199,7 +226,7 @@ are used as keys into a Berkeley database named .isyncuidmap.db, which holds the UID validity as well. .br -The \fBnative\fR scheme is faster, more space efficient, endianess independent +The \fBnative\fR scheme is faster, more space efficient, endianness independent and "human readable", but will be disrupted if a message is copied from another mailbox without getting a new file name; this would result in duplicated UIDs sooner or later, which in turn results in a UID validity change, making @@ -217,11 +244,11 @@ Define the Maildir Store \fIname\fR, opening a section for its parameters. .. .TP -\fBAltMap\fR \fIyes\fR|\fIno\fR +\fBAltMap\fR \fByes\fR|\fBno\fR Use the \fBalternative\fR UID storage scheme for mailboxes in this Store. This does not affect mailboxes that do already have a UID storage scheme; use \fBmdconvert\fR to change it. -(Default: \fIno\fR) +(Default: \fBno\fR) .. .TP \fBInbox\fR \fIpath\fR @@ -229,6 +256,34 @@ but it is allowed to place the \fBINBOX\fR inside the \fBPath\fR. (Default: \fI~/Maildir\fR) .. +.TP +\fBInfoDelimiter\fR \fIdelim\fR +The character used to delimit the info field from a message's basename. +The Maildir standard defines this to be the colon, but this is incompatible +with DOS/Windows file systems. +(Default: the value of \fBFieldDelimiter\fR) +.. +.TP +\fBSubFolders\fR \fBVerbatim\fR|\fBMaildir++\fR|\fBLegacy\fR +The on-disk folder naming style used for hierarchical mailboxes. +This has option has no effect when \fBFlatten\fR is used. +.br +Suppose mailboxes with the canonical paths \fBtop/sub/subsub\fR and +\fBINBOX/sub/subsub\fR, the styles will yield the following on-disk paths: +.br +\fBVerbatim\fR - \fIPath\fB/top/sub/subsub\fR and \fIInbox\fB/sub/subsub\fR +(this is the style you probably want to use) +.br +\fBMaildir++\fR - \fIInbox\fB/.top.sub.subsub\fR and \fIInbox\fB/..sub.subsub\fR +(this style is compatible with Courier and Dovecot - but note that +the mailbox metadata format is \fInot\fR compatible). +Note that attempts to set \fBPath\fR are rejected in this mode. +.br +\fBLegacy\fR - \fIPath\fB/top/.sub/.subsub\fR and \fIInbox\fB/.sub/.subsub\fR +(this is \fBmbsync\fR's historical style) +.br +(Default: unset; will error out when sub-folders are encountered) +.. .SS IMAP4 Accounts .TP \fBIMAPAccount\fR \fIname\fR @@ -237,55 +292,88 @@ .TP \fBHost\fR \fIhost\fR Specify the DNS name or IP address of the IMAP server. +.br +If \fBTunnel\fR is used, this setting is needed only if \fBSSLType\fR is +not \fBNone\fR and \fBCertificateFile\fR is not used, +in which case the host name is used for certificate subject verification. .. .TP \fBPort\fR \fIport\fR Specify the TCP port number of the IMAP server. (Default: 143 for IMAP, 993 for IMAPS) +.br +If \fBTunnel\fR is used, this setting is ignored. +.. +.TP +\fBTimeout\fR \fItimeout\fR +Specify the connect and data timeout for the IMAP server in seconds. +Zero means unlimited. +(Default: \fI20\fR) .. .TP \fBUser\fR \fIusername\fR -Specify the login name on the IMAP server. (Default: current local user) +Specify the login name on the IMAP server. .. .TP \fBPass\fR \fIpassword\fR Specify the password for \fIusername\fR on the IMAP server. -Note that this option is \fBNOT\fR required. +Note that this option is \fInot\fR required. If neither a password nor a password command is specified in the configuration file, \fBmbsync\fR will prompt you for a password. .. .TP -\fBPassCmd\fR \fIcommand\fR +\fBPassCmd\fR [\fB+\fR]\fIcommand\fR Specify a shell command to obtain a password rather than specifying a password directly. This allows you to use password files and agents. The command must produce exactly one line on stdout; the trailing newline is optional. +Prepend \fB+\fR to the command to indicate that it produces TTY output +(e.g., a decryption password prompt); failure to do so will merely produce +messier output. .. .TP \fBTunnel\fR \fIcommand\fR Specify a command to run to establish a connection rather than opening a TCP socket. This allows you to run an IMAP session over an SSH tunnel, for example. -\fBHost\fR and \fBPort\fR are ignored when \fBTunnel\fR is set. .. .TP -\fBRequireCRAM\fR \fIyes\fR|\fIno\fR -If set to \fIyes\fR, \fBmbsync\fR will abort the connection if no CRAM-MD5 -authentication is possible. (Default: \fIno\fR) -.. -.TP -\fBUseIMAPS\fR \fIyes\fR|\fIno\fR -If set to \fIyes\fR, the default for \fBPort\fR is changed to 993 and -\fBmbsync\fR will start SSL negotiation immediately after establishing -the connection to the server. -.br -Note that modern servers support SSL on the regular IMAP port 143 via the -STARTTLS extension, which will be used automatically by default. -.. -.TP -\fBRequireSSL\fR \fIyes\fR|\fIno\fR -\fBmbsync\fR will abort the connection if a TLS/SSL session cannot be -established with the IMAP server. (Default: \fIyes\fR) +\fBAuthMechs\fR \fItype\fR ... +The list of acceptable authentication mechanisms. +In addition to the mechanisms listed in the SASL registry (link below), +the legacy IMAP \fBLOGIN\fR mechanism is known. +The wildcard \fB*\fR represents all mechanisms that are deemed secure +enough for the current \fBSSLType\fR setting. +The actually used mechanism is the most secure choice from the intersection +of this list, the list supplied by the server, and the installed SASL modules. +(Default: \fB*\fR) +.. +.TP +\fBSSLType\fR {\fBNone\fR|\fBSTARTTLS\fR|\fBIMAPS\fR} +Select the connection security/encryption method: +.br +\fBNone\fR - no security. +This is the default when \fBTunnel\fR is set, as tunnels are usually secure. +.br +\fBSTARTTLS\fR - security is established via the STARTTLS extension +after connecting the regular IMAP port 143. Most servers support this, +so it is the default (unless a tunnel is used). +.br +\fBIMAPS\fR - security is established by starting SSL/TLS negotiation +right after connecting the secure IMAP port 993. +.. +.TP +\fBSSLVersions\fR [\fBSSLv2\fR] [\fBSSLv3\fR] [\fBTLSv1\fR] [\fBTLSv1.1\fR] [\fBTLSv1.2\fR] +Select the acceptable SSL/TLS versions. +Use of SSLv2 is strongly discouraged for security reasons, but might be the +only option on some very old servers. +Generally, the newest TLS version is recommended, but as this confuses some +servers, \fBTLSv1\fR is the default. +.. +.TP +\fBSystemCertificates\fR \fByes\fR|\fBno\fR +Whether the system's default root cerificate store should be loaded. +(Default: \fByes\fR) .. .TP \fBCertificateFile\fR \fIpath\fR @@ -293,43 +381,38 @@ identities. Directly matched peer certificates are always trusted, regardless of validity. .br -Note that the system's default certificate store is always used and should -not be specified here. +Note that the system's default certificate store is always used +(unless \fBSystemCertificates\fR is disabled) +and should not be specified here. .. .TP -\fBUseSSLv2\fR \fIyes\fR|\fIno\fR -Use SSLv2 for communication with the IMAP server over SSL? +\fBClientCertificate\fR \fIpath\fR +File containing a client certificate to send to the server. +\fBClientKey\fR should also be specified. .br -Note that this option is deprecated for security reasons. -(Default: \fIno\fR) -.. -.TP -\fBUseSSLv3\fR \fIyes\fR|\fIno\fR -Use SSLv3 for communication with the IMAP server over SSL? -(Default: \fIno\fR) -.. -.TP -\fBUseTLSv1\fR \fIyes\fR|\fIno\fR -Use TLSv1 for communication with the IMAP server over SSL? -(Default: \fIyes\fR) -.. -.TP -\fBUseTLSv1.1\fR \fIyes\fR|\fIno\fR -Use TLSv1.1 for communication with the IMAP server over SSL? -(Default: \fIno\fR) +Note that client certificate verification is usually not required, +so it is unlikely that you need this option. .. .TP -\fBUseTLSv1.2\fR \fIyes\fR|\fIno\fR -Use TLSv1.2 for communication with the IMAP server over SSL? -(Default: \fIno\fR) +\fBClientKey\fR \fIpath\fR +File containing the private key corresponding to \fBClientCertificate\fR. .. .TP \fBPipelineDepth\fR \fIdepth\fR Maximum number of IMAP commands which can be simultaneously in flight. Setting this to \fI1\fR disables pipelining. -This is mostly a debugging only option. +This is mostly a debugging option, but may also be used to limit average +bandwidth consumption (GMail may require this if you have a very fast +connection), or to spare flaky servers like M$ Exchange. (Default: \fIunlimited\fR) .. +.TP +\fBDisableExtension\fR[\fBs\fR] \fIextension\fR ... +Disable the use of specific IMAP extensions. +This can be used to work around bugs in servers +(and possibly \fBmbsync\fR itself). +(Default: empty) +.. .SS IMAP Stores The reference point for relative \fBPath\fRs is whatever the server likes it to be; probably the user's $HOME or $HOME/Mail on that server. The location @@ -346,18 +429,18 @@ one Store only anyway. .. .TP -\fBUseNamespace\fR \fIyes\fR|\fIno\fR +\fBUseNamespace\fR \fByes\fR|\fBno\fR Selects whether the server's first "personal" NAMESPACE should be prefixed to mailbox names. Disabling this makes sense for some broken IMAP servers. This option is meaningless if a \fBPath\fR was specified. -(Default: \fIyes\fR) +(Default: \fByes\fR) .. .TP \fBPathDelimiter\fR \fIdelim\fR Specify the server's hierarchy delimiter. (Default: taken from the server's first "personal" NAMESPACE) .br -Do \fBNOT\fR abuse this to re-interpret the hierarchy. +Do \fInot\fR abuse this to re-interpret the hierarchy. Use \fBFlatten\fR instead. .. .SS Channels @@ -410,17 +493,17 @@ (Default: \fI0\fR). .. .TP -\fBExpireUnread\fR \fIyes\fR|\fIno\fR +\fBExpireUnread\fR \fByes\fR|\fBno\fR Selects whether unread messages should be affected by \fBMaxMessages\fR. Normally, unread messages are considered important and thus never expired. This ensures that you never miss new messages even after an extended absence. However, if your archive contains large amounts of unread messages by design, treating them as important would practically defeat \fBMaxMessages\fR. In this case you need to enable this option. -(Default: \fIno\fR). +(Default: \fBno\fR). .. .TP -\fBSync\fR {\fINone\fR|[\fIPull\fR] [\fIPush\fR] [\fINew\fR] [\fIReNew\fR] [\fIDelete\fR] [\fIFlags\fR]|\fIAll\fR} +\fBSync\fR {\fBNone\fR|[\fBPull\fR] [\fBPush\fR] [\fBNew\fR] [\fBReNew\fR] [\fBDelete\fR] [\fBFlags\fR]|\fBAll\fR} Select the synchronization operation(s) to perform: .br \fBPull\fR - propagate changes from Master to Slave. @@ -439,7 +522,7 @@ that Store is expunged. .br \fBFlags\fR - propagate flag changes. Note that Deleted/Trashed is a flag as -well; this is particularily interesting if you use \fBmutt\fR with the +well; this is particularly interesting if you use \fBmutt\fR with the maildir_trash option. .br \fBAll\fR (\fB--full\fR on the command line) - all of the above. @@ -475,30 +558,43 @@ "\fBSync\fR\ \fBPullNew\fR\ \fBDelete\fR\ \fBPush\fR" induce error messages. .. .TP -\fBCreate\fR {\fINone\fR|\fIMaster\fR|\fISlave\fR|\fIBoth\fR} +\fBCreate\fR {\fBNone\fR|\fBMaster\fR|\fBSlave\fR|\fBBoth\fR} Automatically create missing mailboxes [on the Master/Slave]. Otherwise print an error message and skip that mailbox pair if a mailbox -does not exist. -(Global default: \fINone\fR) +and the corresponding sync state does not exist. +(Global default: \fBNone\fR) .. .TP -\fBExpunge\fR {\fINone\fR|\fIMaster\fR|\fISlave\fR|\fIBoth\fR} +\fBRemove\fR {\fBNone\fR|\fBMaster\fR|\fBSlave\fR|\fBBoth\fR} +Propagate mailbox deletions [to the Master/Slave]. +Otherwise print an error message and skip that mailbox pair if a mailbox +does not exist but the corresponding sync state does. +.br +For MailDir mailboxes it is sufficient to delete the cur/ subdirectory to +mark them as deleted. This ensures compatibility with \fBSyncState *\fR. +.br +Note that for safety, non-empty mailboxes are never deleted. +.br +(Global default: \fBNone\fR) +.. +.TP +\fBExpunge\fR {\fBNone\fR|\fBMaster\fR|\fBSlave\fR|\fBBoth\fR} Permanently remove all messages [on the Master/Slave] marked for deletion. See \fBRECOMMENDATIONS\fR below. -(Global default: \fINone\fR) +(Global default: \fBNone\fR) .. .TP -\fBCopyArrivalDate\fR {\fIyes\fR|\fIno\fR} +\fBCopyArrivalDate\fR {\fByes\fR|\fBno\fR} Selects whether their arrival time should be propagated together with the messages. Enabling this makes sense in order to keep the time stamp based message sorting intact. Note that IMAP does not guarantee that the time stamp (termed \fBinternal date\fR) is actually the arrival time, but it is usually close enough. -(Default: \fIno\fR) +(Default: \fBno\fR) .. .P -\fBSync\fR, \fBCreate\fR, \fBExpunge\fR, +\fBSync\fR, \fBCreate\fR, \fBRemove\fR, \fBExpunge\fR, \fBMaxMessages\fR, and \fBCopyArrivalDate\fR can be used before any section for a global effect. The global settings are overridden by Channel-specific options, @@ -515,7 +611,8 @@ .br This option can be used outside any section for a global effect. In this case the appended string is made up according to the pattern -\fB:\fImaster\fB:\fImaster-box\fB_:\fIslave\fB:\fIslave-box\fR. +\fB:\fImaster\fB:\fImaster-box\fB_:\fIslave\fB:\fIslave-box\fR +(see also \fBFieldDelimiter\fR below). .br (Global default: \fI~/.mbsync/\fR). .. @@ -540,7 +637,7 @@ .. .SS Global Options .TP -\fBFSync\fR \fIyes\fR|\fIno\fR +\fBFSync\fR \fByes\fR|\fBno\fR .br Selects whether \fBmbsync\fR performs forced flushing, which determines the level of data safety after system crashes and power outages. @@ -549,7 +646,40 @@ Enabling it is a wise choice for file systems mounted with data=writeback, in particular modern systems like ext4, btrfs and xfs. The performance impact on older file systems may be disproportionate. -(Default: \fIyes\fR) +(Default: \fByes\fR) +.. +.TP +\fBFieldDelimiter\fR \fIdelim\fR +The character to use to delimit fields in the string appended to a global +\fBSyncState\fR. +\fBmbsync\fR prefers to use the colon, but this is incompatible with +DOS/Windows file systems. +This option is meaningless for \fBSyncState\fR if the latter is \fB*\fR, +obviously. However, it also determines the default of \fBInfoDelimiter\fR. +(Global default: \fI;\fR on Windows, \fI:\fR everywhere else) +.. +.TP +\fBBufferLimit\fR \fIsize\fR[\fBk\fR|\fBm\fR][\fBb\fR] +The per-Channel, per-direction instantaneous memory usage above which +\fBmbsync\fR will refrain from using more memory. Note that this is no +absolute limit, as even a single message can consume more memory than +this. +(Default: \fI10M\fR) +.. +.SH CONSOLE OUTPUT +If \fBmbsync\fR's output is connected to a console, it will print progress +counters by default. The output will look like this: +.P +.in +4 +C: 1/2 B: 3/4 M: +13/13 *23/42 #0/0 S: +0/7 *0/0 #0/0 +.in -4 +.P +This represents the cumulative progress over channels, boxes, and messages +affected on master and slave, respectively. +The message counts represent added messages, messages with updated flags, +and trashed messages, respectively. +No attempt is made to calculate the totals in advance, so they grow over +time as more information is gathered. .. .SH RECOMMENDATIONS Make sure your IMAP server does not auto-expunge deleted messages - it is @@ -578,6 +708,9 @@ good idea to rely on that instead of \fBmbsync\fR's trash functionality. If you do that, and intend to synchronize the trash like other mailboxes, you should not use \fBmbsync\fR's \fBTrash\fR option at all. +.P +Use of the \fBTrash\fR option with M$ Exchange 2013 requires the use of +\fBDisableExtension MOVE\fR due to a server bug. .. .SH INHERENT PROBLEMS Changes done after \fBmbsync\fR has retrieved the message list will not be @@ -602,6 +735,9 @@ mdconvert(1), isync(1), mutt(1), maildir(5) .P Up to date information on \fBmbsync\fR can be found at http://isync.sf.net/ +.P +SASL mechanisms are listed at +http://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml .. .SH AUTHORS Originally written by Michael R. Elkins, diff -Nru isync-1.1.0/src/mbsyncrc.sample isync-1.2.1-1.812.20170514/src/mbsyncrc.sample --- isync-1.1.0/src/mbsyncrc.sample 2013-12-15 12:46:25.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/mbsyncrc.sample 2017-05-26 14:36:31.000000000 +0000 @@ -16,17 +16,16 @@ # Fetch password from gnome-keyring: #PassCmd "gnome-keyring-query get mail_pw" # Fetch password from .netrc: -#PassCmd "sed -n -e 's,^machine work\.host\.com login tehuser password \(.*\),\1,p' < $HOME/.netrc" +#PassCmd "sed -n -e 's,^machine work\\.host\\.com login tehuser password \\(.*\\),\\1,p' < $HOME/.netrc" # Fetch password from a gpg-encrypted file: #PassCmd "gpg --quiet --for-your-eyes-only --decrypt $HOME/imappassword.gpg" # Fetch password from pwmd (http://pwmd.sourceforge.net/): -#PassCmd "echo -ne 'GET myIsp\tpassword' | pwmc datafile" +#PassCmd "echo -ne 'GET myIsp\\tpassword' | pwmc datafile" # On Mac OS X, run "KeyChain Access" -- File->New Password Item. Fill out form using # "Keychain Item Name" http://IMAPSERVER (note: the "http://" is a hack) # "Account Name" USERNAME # "Password" PASSWORD #PassCmd "/usr/bin/security find-internet-password -w -a USERNAME -s IMAPSERVER ~/Library/Keychains/login.keychain" -CertificateFile /etc/ssl/certs/ca-certificates.crt Channel work Master :work: @@ -87,6 +86,7 @@ MaildirStore mirror Path ~/Maildir/ +SubFolders Verbatim Channel o2o Master :server: diff -Nru isync-1.1.0/src/mdconvert.c isync-1.2.1-1.812.20170514/src/mdconvert.c --- isync-1.1.0/src/mdconvert.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/mdconvert.c 2017-05-26 14:36:31.000000000 +0000 @@ -135,7 +135,7 @@ key.data = (void *)"UIDVALIDITY"; key.size = 11; if (altmap) { - if ((n = read( sfd, buf, sizeof(buf) )) <= 0 || + if ((n = read( sfd, buf, sizeof(buf) - 1 )) <= 0 || (buf[n] = 0, sscanf( buf, "%d\n%d", &uv[0], &uv[1] ) != 2)) { fprintf( stderr, "Error: cannot read UIDVALIDITY of '%s'.\n", box ); @@ -208,8 +208,10 @@ nfsnprintf( buf2 + bl, sizeof(buf2) - bl, "%.*s,U=%d%s", ml, e->d_name, uid, ru ); } if (rename( buf, buf2 )) { - if (errno == ENOENT) + if (errno == ENOENT) { + closedir( d ); goto again; + } sys_error( "Cannot rename %s to %s", buf, buf2 ); ebork: closedir( d ); @@ -224,6 +226,7 @@ close( dfd ); if (rename( tdpath, dpath )) { sys_error( "Cannot rename %s to %s", tdpath, dpath ); + close( sfd ); return 1; } if (unlink( spath )) diff -Nru isync-1.1.0/src/run-tests.pl isync-1.2.1-1.812.20170514/src/run-tests.pl --- isync-1.1.0/src/run-tests.pl 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/run-tests.pl 2017-05-26 14:36:31.000000000 +0000 @@ -16,9 +16,14 @@ # along with this program. If not, see . # +use warnings; use strict; +use Cwd; use File::Path; +my $use_vg = $ENV{USE_VALGRIND}; +my $mbsync = getcwd()."/mbsync"; + -d "tmp" or mkdir "tmp"; chdir "tmp" or die "Cannot enter temp direcory.\n"; @@ -27,12 +32,16 @@ ################################################################################ +# Format of the test defs: [ master, slave, state ] +# master/slave: [ maxuid, { seq, uid, flags }... ] +# state: [ MaxPulledUid, MaxExpiredMasterUid, MaxPushedUid, { muid, suid, flags }... ] + # generic syncing tests my @x01 = ( - [ 8, - 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 0, "" ], - [ 8, - 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "", 10, 0, "" ], + [ 9, + 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 9, "" ], + [ 9, + 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "", 10, 9, "" ], [ 8, 0, 0, 1, 1, "", 2, 2, "", 3, 3, "", 4, 4, "", 5, 5, "", 6, 6, "", 7, 7, "", 8, 8, "" ], ); @@ -78,20 +87,20 @@ my @X04 = ( [ 9, 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 9, "" ], - [ 9, - 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 7, 7, "FT", 8, 8, "T", 9, 9, "", 10, 0, "" ], + [ 10, + 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 7, 7, "FT", 8, 8, "T", 9, 10, "", 10, 9, "" ], [ 9, 0, 0, - 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "", 7, 7, "FT", 0, 8, "", 9, 9, "" ], + 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "", 7, 7, "FT", 0, 8, "", 9, 10, "" ], ); test("pull", \@x01, \@X04, @O04); my @O05 = ("", "", "Sync Flags\n"); #show("01", "05", "05"); my @X05 = ( - [ 8, - 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 0, "" ], - [ 8, - 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 7, 7, "FT", 8, 8, "", 10, 0, "" ], + [ 9, + 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 9, "" ], + [ 9, + 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 7, 7, "FT", 8, 8, "", 10, 9, "" ], [ 8, 0, 0, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "", 7, 7, "FT", 8, 8, "" ], ); @@ -100,10 +109,10 @@ my @O06 = ("", "", "Sync Delete\n"); #show("01", "06", "06"); my @X06 = ( - [ 8, - 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "FT", 7, 7, "FT", 9, 0, "" ], - [ 8, - 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "T", 10, 0, "" ], + [ 9, + 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "FT", 7, 7, "FT", 9, 9, "" ], + [ 9, + 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "T", 10, 9, "" ], [ 8, 0, 0, 1, 1, "", 2, 2, "", 3, 3, "", 4, 4, "", 5, 5, "", 6, 0, "", 7, 7, "", 0, 8, "" ], ); @@ -124,10 +133,10 @@ my @O08 = ("", "", "Sync PushFlags PullDelete\n"); #show("01", "08", "08"); my @X08 = ( - [ 8, - 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 0, "" ], - [ 8, - 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "T", 10, 0, "" ], + [ 9, + 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 9, "" ], + [ 9, + 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "T", 10, 9, "" ], [ 8, 0, 0, 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 6, 6, "", 7, 7, "", 0, 8, "" ], ); @@ -136,10 +145,10 @@ # size restriction tests my @x10 = ( - [ 0, - 1, 0, "", 2, 0, "*" ], - [ 0, - 3, 0, "*" ], + [ 2, + 1, 1, "", 2, 2, "*" ], + [ 1, + 3, 1, "*" ], [ 0, 0, 0, ], ); @@ -152,7 +161,7 @@ [ 2, 3, 1, "*", 1, 2, "" ], [ 2, 0, 1, - -1, 1, "", 1, 2, "", 2, -1, "" ], + 0, 1, "^", 1, 2, "", 2, 0, "^" ], ); test("max size", \@x10, \@X11, @O11); @@ -164,15 +173,15 @@ [ 2, 3, 1, "*", 1, 2, "" ], [ 2, 0, 1, - 3, 1, "", 1, 2, "", 2, -1, "" ], + 3, 1, "", 1, 2, "", 2, 0, "^" ], ); test("slave max size", \@X11, \@X22, @O22); # expiration tests my @x30 = ( - [ 0, - 1, 0, "F", 2, 0, "", 3, 0, "S", 4, 0, "", 5, 0, "S", 6, 0, "" ], + [ 6, + 1, 1, "F", 2, 2, "", 3, 3, "S", 4, 4, "", 5, 5, "S", 6, 6, "" ], [ 0, ], [ 0, 0, 0, @@ -186,7 +195,7 @@ 1, 1, "F", 2, 2, "", 3, 3, "S", 4, 4, "", 5, 5, "S", 6, 6, "" ], [ 5, 1, 1, "F", 2, 2, "", 4, 3, "", 5, 4, "S", 6, 5, "" ], - [ 6, 2, 0, + [ 6, 3, 0, 1, 1, "F", 2, 2, "", 4, 3, "", 5, 4, "S", 6, 5, "" ], ); test("max messages", \@x30, \@X31, @O31); @@ -198,7 +207,7 @@ 1, 1, "F", 2, 2, "", 3, 3, "S", 4, 4, "", 5, 5, "S", 6, 6, "" ], [ 4, 1, 1, "F", 4, 2, "", 5, 3, "S", 6, 4, "" ], - [ 6, 1, 0, + [ 6, 3, 0, 1, 1, "F", 4, 2, "", 5, 3, "S", 6, 4, "" ], ); test("max messages vs. unread", \@x30, \@X32, @O32); @@ -209,7 +218,7 @@ [ 6, 1, 1, "S", 2, 2, "ST", 4, 4, "", 5, 5, "", 6, 6, "" ], [ 6, 3, 0, - 1, 1, "FS", 2, 2, "XS", 3, 3, "XS", 4, 4, "", 5, 5, "", 6, 6, "" ], + 1, 1, "FS", 2, 2, "~S", 3, 3, "~S", 4, 4, "", 5, 5, "", 6, 6, "" ], ); my @O51 = ("", "", "MaxMessages 3\nExpunge Both\n"); @@ -222,7 +231,7 @@ [ 6, 3, 0, 2, 2, "FS", 4, 4, "", 5, 5, "", 6, 6, "" ], ); -test("max messages + expire", \@x50, \@X51, @O51); +test("max messages + expunge", \@x50, \@X51, @O51); ################################################################################ @@ -269,16 +278,30 @@ sub killcfg() { + unlink $_ for (glob("*.log")); unlink ".mbsyncrc"; } # $options -sub runsync($) +sub runsync($$) { -# open FILE, "valgrind -q --log-fd=3 ../mbsync ".shift()." -c .mbsyncrc test 3>&2 2>&1 |"; - open FILE, "../mbsync -D -Z ".shift()." -c .mbsyncrc test 2>&1 |"; + my ($flags, $file) = @_; + + my $cmd; + if ($use_vg) { + $cmd = "valgrind -q --error-exitcode=1 "; + } else { + $flags .= " -D"; + } + $cmd .= "$mbsync -Z $flags -c .mbsyncrc test"; + open FILE, "$cmd 2>&1 |"; my @out = ; close FILE or push(@out, $! ? "*** error closing mbsync: $!\n" : "*** mbsync exited with signal ".($?&127).", code ".($?>>8)."\n"); + if ($file) { + open FILE, ">$file" or die("Cannot create $file: $!\n"); + print FILE @out; + close FILE; + } return $?, @out; } @@ -335,22 +358,16 @@ my ($bn) = @_; my ($mu, %ms) = readbox($bn); - print " [ $mu,\n "; - my $frst = 1; + my @MS = ($mu); for my $num (sort { $a <=> $b } keys %ms) { - if ($frst) { - $frst = 0; - } else { - print ", "; - } - print "$num, $ms{$num}[0], \"$ms{$num}[1]\""; + push @MS, $num, $ms{$num}[0], $ms{$num}[1]; } - print " ],\n"; + printbox($bn, @MS); } # $filename # Output: -# [ maxuid[M], smaxxuid, maxuid[S], +# [ maxuid[M], mmaxxuid, maxuid[S], # uid[M], uid[S], "flags", ... ], sub showstate($) { @@ -378,22 +395,14 @@ close FILE; return; } - print " [ ".($hdr{'MaxPulledUid'} // "missing").", ". - ($hdr{'MaxExpiredSlaveUid'} // "0").", ".($hdr{'MaxPushedUid'} // "missing").",\n "; - my $frst = 1; + my @T = ($hdr{'MaxPulledUid'} // "missing", + $hdr{'MaxExpiredMasterUid'} // "0", + $hdr{'MaxPushedUid'} // "missing"); for (@ls) { - if ($frst) { - $frst = 0; - } else { - print ", "; - } - if (!/^(-?\d+) (-?\d+) (.*)$/) { - print "??, ??, \"??\""; - } else { - print "$1, $2, \"$3\""; - } + /^(\d+) (\d+) (.*)$/; + push @T, $1, $2, $3; } - print " ],\n"; + printstate(@T); } # $filename @@ -418,7 +427,7 @@ showchan("slave/.mbsyncstate"); print ");\n"; &writecfg(@sfx); - runsync(""); + runsync("", ""); killcfg(); print "my \@X$tx = (\n"; showchan("slave/.mbsyncstate"); @@ -463,7 +472,7 @@ open(FILE, ">", "slave/.mbsyncstate") or die "Cannot create sync state.\n"; print FILE "MasterUidValidity 1\nMaxPulledUid ".shift(@t)."\n". - "SlaveUidValidity 1\nMaxExpiredSlaveUid ".shift(@t)."\nMaxPushedUid ".shift(@t)."\n\n"; + "SlaveUidValidity 1\nMaxExpiredMasterUid ".shift(@t)."\nMaxPushedUid ".shift(@t)."\n\n"; while (@t) { print FILE shift(@t)." ".shift(@t)." ".shift(@t)."\n"; } @@ -506,13 +515,13 @@ # $filename, @syncstate sub ckstate($@) { - my ($fn, $mmaxuid, $smaxxuid, $smaxuid, @T) = @_; + my ($fn, $mmaxuid, $mmaxxuid, $smaxuid, @T) = @_; my %hdr; $hdr{'MasterUidValidity'} = "1"; $hdr{'SlaveUidValidity'} = "1"; $hdr{'MaxPulledUid'} = $mmaxuid; $hdr{'MaxPushedUid'} = $smaxuid; - $hdr{'MaxExpiredSlaveUid'} = $smaxxuid if ($smaxxuid ne 0); + $hdr{'MaxExpiredMasterUid'} = $mmaxxuid if ($mmaxxuid ne 0); open(FILE, "<", $fn) or die "Cannot read sync state $fn.\n"; chomp(my @ls = ); close FILE; @@ -600,10 +609,9 @@ } else { print ", "; } - print shift(@t).", ".shift(@t).", \"".shift(@t)."\""; + print((shift(@t) // "??").", ".(shift(@t) // "??").", \"".(shift(@t) // "??")."\""); } print " ],\n"; - close FILE; } # \@chan_state @@ -616,6 +624,16 @@ printstate(@{ $$cs[2] }); } +sub readfile($) +{ + my ($file) = @_; + + open(FILE, $file) or return; + my @nj = ; + close FILE; + return @nj; +} + # $title, \@source_state, \@target_state, @channel_configs sub test($$$@) { @@ -623,91 +641,102 @@ return 0 if (scalar(@ARGV) && !grep { $_ eq $ttl } @ARGV); print "Testing: ".$ttl." ...\n"; - mkchan($$sx[0], $$sx[1], @{ $$sx[2] }); &writecfg(@sfx); - my ($xc, @ret) = runsync("-J"); - if ($xc) { - print "Input:\n"; - printchan($sx); - print "Options:\n"; - print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; - print "Expected result:\n"; - printchan($tx); - print "Debug output:\n"; - print @ret; - exit 1; - } - if (ckchan("slave/.mbsyncstate.new", $tx)) { + mkchan($$sx[0], $$sx[1], @{ $$sx[2] }); + + my ($xc, @ret) = runsync("-J", "1-initial.log"); + if ($xc || ckchan("slave/.mbsyncstate.new", $tx)) { print "Input:\n"; printchan($sx); print "Options:\n"; print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; - print "Expected result:\n"; - printchan($tx); - print "Actual result:\n"; - showchan("slave/.mbsyncstate.new"); + if (!$xc) { + print "Expected result:\n"; + printchan($tx); + print "Actual result:\n"; + showchan("slave/.mbsyncstate.new"); + } print "Debug output:\n"; print @ret; exit 1; } - open(FILE, "<", "slave/.mbsyncstate.journal") or - die "Cannot read journal.\n"; - my @nj = ; - close FILE; - ($xc, @ret) = runsync("-0 --no-expunge"); - if ($xc) { + my @nj = readfile("slave/.mbsyncstate.journal"); + my ($jxc, @jret) = runsync("-0 --no-expunge", "2-replay.log"); + if ($jxc || ckstate("slave/.mbsyncstate", @{ $$tx[2] })) { print "Journal replay failed.\n"; - print "Input == Expected result:\n"; - printchan($tx); print "Options:\n"; print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ], [ \"-0\", \"--no-expunge\" ]\n"; - print "Debug output:\n"; - print @ret; - exit 1; - } - if (ckstate("slave/.mbsyncstate", @{ $$tx[2] })) { - print "Journal replay failed.\n"; - print "Options:\n"; - print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; print "Old State:\n"; printstate(@{ $$sx[2] }); print "Journal:\n".join("", @nj)."\n"; - print "Expected New State:\n"; - printstate(@{ $$tx[2] }); - print "New State:\n"; - showstate("slave/.mbsyncstate"); + if (!$jxc) { + print "Expected New State:\n"; + printstate(@{ $$tx[2] }); + print "New State:\n"; + showstate("slave/.mbsyncstate"); + } print "Debug output:\n"; - print @ret; + print @jret; exit 1; } - ($xc, @ret) = runsync(""); - if ($xc) { - print "Idempotence verification run failed.\n"; - print "Input == Expected result:\n"; - printchan($tx); - print "Options:\n"; - print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; - print "Debug output:\n"; - print @ret; - exit 1; - } - if (ckchan("slave/.mbsyncstate", $tx)) { + my ($ixc, @iret) = runsync("", "3-verify.log"); + if ($ixc || ckchan("slave/.mbsyncstate", $tx)) { print "Idempotence verification run failed.\n"; print "Input == Expected result:\n"; printchan($tx); print "Options:\n"; print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; - print "Actual result:\n"; - showchan("slave/.mbsyncstate"); + if (!$ixc) { + print "Actual result:\n"; + showchan("slave/.mbsyncstate"); + } print "Debug output:\n"; - print @ret; + print @iret; exit 1; } - killcfg(); rmtree "slave"; rmtree "master"; + + my $njl = (@nj - 1) * 2; + for (my $l = 2; $l < $njl; $l++) { + mkchan($$sx[0], $$sx[1], @{ $$sx[2] }); + + my ($nxc, @nret) = runsync("-J$l", "4-interrupt.log"); + if ($nxc != (100 + ($l & 1)) << 8) { + print "Interrupting at step $l/$njl failed.\n"; + print "Debug output:\n"; + print @nret; + exit 1; + } + + ($nxc, @nret) = runsync("-J", "5-resume.log"); + if ($nxc || ckchan("slave/.mbsyncstate.new", $tx)) { + print "Resuming from step $l/$njl failed.\n"; + print "Input:\n"; + printchan($sx); + print "Options:\n"; + print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; + my @nnj = readfile("slave/.mbsyncstate.journal"); + print "Journal:\n".join("", @nnj[0..($l / 2 - 1)])."-------\n".join("", @nnj[($l / 2)..$#nnj])."\n"; + print "Full journal:\n".join("", @nj)."\n"; + if (!$nxc) { + print "Expected result:\n"; + printchan($tx); + print "Actual result:\n"; + showchan("slave/.mbsyncstate"); + } + print "Debug output:\n"; + print @nret; + exit 1; + } + + rmtree "slave"; + rmtree "master"; + } + + killcfg(); } diff -Nru isync-1.1.0/src/socket.c isync-1.2.1-1.812.20170514/src/socket.c --- isync-1.1.0/src/socket.c 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/socket.c 2017-05-26 14:36:31.000000000 +0000 @@ -39,8 +39,11 @@ #ifdef HAVE_LIBSSL # include # include -# include # include +# if OPENSSL_VERSION_NUMBER < 0x10100000L +# define X509_OBJECT_get0_X509(o) ((o)->data.x509) +# define X509_STORE_get0_objects(o) ((o)->objs) +# endif #endif enum { @@ -48,7 +51,8 @@ #ifdef HAVE_LIBSSL SCK_STARTTLS, #endif - SCK_READY + SCK_READY, + SCK_EOF }; static void @@ -58,8 +62,6 @@ } #ifdef HAVE_LIBSSL -static int ssl_data_idx; - static int ssl_return( const char *func, conn_t *conn, int ret ) { @@ -69,17 +71,21 @@ case SSL_ERROR_NONE: return ret; case SSL_ERROR_WANT_WRITE: - conf_fd( conn->fd, POLLIN, POLLOUT ); + conf_notifier( &conn->notify, POLLIN, POLLOUT ); /* fallthrough */ case SSL_ERROR_WANT_READ: return 0; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: if (!(err = ERR_get_error())) { - if (ret == 0) - error( "Socket error: secure %s %s: unexpected EOF\n", func, conn->name ); - else - sys_error( "Socket error: secure %s %s", func, conn->name ); + if (ret == 0) { + case SSL_ERROR_ZERO_RETURN: + /* Callers take the short path out, so signal higher layers from here. */ + conn->state = SCK_EOF; + conn->read_callback( conn->callback_aux ); + return -1; + } + sys_error( "Socket error: secure %s %s", func, conn->name ); } else { error( "Socket error: secure %s %s: %s\n", func, conn->name, ERR_error_string( err, 0 ) ); } @@ -156,10 +162,10 @@ static int verify_cert_host( const server_conf_t *conf, conn_t *sock ) { + int i; + long err; X509 *cert; - - if (!conf->host || sock->force_trusted > 0) - return 0; + STACK_OF(X509_OBJECT) *trusted; cert = SSL_get_peer_certificate( sock->ssl ); if (!cert) { @@ -167,31 +173,24 @@ return -1; } - return verify_hostname( cert, conf->host ); -} + trusted = (STACK_OF(X509_OBJECT) *)sock->conf->trusted_certs; + for (i = 0; i < sk_X509_OBJECT_num( trusted ); i++) { + if (!X509_cmp( cert, X509_OBJECT_get0_X509( sk_X509_OBJECT_value( trusted, i ) ) )) + return 0; + } -static int -ssl_verify_callback( int ok, X509_STORE_CTX *ctx ) -{ - SSL *ssl = X509_STORE_CTX_get_ex_data( ctx, SSL_get_ex_data_X509_STORE_CTX_idx() ); - conn_t *conn = SSL_get_ex_data( ssl, ssl_data_idx ); + err = SSL_get_verify_result( sock->ssl ); + if (err != X509_V_OK) { + error( "SSL error connecting %s: %s\n", sock->name, X509_verify_cert_error_string( err ) ); + return -1; + } - if (!conn->force_trusted) { - X509 *cert = sk_X509_value( ctx->chain, 0 ); - STACK_OF(X509_OBJECT) *trusted = ctx->ctx->objs; - unsigned i; - - conn->force_trusted = -1; - for (i = 0; i < conn->conf->num_trusted; i++) { - if (!X509_cmp( cert, sk_X509_OBJECT_value( trusted, i )->data.x509 )) { - conn->force_trusted = 1; - break; - } - } + if (!conf->host) { + error( "SSL error connecting %s: Neither host nor matching certificate specified\n", sock->name ); + return -1; } - if (conn->force_trusted > 0) - ok = 1; - return ok; + + return verify_hostname( cert, conf->host ); } static int @@ -205,18 +204,18 @@ mconf->SSLContext = SSL_CTX_new( SSLv23_client_method() ); - if (!conf->use_sslv2) + if (!(conf->ssl_versions & SSLv2)) options |= SSL_OP_NO_SSLv2; - if (!conf->use_sslv3) + if (!(conf->ssl_versions & SSLv3)) options |= SSL_OP_NO_SSLv3; - if (!conf->use_tlsv1) + if (!(conf->ssl_versions & TLSv1)) options |= SSL_OP_NO_TLSv1; #ifdef SSL_OP_NO_TLSv1_1 - if (!conf->use_tlsv11) + if (!(conf->ssl_versions & TLSv1_1)) options |= SSL_OP_NO_TLSv1_1; #endif #ifdef SSL_OP_NO_TLSv1_2 - if (!conf->use_tlsv12) + if (!(conf->ssl_versions & TLSv1_2)) options |= SSL_OP_NO_TLSv1_2; #endif @@ -227,12 +226,23 @@ conf->cert_file, ERR_error_string( ERR_get_error(), 0 ) ); return 0; } - mconf->num_trusted = sk_X509_OBJECT_num( SSL_CTX_get_cert_store( mconf->SSLContext )->objs ); - if (!SSL_CTX_set_default_verify_paths( mconf->SSLContext )) + mconf->trusted_certs = (_STACK *)sk_X509_OBJECT_dup( X509_STORE_get0_objects( SSL_CTX_get_cert_store( mconf->SSLContext ) ) ); + if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( mconf->SSLContext )) warn( "Warning: Unable to load default certificate files: %s\n", ERR_error_string( ERR_get_error(), 0 ) ); - SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_PEER, ssl_verify_callback ); + SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, NULL ); + + if (conf->client_certfile && !SSL_CTX_use_certificate_chain_file( mconf->SSLContext, conf->client_certfile)) { + error( "Error while loading client certificate file '%s': %s\n", + conf->client_certfile, ERR_error_string( ERR_get_error(), 0 ) ); + return 0; + } + if (conf->client_keyfile && !SSL_CTX_use_PrivateKey_file( mconf->SSLContext, conf->client_keyfile, SSL_FILETYPE_PEM)) { + error( "Error while loading client private key '%s': %s\n", + conf->client_keyfile, ERR_error_string( ERR_get_error(), 0 ) ); + return 0; + } mconf->ssl_ctx_valid = 1; return 1; @@ -240,6 +250,7 @@ static void start_tls_p2( conn_t * ); static void start_tls_p3( conn_t *, int ); +static void ssl_fake_cb( void * ); void socket_start_tls( conn_t *conn, void (*cb)( int ok, void *aux ) ) @@ -251,7 +262,6 @@ if (!ssl_inited) { SSL_library_init(); SSL_load_error_strings(); - ssl_data_idx = SSL_get_ex_new_index( 0, NULL, NULL, NULL, NULL ); ssl_inited = 1; } @@ -260,10 +270,11 @@ return; } + init_wakeup( &conn->ssl_fake, ssl_fake_cb, conn ); conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext ); SSL_set_fd( conn->ssl, conn->fd ); SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER ); - SSL_set_ex_data( conn->ssl, ssl_data_idx, conn ); + socket_expect_read( conn, 1 ); conn->state = SCK_STARTTLS; start_tls_p2( conn ); } @@ -272,7 +283,6 @@ start_tls_p2( conn_t *conn ) { if (ssl_return( "connect to", conn, SSL_connect( conn->ssl ) ) > 0) { - /* verify whether the server hostname matches the certificate */ if (verify_cert_host( conn->conf, conn )) { start_tls_p3( conn, 0 ); } else { @@ -284,13 +294,53 @@ static void start_tls_p3( conn_t *conn, int ok ) { + socket_expect_read( conn, 0 ); conn->state = SCK_READY; conn->callbacks.starttls( ok, conn->callback_aux ); } #endif /* HAVE_LIBSSL */ +#ifdef HAVE_LIBZ + +static void z_fake_cb( void * ); + +void +socket_start_deflate( conn_t *conn ) +{ + int result; + + conn->in_z = nfcalloc( sizeof(*conn->in_z) ); + result = inflateInit2( + conn->in_z, + -15 /* Use raw deflate */ + ); + if (result != Z_OK) { + error( "Fatal: Cannot initialize decompression: %s\n", conn->in_z->msg ); + abort(); + } + + conn->out_z = nfcalloc( sizeof(*conn->out_z) ); + result = deflateInit2( + conn->out_z, + Z_DEFAULT_COMPRESSION, /* Compression level */ + Z_DEFLATED, /* Only valid value */ + -15, /* Use raw deflate */ + 8, /* Default memory usage */ + Z_DEFAULT_STRATEGY /* Don't try to do anything fancy */ + ); + if (result != Z_OK) { + error( "Fatal: Cannot initialize compression: %s\n", conn->out_z->msg ); + abort(); + } + + init_wakeup( &conn->z_fake, z_fake_cb, conn ); +} +#endif /* HAVE_LIBZ */ + static void socket_fd_cb( int, void * ); +static void socket_fake_cb( void * ); +static void socket_timeout_cb( void * ); static void socket_connect_one( conn_t * ); static void socket_connect_failed( conn_t * ); @@ -298,9 +348,21 @@ static void socket_connect_bail( conn_t * ); static void +socket_open_internal( conn_t *sock, int fd ) +{ + sock->fd = fd; + fcntl( fd, F_SETFL, O_NONBLOCK ); + init_notifier( &sock->notify, fd, socket_fd_cb, sock ); + init_wakeup( &sock->fd_fake, socket_fake_cb, sock ); + init_wakeup( &sock->fd_timeout, socket_timeout_cb, sock ); +} + +static void socket_close_internal( conn_t *sock ) { - del_fd( sock->fd ); + wipe_notifier( &sock->notify ); + wipe_wakeup( &sock->fd_fake ); + wipe_wakeup( &sock->fd_timeout ); close( sock->fd ); sock->fd = -1; } @@ -312,7 +374,7 @@ sock->callbacks.connect = cb; - /* open connection to IMAP server */ + /* open connection to server */ if (conf->tunnel) { int a[2]; @@ -334,10 +396,7 @@ } close( a[0] ); - sock->fd = a[1]; - - fcntl( a[1], F_SETFL, O_NONBLOCK ); - add_fd( a[1], socket_fd_cb, sock ); + socket_open_internal( sock, a[1] ); info( "\vok\n" ); socket_connected( sock ); @@ -349,10 +408,10 @@ memset( &hints, 0, sizeof(hints) ); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; + hints.ai_flags = AI_ADDRCONFIG; infon( "Resolving %s... ", conf->host ); if ((gaierr = getaddrinfo( conf->host, NULL, &hints, &sock->addrs ))) { - error( "IMAP error: Cannot resolve server '%s': %s\n", conf->host, gai_strerror( gaierr ) ); + error( "Error: Cannot resolve server '%s': %s\n", conf->host, gai_strerror( gaierr ) ); socket_connect_bail( sock ); return; } @@ -365,7 +424,7 @@ infon( "Resolving %s... ", conf->host ); he = gethostbyname( conf->host ); if (!he) { - error( "IMAP error: Cannot resolve server '%s': %s\n", conf->host, hstrerror( h_errno ) ); + error( "Error: Cannot resolve server '%s': %s\n", conf->host, hstrerror( h_errno ) ); socket_connect_bail( sock ); return; } @@ -381,7 +440,6 @@ socket_connect_one( conn_t *sock ) { int s; - ushort port; #ifdef HAVE_IPV6 struct addrinfo *ai; #else @@ -400,18 +458,13 @@ return; } - port = sock->conf->port ? sock->conf->port : -#ifdef HAVE_LIBSSL - sock->conf->use_imaps ? 993 : -#endif - 143; #ifdef HAVE_IPV6 if (ai->ai_family == AF_INET6) { struct sockaddr_in6 *in6 = ((struct sockaddr_in6 *)ai->ai_addr); char sockname[64]; - in6->sin6_port = htons( port ); + in6->sin6_port = htons( sock->conf->port ); nfasprintf( &sock->name, "%s ([%s]:%hu)", - sock->conf->host, inet_ntop( AF_INET6, &in6->sin6_addr, sockname, sizeof(sockname) ), port ); + sock->conf->host, inet_ntop( AF_INET6, &in6->sin6_addr, sockname, sizeof(sockname) ), sock->conf->port ); } else #endif { @@ -421,9 +474,9 @@ in->sin_family = AF_INET; in->sin_addr.s_addr = *((int *)*sock->curr_addr); #endif - in->sin_port = htons( port ); + in->sin_port = htons( sock->conf->port ); nfasprintf( &sock->name, "%s (%s:%hu)", - sock->conf->host, inet_ntoa( in->sin_addr ), port ); + sock->conf->host, inet_ntoa( in->sin_addr ), sock->conf->port ); } #ifdef HAVE_IPV6 @@ -435,9 +488,7 @@ perror( "socket" ); exit( 1 ); } - sock->fd = s; - fcntl( s, F_SETFL, O_NONBLOCK ); - add_fd( s, socket_fd_cb, sock ); + socket_open_internal( sock, s ); infon( "Connecting to %s... ", sock->name ); #ifdef HAVE_IPV6 @@ -449,7 +500,8 @@ socket_connect_failed( sock ); return; } - conf_fd( s, 0, POLLOUT ); + conf_notifier( &sock->notify, 0, POLLOUT ); + socket_expect_read( sock, 1 ); sock->state = SCK_CONNECTING; info( "\v\n" ); return; @@ -478,20 +530,31 @@ { #ifdef HAVE_IPV6 freeaddrinfo( conn->addrs ); + conn->addrs = 0; #endif - conf_fd( conn->fd, 0, POLLIN ); + conf_notifier( &conn->notify, 0, POLLIN ); + socket_expect_read( conn, 0 ); conn->state = SCK_READY; conn->callbacks.connect( 1, conn->callback_aux ); } static void -socket_connect_bail( conn_t *conn ) +socket_cleanup_names( conn_t *conn ) { #ifdef HAVE_IPV6 - freeaddrinfo( conn->addrs ); + if (conn->addrs) { + freeaddrinfo( conn->addrs ); + conn->addrs = 0; + } #endif free( conn->name ); conn->name = 0; +} + +static void +socket_connect_bail( conn_t *conn ) +{ + socket_cleanup_names( conn ); conn->callbacks.connect( 0, conn->callback_aux ); } @@ -502,58 +565,148 @@ { if (sock->fd >= 0) socket_close_internal( sock ); - free( sock->name ); - sock->name = 0; + socket_cleanup_names( sock ); #ifdef HAVE_LIBSSL if (sock->ssl) { SSL_free( sock->ssl ); sock->ssl = 0; + wipe_wakeup( &sock->ssl_fake ); + } +#endif +#ifdef HAVE_LIBZ + if (sock->in_z) { + inflateEnd( sock->in_z ); + free( sock->in_z ); + sock->in_z = 0; + deflateEnd( sock->out_z ); + free( sock->out_z ); + sock->out_z = 0; + wipe_wakeup( &sock->z_fake ); } #endif while (sock->write_buf) dispose_chunk( sock ); + free( sock->append_buf ); + sock->append_buf = 0; } -static void -socket_fill( conn_t *sock ) +static int +prepare_read( conn_t *sock, char **buf, int *len ) { - char *buf; int n = sock->offset + sock->bytes; - int len = sizeof(sock->buf) - n; - if (!len) { + if (!(*len = sizeof(sock->buf) - n)) { error( "Socket error: receive buffer full. Probably protocol error.\n" ); socket_fail( sock ); - return; + return -1; } + *buf = sock->buf + n; + return 0; +} + +static int +do_read( conn_t *sock, char *buf, int len ) +{ + int n; + assert( sock->fd >= 0 ); - buf = sock->buf + n; + if (pending_wakeup( &sock->fd_timeout )) + conf_wakeup( &sock->fd_timeout, sock->conf->timeout ); #ifdef HAVE_LIBSSL if (sock->ssl) { if ((n = ssl_return( "read from", sock, SSL_read( sock->ssl, buf, len ) )) <= 0) - return; + return n; + if (n == len && SSL_pending( sock->ssl )) - fake_fd( sock->fd, POLLIN ); + conf_wakeup( &sock->ssl_fake, 0 ); } else #endif { if ((n = read( sock->fd, buf, len )) < 0) { sys_error( "Socket error: read from %s", sock->name ); socket_fail( sock ); - return; } else if (!n) { - error( "Socket error: read from %s: unexpected EOF\n", sock->name ); - socket_fail( sock ); - return; + /* EOF. Callers take the short path out, so signal higher layers from here. */ + sock->state = SCK_EOF; + sock->read_callback( sock->callback_aux ); } } - sock->bytes += n; - sock->read_callback( sock->callback_aux ); + + return n; +} + +#ifdef HAVE_LIBZ +static void +socket_fill_z( conn_t *sock ) +{ + char *buf; + int len, ret; + + if (prepare_read( sock, &buf, &len ) < 0) + return; + + sock->in_z->avail_out = len; + sock->in_z->next_out = (unsigned char *)buf; + + ret = inflate( sock->in_z, Z_SYNC_FLUSH ); + if (ret != Z_OK && ret != Z_STREAM_END) { + error( "Error decompressing data from %s: %s\n", sock->name, sock->in_z->msg ); + socket_fail( sock ); + return; + } + + if (!sock->in_z->avail_out) + conf_wakeup( &sock->z_fake, 0 ); + + if ((len = (char *)sock->in_z->next_out - buf)) { + sock->bytes += len; + sock->read_callback( sock->callback_aux ); + } +} +#endif + +static void +socket_fill( conn_t *sock ) +{ +#ifdef HAVE_LIBZ + if (sock->in_z) { + int ret; + /* The timer will preempt reads until the buffer is empty. */ + assert( !sock->in_z->avail_in ); + sock->in_z->next_in = (uchar *)sock->z_buf; + if ((ret = do_read( sock, sock->z_buf, sizeof(sock->z_buf) )) <= 0) + return; + sock->in_z->avail_in = ret; + socket_fill_z( sock ); + } else +#endif + { + char *buf; + int len; + + if (prepare_read( sock, &buf, &len ) < 0) + return; + + if ((len = do_read( sock, buf, len )) <= 0) + return; + + sock->bytes += len; + sock->read_callback( sock->callback_aux ); + } +} + +void +socket_expect_read( conn_t *conn, int expect ) +{ + if (conn->conf->timeout > 0 && expect != pending_wakeup( &conn->fd_timeout )) + conf_wakeup( &conn->fd_timeout, expect ? conn->conf->timeout : -1 ); } int socket_read( conn_t *conn, char *buf, int len ) { int n = conn->bytes; + if (!n && conn->state == SCK_EOF) + return -1; if (n > len) n = len; memcpy( buf, conn->buf + conn->offset, n ); @@ -578,6 +731,8 @@ memmove( b->buf, b->buf + b->offset, b->bytes ); b->offset = 0; } + if (b->state == SCK_EOF) + return (void *)~0; return 0; } n = p + 1 - s; @@ -607,10 +762,10 @@ socket_fail( sock ); } else { n = 0; - conf_fd( sock->fd, POLLIN, POLLOUT ); + conf_notifier( &sock->notify, POLLIN, POLLOUT ); } } else if (n != len) { - conf_fd( sock->fd, POLLIN, POLLOUT ); + conf_notifier( &sock->notify, POLLIN, POLLOUT ); } return n; } @@ -621,8 +776,7 @@ buff_chunk_t *bc = conn->write_buf; if (!(conn->write_buf = bc->next)) conn->write_buf_append = &conn->write_buf; - if (bc->data != bc->buf) - free( bc->data ); + conn->buffer_mem -= bc->len; free( bc ); } @@ -640,6 +794,7 @@ return -1; if (n != len) { conn->write_offset += n; + conn->writing = 1; return 0; } conn->write_offset = 0; @@ -647,46 +802,149 @@ } #ifdef HAVE_LIBSSL if (conn->ssl && SSL_pending( conn->ssl )) - fake_fd( conn->fd, POLLIN ); + conf_wakeup( &conn->ssl_fake, 0 ); #endif - return conn->write_callback( conn->callback_aux ); + conn->writing = 0; + conn->write_callback( conn->callback_aux ); + return -1; } static void -do_append( conn_t *conn, char *buf, int len, ownership_t takeOwn ) +do_append( conn_t *conn, buff_chunk_t *bc ) { - buff_chunk_t *bc; - - if (takeOwn == GiveOwn) { - bc = nfmalloc( offsetof(buff_chunk_t, buf) ); - bc->data = buf; - } else { - bc = nfmalloc( offsetof(buff_chunk_t, buf) + len ); - bc->data = bc->buf; - memcpy( bc->data, buf, len ); - } - bc->len = len; bc->next = 0; + conn->buffer_mem += bc->len; *conn->write_buf_append = bc; conn->write_buf_append = &bc->next; } -int -socket_write( conn_t *conn, char *buf, int len, ownership_t takeOwn ) +/* This is big enough to avoid excessive chunking, but is + * sufficiently small to keep SSL latency low with a slow uplink. */ +#define WRITE_CHUNK_SIZE 1024 + +static void +do_flush( conn_t *conn ) +{ + buff_chunk_t *bc = conn->append_buf; +#ifdef HAVE_LIBZ + if (conn->out_z) { + int buf_avail = conn->append_avail; + if (!conn->z_written) + return; + do { + if (!bc) { + buf_avail = WRITE_CHUNK_SIZE; + bc = nfmalloc( offsetof(buff_chunk_t, data) + buf_avail ); + bc->len = 0; + } + conn->out_z->next_in = Z_NULL; + conn->out_z->avail_in = 0; + conn->out_z->next_out = (uchar *)bc->data + bc->len; + conn->out_z->avail_out = buf_avail; + if (deflate( conn->out_z, Z_PARTIAL_FLUSH ) != Z_OK) { + error( "Fatal: Compression error: %s\n", conn->out_z->msg ); + abort(); + } + bc->len = (char *)conn->out_z->next_out - bc->data; + if (bc->len) { + do_append( conn, bc ); + bc = 0; + buf_avail = 0; + } else { + buf_avail = conn->out_z->avail_out; + } + } while (!conn->out_z->avail_out); + conn->append_buf = bc; + conn->append_avail = buf_avail; + conn->z_written = 0; + } else +#endif + if (bc) { + do_append( conn, bc ); + conn->append_buf = 0; +#ifdef HAVE_LIBZ + conn->append_avail = 0; +#endif + } +} + +void +socket_write( conn_t *conn, conn_iovec_t *iov, int iovcnt ) { - if (conn->write_buf) { - do_append( conn, buf, len, takeOwn ); - return len; - } else { - int n = do_write( conn, buf, len ); - if (n != len && n >= 0) { - conn->write_offset = n; - do_append( conn, buf, len, takeOwn ); - } else if (takeOwn) { - free( buf ); + int i, buf_avail, len, offset = 0, total = 0; + buff_chunk_t *bc; + + for (i = 0; i < iovcnt; i++) + total += iov[i].len; + if (total >= WRITE_CHUNK_SIZE) { + /* If the new data is too big, queue the pending buffer to avoid latency. */ + do_flush( conn ); + } + bc = conn->append_buf; +#ifdef HAVE_LIBZ + buf_avail = conn->append_avail; +#endif + while (total) { + if (!bc) { + /* We don't do anything special when compressing, as there is no way to + * predict a reasonable output buffer size anyway - deflatePending() does + * not account for consumed but not yet compressed input, and adding up + * the deflateBound()s would be a tad *too* pessimistic. */ + buf_avail = total > WRITE_CHUNK_SIZE ? total : WRITE_CHUNK_SIZE; + bc = nfmalloc( offsetof(buff_chunk_t, data) + buf_avail ); + bc->len = 0; +#ifndef HAVE_LIBZ + } else { + /* A pending buffer will always be of standard size - over-sized + * buffers are immediately filled and queued. */ + buf_avail = WRITE_CHUNK_SIZE - bc->len; +#endif + } + while (total) { + len = iov->len - offset; +#ifdef HAVE_LIBZ + if (conn->out_z) { + conn->out_z->next_in = (uchar *)iov->buf + offset; + conn->out_z->avail_in = len; + conn->out_z->next_out = (uchar *)bc->data + bc->len; + conn->out_z->avail_out = buf_avail; + if (deflate( conn->out_z, Z_NO_FLUSH ) != Z_OK) { + error( "Fatal: Compression error: %s\n", conn->out_z->msg ); + abort(); + } + bc->len = (char *)conn->out_z->next_out - bc->data; + buf_avail = conn->out_z->avail_out; + len -= conn->out_z->avail_in; + conn->z_written = 1; + } else +#endif + { + if (len > buf_avail) + len = buf_avail; + memcpy( bc->data + bc->len, iov->buf + offset, len ); + bc->len += len; + buf_avail -= len; + } + offset += len; + total -= len; + if (offset == iov->len) { + if (iov->takeOwn == GiveOwn) + free( iov->buf ); + iov++; + offset = 0; + } + if (!buf_avail) { + do_append( conn, bc ); + bc = 0; + break; + } } - return n; } + conn->append_buf = bc; +#ifdef HAVE_LIBZ + conn->append_avail = buf_avail; +#endif + conf_wakeup( &conn->fd_fake, 0 ); } static void @@ -715,7 +973,7 @@ } if (events & POLLOUT) - conf_fd( conn->fd, POLLIN, 0 ); + conf_notifier( &conn->notify, POLLIN, 0 ); #ifdef HAVE_LIBSSL if (conn->state == SCK_STARTTLS) { @@ -736,57 +994,48 @@ socket_fill( conn ); } -#ifdef HAVE_LIBSSL -/* this isn't strictly socket code, but let's have all OpenSSL use in one file. */ +static void +socket_fake_cb( void *aux ) +{ + conn_t *conn = (conn_t *)aux; -#define ENCODED_SIZE(n) (4*((n+2)/3)) + /* Ensure that a pending write gets queued. */ + do_flush( conn ); + /* If no writes are ongoing, start writing now. */ + if (!conn->writing) + do_queued_write( conn ); +} -static char -hexchar( unsigned int b ) +static void +socket_timeout_cb( void *aux ) { - if (b < 10) - return '0' + b; - return 'a' + (b - 10); + conn_t *conn = (conn_t *)aux; + + if (conn->state == SCK_CONNECTING) { + errno = ETIMEDOUT; + socket_connect_failed( conn ); + } else { + error( "Socket error on %s: timeout.\n", conn->name ); + socket_fail( conn ); + } } -void -cram( const char *challenge, const char *user, const char *pass, char **_final, int *_finallen ) +#ifdef HAVE_LIBZ +static void +z_fake_cb( void *aux ) { - char *response, *final; - unsigned hashlen; - int i, clen, blen, flen, olen; - unsigned char hash[16]; - char buf[256], hex[33]; - HMAC_CTX hmac; - - HMAC_Init( &hmac, (unsigned char *)pass, strlen( pass ), EVP_md5() ); - - clen = strlen( challenge ); - /* response will always be smaller than challenge because we are decoding. */ - response = nfcalloc( 1 + clen ); - EVP_DecodeBlock( (unsigned char *)response, (unsigned char *)challenge, clen ); - HMAC_Update( &hmac, (unsigned char *)response, strlen( response ) ); - free( response ); - - hashlen = sizeof(hash); - HMAC_Final( &hmac, hash, &hashlen ); - assert( hashlen == sizeof(hash) ); - - hex[32] = 0; - for (i = 0; i < 16; i++) { - hex[2 * i] = hexchar( (hash[i] >> 4) & 0xf ); - hex[2 * i + 1] = hexchar( hash[i] & 0xf ); - } - - blen = nfsnprintf( buf, sizeof(buf), "%s %s", user, hex ); - - flen = ENCODED_SIZE( blen ); - final = nfmalloc( flen + 1 ); - final[flen] = 0; - olen = EVP_EncodeBlock( (unsigned char *)final, (unsigned char *)buf, blen ); - assert( olen == flen ); + conn_t *conn = (conn_t *)aux; + + socket_fill_z( conn ); +} +#endif + +#ifdef HAVE_LIBSSL +static void +ssl_fake_cb( void *aux ) +{ + conn_t *conn = (conn_t *)aux; - *_final = final; - *_finallen = flen; + socket_fill( conn ); } #endif diff -Nru isync-1.1.0/src/socket.h isync-1.2.1-1.812.20170514/src/socket.h --- isync-1.1.0/src/socket.h 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/socket.h 2017-05-26 14:36:31.000000000 +0000 @@ -25,30 +25,47 @@ #include "common.h" +#ifdef HAVE_LIBZ +#include +#endif + +#ifdef HAVE_LIBSSL typedef struct ssl_st SSL; typedef struct ssl_ctx_st SSL_CTX; +typedef struct stack_st _STACK; -typedef struct server_conf { +enum { + SSLv2 = 1, + SSLv3 = 2, + TLSv1 = 4, + TLSv1_1 = 8, + TLSv1_2 = 16 +}; +#endif + +typedef struct { char *tunnel; char *host; int port; + int timeout; #ifdef HAVE_LIBSSL char *cert_file; - char use_imaps; - char use_sslv2, use_sslv3, use_tlsv1, use_tlsv11, use_tlsv12; + char *client_certfile; + char *client_keyfile; + char system_certs; + char ssl_versions; /* these are actually variables and are leaked at the end */ char ssl_ctx_valid; - unsigned num_trusted; + _STACK *trusted_certs; SSL_CTX *SSLContext; #endif } server_conf_t; typedef struct buff_chunk { struct buff_chunk *next; - char *data; int len; - char buf[1]; + char data[1]; } buff_chunk_t; typedef struct { @@ -64,27 +81,45 @@ char *name; #ifdef HAVE_LIBSSL SSL *ssl; - int force_trusted; + wakeup_t ssl_fake; +#endif +#ifdef HAVE_LIBZ + z_streamp in_z, out_z; + wakeup_t z_fake; + int z_written; #endif void (*bad_callback)( void *aux ); /* async fail while sending or listening */ void (*read_callback)( void *aux ); /* data available for reading */ - int (*write_callback)( void *aux ); /* all *queued* data was sent */ + void (*write_callback)( void *aux ); /* all *queued* data was sent */ union { void (*connect)( int ok, void *aux ); void (*starttls)( int ok, void *aux ); } callbacks; void *callback_aux; + notifier_t notify; + wakeup_t fd_fake; + wakeup_t fd_timeout; + /* writing */ + buff_chunk_t *append_buf; /* accumulating buffer */ buff_chunk_t *write_buf, **write_buf_append; /* buffer head & tail */ + int writing; +#ifdef HAVE_LIBZ + int append_avail; /* space left in accumulating buffer */ +#endif int write_offset; /* offset into buffer head */ + int buffer_mem; /* memory currently occupied by buffers in the queue */ /* reading */ int offset; /* start of filled bytes in buffer */ int bytes; /* number of filled bytes in buffer */ int scanoff; /* offset to continue scanning for newline at, relative to 'offset' */ char buf[100000]; +#ifdef HAVE_LIBZ + char z_buf[100000]; +#endif } conn_t; /* call this before doing anything with the socket */ @@ -92,7 +127,7 @@ const server_conf_t *conf, void (*bad_callback)( void *aux ), void (*read_callback)( void *aux ), - int (*write_callback)( void *aux ), + void (*write_callback)( void *aux ), void *aux ) { conn->conf = conf; @@ -106,13 +141,17 @@ } void socket_connect( conn_t *conn, void (*cb)( int ok, void *aux ) ); void socket_start_tls(conn_t *conn, void (*cb)( int ok, void *aux ) ); +void socket_start_deflate( conn_t *conn ); void socket_close( conn_t *sock ); +void socket_expect_read( conn_t *sock, int expect ); int socket_read( conn_t *sock, char *buf, int len ); /* never waits */ char *socket_read_line( conn_t *sock ); /* don't free return value; never waits */ typedef enum { KeepOwn = 0, GiveOwn } ownership_t; -int socket_write( conn_t *sock, char *buf, int len, ownership_t takeOwn ); - -void cram( const char *challenge, const char *user, const char *pass, - char **_final, int *_finallen ); +typedef struct { + char *buf; + int len; + ownership_t takeOwn; +} conn_iovec_t; +void socket_write( conn_t *sock, conn_iovec_t *iov, int iovcnt ); #endif diff -Nru isync-1.1.0/src/sync.c isync-1.2.1-1.812.20170514/src/sync.c --- isync-1.1.0/src/sync.c 2013-12-18 21:09:33.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/sync.c 2017-05-26 14:36:31.000000000 +0000 @@ -35,7 +35,7 @@ #include #include -#ifndef _POSIX_SYNCHRONIZED_IO +#if !defined(_POSIX_SYNCHRONIZED_IO) || _POSIX_SYNCHRONIZED_IO <= 0 # define fdatasync fsync #endif @@ -45,37 +45,64 @@ const char *str_ms[] = { "master", "slave" }, *str_hl[] = { "push", "pull" }; +static void ATTR_PRINTFLIKE(1, 2) +debug( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vdebug( DEBUG_SYNC, msg, va ); + va_end( va ); +} + +static void ATTR_PRINTFLIKE(1, 2) +debugn( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vdebugn( DEBUG_SYNC, msg, va ); + va_end( va ); +} + void Fclose( FILE *f, int safe ) { if ((safe && (fflush( f ) || (UseFSync && fdatasync( fileno( f ) )))) || fclose( f ) == EOF) { - sys_error( "Error: cannot close file. Disk full?" ); + sys_error( "Error: cannot close file" ); exit( 1 ); } } void -Fprintf( FILE *f, const char *msg, ... ) +vFprintf( FILE *f, const char *msg, va_list va ) { int r; - va_list va; - va_start( va, msg ); r = vfprintf( f, msg, va ); - va_end( va ); if (r < 0) { - sys_error( "Error: cannot write file. Disk full?" ); + sys_error( "Error: cannot write file" ); exit( 1 ); } } +void +Fprintf( FILE *f, const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vFprintf( f, msg, va ); + va_end( va ); +} + static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' }; static int parse_flags( const char *buf ) { - unsigned flags, i, d; + uint flags, i, d; for (flags = i = d = 0; i < as(Flags); i++) if (buf[d] == Flags[i]) { @@ -88,7 +115,7 @@ static int make_flags( int flags, char *buf ) { - unsigned i, d; + uint i, d; for (i = d = 0; i < as(Flags); i++) if (flags & (1 << i)) @@ -97,72 +124,49 @@ return d; } - -#define S_DEAD (1<<0) /* ephemeral: the entry was killed and should be ignored */ -#define S_DEL(ms) (1<<(2+(ms))) /* ephemeral: m/s message would be subject to expunge */ -#define S_EXPIRED (1<<4) /* the entry is expired (slave message removal confirmed) */ -#define S_EXPIRE (1<<5) /* the entry is being expired (slave message removal scheduled) */ -#define S_NEXPIRE (1<<6) /* temporary: new expiration state */ -#define S_DELETE (1<<7) /* ephemeral: flags propagation is a deletion */ - -#define mvBit(in,ib,ob) ((unsigned char)(((unsigned)in) * (ob) / (ib))) +// These is the (mostly) persistent status of the sync record. +// Most of these bits are actually mutually exclusive. It is a +// bitfield to allow for easy testing for multiple states. +#define S_EXPIRE (1<<0) // the entry is being expired (slave message removal scheduled) +#define S_EXPIRED (1<<1) // the entry is expired (slave message removal confirmed) +#define S_PENDING (1<<2) // the entry is new and awaits propagation (possibly a retry) +#define S_SKIPPED (1<<3) // the entry was not propagated (message is too big) +#define S_DEAD (1<<7) // ephemeral: the entry was killed and should be ignored + +// Ephemeral working set. +#define W_NEXPIRE (1<<0) // temporary: new expiration state +#define W_DELETE (1<<1) // ephemeral: flags propagation is a deletion +#define W_DEL(ms) (1<<(2+(ms))) // ephemeral: m/s message would be subject to expunge typedef struct sync_rec { struct sync_rec *next; /* string_list_t *keywords; */ - int uid[2]; /* -2 = pending (use tuid), -1 = skipped (too big), 0 = expired */ + uint uid[2]; message_t *msg[2]; - unsigned char status, flags, aflags[2], dflags[2]; + uchar status, wstate, flags, aflags[2], dflags[2]; char tuid[TUIDL]; } sync_rec_t; - -/* cases: - a) both non-null - b) only master null - b.1) uid[M] 0 - b.2) uid[M] -1 - b.3) master not scanned - b.4) master gone - c) only slave null - c.1) uid[S] 0 - c.2) uid[S] -1 - c.3) slave not scanned - c.4) slave gone - d) both null - d.1) both gone - d.2) uid[M] 0, slave not scanned - d.3) uid[M] -1, slave not scanned - d.4) master gone, slave not scanned - d.5) uid[M] 0, slave gone - d.6) uid[M] -1, slave gone - d.7) uid[S] 0, master not scanned - d.8) uid[S] -1, master not scanned - d.9) slave gone, master not scanned - d.10) uid[S] 0, master gone - d.11) uid[S] -1, master gone - impossible cases: both uid[M] & uid[S] 0 or -1, both not scanned -*/ - typedef struct { int t[2]; void (*cb)( int sts, void *aux ), *aux; - char *dname, *jname, *nname, *lname; + char *dname, *jname, *nname, *lname, *box_name[2]; FILE *jfp, *nfp; sync_rec_t *srecs, **srecadd; channel_conf_t *chan; store_t *ctx[2]; driver_t *drv[2]; - int state[2], ref_count, nsrecs, ret, lfd; - int new_total[2], new_done[2]; - int flags_total[2], flags_done[2]; - int trash_total[2], trash_done[2]; - int maxuid[2]; /* highest UID that was already propagated */ - int newmaxuid[2]; /* highest UID that is currently being propagated */ - int uidval[2]; /* UID validity value */ - int newuid[2]; /* TUID lookup makes sense only for UIDs >= this */ - int mmaxxuid; /* highest expired UID on master during new message propagation */ - int smaxxuid; /* highest expired UID on slave */ + const char *orig_name[2]; + message_t *msgs[2], *new_msgs[2]; + uint_array_alloc_t trashed_msgs[2]; + int state[2], opts[2], ref_count, nsrecs, ret, lfd, existing, replayed; + int new_pending[2], flags_pending[2], trash_pending[2]; + uint maxuid[2]; // highest UID that was already propagated + uint newmaxuid[2]; // highest UID that is currently being propagated + uint uidval[2]; // UID validity value + uint newuidval[2]; // UID validity obtained from driver + uint newuid[2]; // TUID lookup makes sense only for UIDs >= this + uint mmaxxuid; // highest expired UID on master } sync_vars_t; static void sync_ref( sync_vars_t *svars ) { ++svars->ref_count; } @@ -204,10 +208,27 @@ #define ST_SELECTED (1<<10) #define ST_DID_EXPUNGE (1<<11) #define ST_CLOSING (1<<12) +#define ST_CONFIRMED (1<<13) +#define ST_PRESENT (1<<14) +#define ST_SENDING_NEW (1<<15) +void +jFprintf( sync_vars_t *svars, const char *msg, ... ) +{ + va_list va; + + if (JLimit && !--JLimit) + exit( 101 ); + va_start( va, msg ); + vFprintf( svars->jfp, msg, va ); + va_end( va ); + if (JLimit && !--JLimit) + exit( 100 ); +} + static void -match_tuids( sync_vars_t *svars, int t ) +match_tuids( sync_vars_t *svars, int t, message_t *msgs ) { sync_rec_t *srec; message_t *tmsg, *ntmsg = 0; @@ -217,8 +238,8 @@ for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; - if (srec->uid[t] == -2 && srec->tuid[0]) { - debug( " pair(%d,%d): lookup %s, TUID %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], str_ms[t], srec->tuid ); + if (!srec->uid[t] && srec->tuid[0]) { + debug( " pair(%u,%u): lookup %s, TUID %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], str_ms[t], srec->tuid ); for (tmsg = ntmsg; tmsg; tmsg = tmsg->next) { if (tmsg->status & M_DEAD) continue; @@ -227,7 +248,7 @@ goto mfound; } } - for (tmsg = svars->ctx[t]->msgs; tmsg != ntmsg; tmsg = tmsg->next) { + for (tmsg = msgs; tmsg != ntmsg; tmsg = tmsg->next) { if (tmsg->status & M_DEAD) continue; if (tmsg->tuid[0] && !memcmp( tmsg->tuid, srec->tuid, TUIDL )) { @@ -236,18 +257,20 @@ } } debug( " -> TUID lost\n" ); - Fprintf( svars->jfp, "& %d %d\n", srec->uid[M], srec->uid[S] ); + jFprintf( svars, "& %u %u\n", srec->uid[M], srec->uid[S] ); srec->flags = 0; + // Note: status remains S_PENDING. srec->tuid[0] = 0; num_lost++; continue; mfound: - debug( " -> new UID %d %s\n", tmsg->uid, diag ); - Fprintf( svars->jfp, "%c %d %d %d\n", "<>"[t], srec->uid[M], srec->uid[S], tmsg->uid ); + debug( " -> new UID %u %s\n", tmsg->uid, diag ); + jFprintf( svars, "%c %u %u %u\n", "<>"[t], srec->uid[M], srec->uid[S], tmsg->uid ); tmsg->srec = srec; srec->msg[t] = tmsg; ntmsg = tmsg->next; srec->uid[t] = tmsg->uid; + srec->status = 0; srec->tuid[0] = 0; } } @@ -257,7 +280,7 @@ typedef struct copy_vars { - void (*cb)( int sts, int uid, struct copy_vars *vars ); + void (*cb)( int sts, uint uid, struct copy_vars *vars ); void *aux; sync_rec_t *srec; /* also ->tuid */ message_t *msg; @@ -277,17 +300,114 @@ svars->drv[t]->fetch_msg( svars->ctx[t], vars->msg, &vars->data, msg_fetched, vars ); } -static void msg_stored( int sts, int uid, void *aux ); +static void msg_stored( int sts, uint uid, void *aux ); + +static void +copy_msg_bytes( char **out_ptr, const char *in_buf, int *in_idx, int in_len, int in_cr, int out_cr ) +{ + char *out = *out_ptr; + int idx = *in_idx; + if (out_cr != in_cr) { + char c; + if (out_cr) { + for (; idx < in_len; idx++) { + if ((c = in_buf[idx]) != '\r') { + if (c == '\n') + *out++ = '\r'; + *out++ = c; + } + } + } else { + for (; idx < in_len; idx++) { + if ((c = in_buf[idx]) != '\r') + *out++ = c; + } + } + } else { + memcpy( out, in_buf + idx, in_len - idx ); + out += in_len - idx; + idx = in_len; + } + *out_ptr = out; + *in_idx = idx; +} + +static int +copy_msg_convert( int in_cr, int out_cr, copy_vars_t *vars ) +{ + char *in_buf = vars->data.data; + int in_len = vars->data.len; + int idx = 0, sbreak = 0, ebreak = 0; + int lines = 0, hdr_crs = 0, bdy_crs = 0, app_cr = 0, extra = 0; + if (vars->srec) { + nloop: ; + int start = idx; + int line_crs = 0; + while (idx < in_len) { + char c = in_buf[idx++]; + if (c == '\r') { + line_crs++; + } else if (c == '\n') { + if (starts_with_upper( in_buf + start, in_len - start, "X-TUID: ", 8 )) { + extra = (sbreak = start) - (ebreak = idx); + goto oke; + } + lines++; + hdr_crs += line_crs; + if (idx - line_crs - 1 == start) { + sbreak = ebreak = start; + goto oke; + } + goto nloop; + } + } + /* invalid message */ + free( in_buf ); + return 0; + oke: + app_cr = out_cr && (!in_cr || hdr_crs); + extra += 8 + TUIDL + app_cr + 1; + } + if (out_cr != in_cr) { + for (; idx < in_len; idx++) { + char c = in_buf[idx]; + if (c == '\r') + bdy_crs++; + else if (c == '\n') + lines++; + } + extra -= hdr_crs + bdy_crs; + if (out_cr) + extra += lines; + } + + vars->data.len = in_len + extra; + char *out_buf = vars->data.data = nfmalloc( vars->data.len ); + idx = 0; + if (vars->srec) { + copy_msg_bytes( &out_buf, in_buf, &idx, sbreak, in_cr, out_cr ); + + memcpy( out_buf, "X-TUID: ", 8 ); + out_buf += 8; + memcpy( out_buf, vars->srec->tuid, TUIDL ); + out_buf += TUIDL; + if (app_cr) + *out_buf++ = '\r'; + *out_buf++ = '\n'; + idx = ebreak; + } + copy_msg_bytes( &out_buf, in_buf, &idx, in_len, in_cr, out_cr ); + + free( in_buf ); + return 1; +} static void msg_fetched( int sts, void *aux ) { copy_vars_t *vars = (copy_vars_t *)aux; DECL_SVARS; - char *fmap, *buf; - int i, len, extra, scr, tcr, lcrs, hcrs, bcrs, lines; - int start, sbreak = 0, ebreak = 0; - char c; + int scr, tcr; switch (sts) { case DRV_OK: @@ -300,104 +420,15 @@ vars->msg->flags = vars->data.flags; - scr = (svars->drv[1-t]->flags / DRV_CRLF) & 1; - tcr = (svars->drv[t]->flags / DRV_CRLF) & 1; + scr = (svars->drv[1-t]->get_caps( svars->ctx[1-t] ) / DRV_CRLF) & 1; + tcr = (svars->drv[t]->get_caps( svars->ctx[t] ) / DRV_CRLF) & 1; if (vars->srec || scr != tcr) { - fmap = vars->data.data; - len = vars->data.len; - extra = lines = hcrs = bcrs = i = 0; - if (vars->srec) { - nloop: - start = i; - lcrs = 0; - while (i < len) { - c = fmap[i++]; - if (c == '\r') - lcrs++; - else if (c == '\n') { - if (!memcmp( fmap + start, "X-TUID: ", 8 )) { - extra = (sbreak = start) - (ebreak = i); - goto oke; - } - lines++; - hcrs += lcrs; - if (i - lcrs - 1 == start) { - sbreak = ebreak = start; - goto oke; - } - goto nloop; - } - } - /* invalid message */ - warn( "Warning: message %d from %s has incomplete header.\n", + if (!copy_msg_convert( scr, tcr, vars )) { + warn( "Warning: message %u from %s has incomplete header.\n", vars->msg->uid, str_ms[1-t] ); - free( fmap ); vars->cb( SYNC_NOGOOD, 0, vars ); return; - oke: - extra += 8 + TUIDL + 1 + (tcr && (!scr || hcrs)); } - if (tcr != scr) { - for (; i < len; i++) { - c = fmap[i]; - if (c == '\r') - bcrs++; - else if (c == '\n') - lines++; - } - extra -= hcrs + bcrs; - if (tcr) - extra += lines; - } - - vars->data.len = len + extra; - buf = vars->data.data = nfmalloc( vars->data.len ); - i = 0; - if (vars->srec) { - if (tcr != scr) { - if (tcr) { - for (; i < sbreak; i++) - if ((c = fmap[i]) != '\r') { - if (c == '\n') - *buf++ = '\r'; - *buf++ = c; - } - } else { - for (; i < sbreak; i++) - if ((c = fmap[i]) != '\r') - *buf++ = c; - } - } else { - memcpy( buf, fmap, sbreak ); - buf += sbreak; - } - - memcpy( buf, "X-TUID: ", 8 ); - buf += 8; - memcpy( buf, vars->srec->tuid, TUIDL ); - buf += TUIDL; - if (tcr && (!scr || hcrs)) - *buf++ = '\r'; - *buf++ = '\n'; - i = ebreak; - } - if (tcr != scr) { - if (tcr) { - for (; i < len; i++) - if ((c = fmap[i]) != '\r') { - if (c == '\n') - *buf++ = '\r'; - *buf++ = c; - } - } else { - for (; i < len; i++) - if ((c = fmap[i]) != '\r') - *buf++ = c; - } - } else - memcpy( buf, fmap + i, len - i ); - - free( fmap ); } svars->drv[t]->store_msg( svars->ctx[t], &vars->data, !vars->srec, msg_stored, vars ); @@ -415,7 +446,7 @@ } static void -msg_stored( int sts, int uid, void *aux ) +msg_stored( int sts, uint uid, void *aux ) { copy_vars_t *vars = (copy_vars_t *)aux; DECL_SVARS; @@ -430,7 +461,7 @@ case DRV_MSG_BAD: INIT_SVARS(vars->aux); (void)svars; - warn( "Warning: %s refuses to store message %d from %s.\n", + warn( "Warning: %s refuses to store message %u from %s.\n", str_ms[t], vars->msg->uid, str_ms[1-t] ); vars->cb( SYNC_NOGOOD, 0, vars ); break; @@ -441,32 +472,7 @@ } -static void -stats( sync_vars_t *svars ) -{ - char buf[2][64]; - char *cs; - int t, l; - static int cols = -1; - - if (cols < 0 && (!(cs = getenv( "COLUMNS" )) || !(cols = atoi( cs ) / 2))) - cols = 36; - if (!(DFlags & QUIET)) { - for (t = 0; t < 2; t++) { - l = sprintf( buf[t], "+%d/%d *%d/%d #%d/%d", - svars->new_done[t], svars->new_total[t], - svars->flags_done[t], svars->flags_total[t], - svars->trash_done[t], svars->trash_total[t] ); - if (l > cols) - buf[t][cols - 1] = '~'; - } - infon( "\v\rM: %.*s S: %.*s", cols, buf[0], cols, buf[1] ); - } -} - - static void sync_bail( sync_vars_t *svars ); -static void sync_bail1( sync_vars_t *svars ); static void sync_bail2( sync_vars_t *svars ); static void sync_bail3( sync_vars_t *svars ); static void cancel_done( void *aux ); @@ -483,7 +489,7 @@ } else if (!(svars->state[t] & ST_SENT_CANCEL)) { /* ignore subsequent failures from in-flight commands */ svars->state[t] |= ST_SENT_CANCEL; - svars->drv[t]->cancel( svars->ctx[t], cancel_done, AUX ); + svars->drv[t]->cancel_cmds( svars->ctx[t], cancel_done, AUX ); } if (other_state & ST_CANCELED) break; @@ -497,13 +503,11 @@ svars->state[t] |= ST_CANCELED; if (svars->state[1-t] & ST_CANCELED) { - if (svars->lfd) { + if (svars->nfp) { Fclose( svars->nfp, 0 ); Fclose( svars->jfp, 0 ); - sync_bail( svars ); - } else { - sync_bail2( svars ); } + sync_bail( svars ); } } @@ -576,118 +580,58 @@ } -#define JOURNAL_VERSION "2" - -static void box_selected( int sts, void *aux ); - -void -sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, - void (*cb)( int sts, void *aux ), void *aux ) -{ - sync_vars_t *svars; - int t; - - svars = nfcalloc( sizeof(*svars) ); - svars->t[1] = 1; - svars->ref_count = 1; - svars->cb = cb; - svars->aux = aux; - svars->ctx[0] = ctx[0]; - svars->ctx[1] = ctx[1]; - svars->chan = chan; - svars->uidval[0] = svars->uidval[1] = -1; - svars->srecadd = &svars->srecs; - - for (t = 0; t < 2; t++) { - ctx[t]->orig_name = - (!names[t] || (ctx[t]->conf->map_inbox && !strcmp( ctx[t]->conf->map_inbox, names[t] ))) ? - "INBOX" : names[t]; - if (!ctx[t]->conf->flat_delim) { - ctx[t]->name = nfstrdup( ctx[t]->orig_name ); - } else if (map_name( ctx[t]->orig_name, &ctx[t]->name, 0, "/", ctx[t]->conf->flat_delim ) < 0) { - error( "Error: canonical mailbox name '%s' contains flattened hierarchy delimiter\n", ctx[t]->name ); - svars->ret = SYNC_FAIL; - sync_bail3( svars ); - return; - } - ctx[t]->uidvalidity = -1; - set_bad_callback( ctx[t], store_bad, AUX ); - svars->drv[t] = ctx[t]->conf->driver; - } - /* Both boxes must be fully set up at this point, so that error exit paths - * don't run into uninitialized variables. */ - sync_ref( svars ); - for (t = 0; t < 2; t++) { - info( "Selecting %s %s...\n", str_ms[t], ctx[t]->orig_name ); - svars->drv[t]->select( ctx[t], (chan->ops[t] & OP_CREATE) != 0, box_selected, AUX ); - if (check_cancel( svars )) - break; - } - sync_deref( svars ); -} - -static void load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ); +#define JOURNAL_VERSION "3" -static void -box_selected( int sts, void *aux ) +static int +prepare_state( sync_vars_t *svars ) { - DECL_SVARS; - sync_rec_t *srec, *nsrec; char *s, *cmname, *csname; - store_t *ctx[2]; channel_conf_t *chan; - FILE *jfp; - int opts[2], line, t1, t2, t3; - int *mexcs, nmexcs, rmexcs, minwuid; - struct stat st; - struct flock lck; - char fbuf[16]; /* enlarge when support for keywords is added */ - char buf[128], buf1[64], buf2[64]; - - if (check_ret( sts, aux )) - return; - INIT_SVARS(aux); - ctx[0] = svars->ctx[0]; - ctx[1] = svars->ctx[1]; - svars->state[t] |= ST_SELECTED; - if (!(svars->state[1-t] & ST_SELECTED)) - return; chan = svars->chan; if (!strcmp( chan->sync_state ? chan->sync_state : global_conf.sync_state, "*" )) { - if (!ctx[S]->path) { + const char *path = svars->drv[S]->get_box_path( svars->ctx[S] ); + if (!path) { error( "Error: store '%s' does not support in-box sync state\n", chan->stores[S]->name ); - sbail: - svars->ret = SYNC_FAIL; - sync_bail2( svars ); - return; + return 0; } - nfasprintf( &svars->dname, "%s/." EXE "state", ctx[S]->path ); + nfasprintf( &svars->dname, "%s/." EXE "state", path ); } else { - csname = clean_strdup( ctx[S]->name ); + csname = clean_strdup( svars->box_name[S] ); if (chan->sync_state) nfasprintf( &svars->dname, "%s%s", chan->sync_state, csname ); else { - cmname = clean_strdup( ctx[M]->name ); - nfasprintf( &svars->dname, "%s:%s:%s_:%s:%s", global_conf.sync_state, - chan->stores[M]->name, cmname, chan->stores[S]->name, csname ); + char c = FieldDelimiter; + cmname = clean_strdup( svars->box_name[M] ); + nfasprintf( &svars->dname, "%s%c%s%c%s_%c%s%c%s", global_conf.sync_state, + c, chan->stores[M]->name, c, cmname, c, chan->stores[S]->name, c, csname ); free( cmname ); } free( csname ); if (!(s = strrchr( svars->dname, '/' ))) { error( "Error: invalid SyncState location '%s'\n", svars->dname ); - goto sbail; + return 0; } *s = 0; if (mkdir( svars->dname, 0700 ) && errno != EEXIST) { sys_error( "Error: cannot create SyncState directory '%s'", svars->dname ); - goto sbail; + return 0; } *s = '/'; } nfasprintf( &svars->jname, "%s.journal", svars->dname ); nfasprintf( &svars->nname, "%s.new", svars->dname ); nfasprintf( &svars->lname, "%s.lock", svars->dname ); + return 1; +} + +static int +lock_state( sync_vars_t *svars ) +{ + struct flock lck; + + if (svars->lfd >= 0) + return 1; memset( &lck, 0, sizeof(lck) ); #if SEEK_SET != 0 lck.l_whence = SEEK_SET; @@ -697,56 +641,103 @@ #endif if ((svars->lfd = open( svars->lname, O_WRONLY|O_CREAT, 0666 )) < 0) { sys_error( "Error: cannot create lock file %s", svars->lname ); - svars->ret = SYNC_FAIL; - sync_bail2( svars ); - return; + return 0; } if (fcntl( svars->lfd, F_SETLK, &lck )) { error( "Error: channel :%s:%s-:%s:%s is locked\n", - chan->stores[M]->name, ctx[M]->orig_name, chan->stores[S]->name, ctx[S]->orig_name ); - svars->ret = SYNC_FAIL; - sync_bail1( svars ); - return; + svars->chan->stores[M]->name, svars->orig_name[M], svars->chan->stores[S]->name, svars->orig_name[S] ); + close( svars->lfd ); + svars->lfd = -1; + return 0; } + return 1; +} + +static void +save_state( sync_vars_t *svars ) +{ + sync_rec_t *srec; + char fbuf[16]; /* enlarge when support for keywords is added */ + + Fprintf( svars->nfp, + "MasterUidValidity %u\nSlaveUidValidity %u\nMaxPulledUid %u\nMaxPushedUid %u\n", + svars->uidval[M], svars->uidval[S], svars->maxuid[M], svars->maxuid[S] ); + if (svars->mmaxxuid) + Fprintf( svars->nfp, "MaxExpiredMasterUid %u\n", svars->mmaxxuid ); + Fprintf( svars->nfp, "\n" ); + for (srec = svars->srecs; srec; srec = srec->next) { + if (srec->status & S_DEAD) + continue; + make_flags( srec->flags, fbuf ); + Fprintf( svars->nfp, "%u %u %s%s\n", srec->uid[M], srec->uid[S], + (srec->status & S_SKIPPED) ? "^" : (srec->status & S_PENDING) ? "!" : (srec->status & S_EXPIRED) ? "~" : "", fbuf ); + } + + Fclose( svars->nfp, 1 ); + Fclose( svars->jfp, 0 ); + if (!(DFlags & KEEPJOURNAL)) { + /* order is important! */ + if (rename( svars->nname, svars->dname )) + warn( "Warning: cannot commit sync state %s\n", svars->dname ); + else if (unlink( svars->jname )) + warn( "Warning: cannot delete journal %s\n", svars->jname ); + } +} + +static int +load_state( sync_vars_t *svars ) +{ + sync_rec_t *srec, *nsrec; + char *s; + FILE *jfp; + int ll; + uint smaxxuid = 0; + char c; + struct stat st; + char fbuf[16]; /* enlarge when support for keywords is added */ + char buf[128], buf1[64], buf2[64]; + if ((jfp = fopen( svars->dname, "r" ))) { + if (!lock_state( svars )) + goto jbail; debug( "reading sync state %s ...\n", svars->dname ); - line = 0; + int line = 0; while (fgets( buf, sizeof(buf), jfp )) { line++; - if (!(t = strlen( buf )) || buf[t - 1] != '\n') { + if (!(ll = strlen( buf )) || buf[ll - 1] != '\n') { error( "Error: incomplete sync state header entry at %s:%d\n", svars->dname, line ); jbail: fclose( jfp ); - bail: - svars->ret = SYNC_FAIL; - sync_bail( svars ); - return; + return 0; } - if (t == 1) + if (ll == 1) goto gothdr; if (line == 1 && isdigit( buf[0] )) { if (sscanf( buf, "%63s %63s", buf1, buf2 ) != 2 || - sscanf( buf1, "%d:%d", &svars->uidval[M], &svars->maxuid[M] ) < 2 || - sscanf( buf2, "%d:%d:%d", &svars->uidval[S], &svars->smaxxuid, &svars->maxuid[S] ) < 3) { + sscanf( buf1, "%u:%u", &svars->uidval[M], &svars->maxuid[M] ) < 2 || + sscanf( buf2, "%u:%u:%u", &svars->uidval[S], &smaxxuid, &svars->maxuid[S] ) < 3) { error( "Error: invalid sync state header in %s\n", svars->dname ); goto jbail; } goto gothdr; } - if (sscanf( buf, "%63s %d", buf1, &t1 ) != 2) { + uint uid; + if (sscanf( buf, "%63s %u", buf1, &uid ) != 2) { error( "Error: malformed sync state header entry at %s:%d\n", svars->dname, line ); goto jbail; } if (!strcmp( buf1, "MasterUidValidity" )) - svars->uidval[M] = t1; + svars->uidval[M] = uid; else if (!strcmp( buf1, "SlaveUidValidity" )) - svars->uidval[S] = t1; + svars->uidval[S] = uid; else if (!strcmp( buf1, "MaxPulledUid" )) - svars->maxuid[M] = t1; + svars->maxuid[M] = uid; else if (!strcmp( buf1, "MaxPushedUid" )) - svars->maxuid[S] = t1; - else if (!strcmp( buf1, "MaxExpiredSlaveUid" )) - svars->smaxxuid = t1; + svars->maxuid[S] = uid; + else if (!strcmp( buf1, "MaxExpiredMasterUid" )) + svars->mmaxxuid = uid; + else if (!strcmp( buf1, "MaxExpiredSlaveUid" )) // Legacy + smaxxuid = uid; else { error( "Error: unrecognized sync state header entry at %s:%d\n", svars->dname, line ); goto jbail; @@ -757,12 +748,14 @@ gothdr: while (fgets( buf, sizeof(buf), jfp )) { line++; - if (!(t = strlen( buf )) || buf[t - 1] != '\n') { + if (!(ll = strlen( buf )) || buf[--ll] != '\n') { error( "Error: incomplete sync state entry at %s:%d\n", svars->dname, line ); goto jbail; } + buf[ll] = 0; fbuf[0] = 0; - if (sscanf( buf, "%d %d %15s", &t1, &t2, fbuf ) < 2) { + uint t1, t2; + if (sscanf( buf, "%u %u %15s", &t1, &t2, fbuf ) < 2) { error( "Error: invalid sync state entry at %s:%d\n", svars->dname, line ); goto jbail; } @@ -770,13 +763,33 @@ srec->uid[M] = t1; srec->uid[S] = t2; s = fbuf; - if (*s == 'X') { + if (*s == '^') { + s++; + srec->status = S_SKIPPED; + } else if (*s == '!') { + s++; + srec->status = S_PENDING; + } else if (*s == '~' || *s == 'X' /* Pre-1.3 legacy */) { s++; srec->status = S_EXPIRE | S_EXPIRED; + } else if (srec->uid[M] == (uint)-1) { // Pre-1.3 legacy + srec->uid[M] = 0; + srec->status = S_SKIPPED; + } else if (srec->uid[M] == (uint)-2) { + srec->uid[M] = 0; + srec->status = S_PENDING; + } else if (srec->uid[S] == (uint)-1) { + srec->uid[S] = 0; + srec->status = S_SKIPPED; + } else if (srec->uid[S] == (uint)-2) { + srec->uid[S] = 0; + srec->status = S_PENDING; } else srec->status = 0; + srec->wstate = 0; srec->flags = parse_flags( s ); - debug( " entry (%d,%d,%u,%s)\n", srec->uid[M], srec->uid[S], srec->flags, srec->status & S_EXPIRED ? "X" : "" ); + debug( " entry (%u,%u,%u,%s)\n", srec->uid[M], srec->uid[S], srec->flags, + (srec->status & S_SKIPPED) ? "SKIP" : (srec->status & S_PENDING) ? "FAIL" : (srec->status & S_EXPIRED) ? "XPIRE" : "" ); srec->msg[M] = srec->msg[S] = 0; srec->tuid[0] = 0; srec->next = 0; @@ -785,61 +798,94 @@ svars->nsrecs++; } fclose( jfp ); + svars->existing = 1; } else { if (errno != ENOENT) { - error( "Error: cannot read sync state %s\n", svars->dname ); - goto bail; + sys_error( "Error: cannot read sync state %s", svars->dname ); + return 0; } + svars->existing = 0; } + + // This is legacy support for pre-1.3 sync states. + if (smaxxuid) { + uint minwuid = UINT_MAX; + for (srec = svars->srecs; srec; srec = srec->next) { + if ((srec->status & (S_DEAD | S_SKIPPED | S_PENDING)) || !srec->uid[M]) + continue; + if (srec->status & S_EXPIRED) { + if (!srec->uid[S]) { + // The expired message was already gone. + continue; + } + // The expired message was not expunged yet, so re-examine it. + // This will happen en masse, so just extend the bulk fetch. + } else { + if (srec->uid[S] && smaxxuid >= srec->uid[S]) { + // The non-expired message is in the generally expired range, + // so don't make it contribute to the bulk fetch. + continue; + } + // Usual non-expired message. + } + if (minwuid > srec->uid[M]) + minwuid = srec->uid[M]; + } + svars->mmaxxuid = minwuid - 1; + } + svars->newmaxuid[M] = svars->maxuid[M]; svars->newmaxuid[S] = svars->maxuid[S]; - svars->mmaxxuid = INT_MAX; - line = 0; + int line = 0; if ((jfp = fopen( svars->jname, "r" ))) { + if (!lock_state( svars )) + goto jbail; if (!stat( svars->nname, &st ) && fgets( buf, sizeof(buf), jfp )) { debug( "recovering journal ...\n" ); - if (!(t = strlen( buf )) || buf[t - 1] != '\n') { + if (!(ll = strlen( buf )) || buf[--ll] != '\n') { error( "Error: incomplete journal header in %s\n", svars->jname ); goto jbail; } - if (memcmp( buf, JOURNAL_VERSION "\n", strlen(JOURNAL_VERSION) + 1 )) { + buf[ll] = 0; + if (!equals( buf, ll, JOURNAL_VERSION, strlen(JOURNAL_VERSION) )) { error( "Error: incompatible journal version " - "(got %.*s, expected " JOURNAL_VERSION ")\n", t - 1, buf ); + "(got %s, expected " JOURNAL_VERSION ")\n", buf ); goto jbail; } srec = 0; line = 1; while (fgets( buf, sizeof(buf), jfp )) { line++; - if (!(t = strlen( buf )) || buf[t - 1] != '\n') { + if (!(ll = strlen( buf )) || buf[--ll] != '\n') { error( "Error: incomplete journal entry at %s:%d\n", svars->jname, line ); goto jbail; } - if (buf[0] == '#' ? - (t3 = 0, (sscanf( buf + 2, "%d %d %n", &t1, &t2, &t3 ) < 2) || !t3 || (t - t3 != TUIDL + 3)) : - buf[0] == '(' || buf[0] == ')' || buf[0] == '{' || buf[0] == '}' || buf[0] == '!' ? - (sscanf( buf + 2, "%d", &t1 ) != 1) : - buf[0] == '+' || buf[0] == '&' || buf[0] == '-' || buf[0] == '|' || buf[0] == '/' || buf[0] == '\\' ? - (sscanf( buf + 2, "%d %d", &t1, &t2 ) != 2) : - (sscanf( buf + 2, "%d %d %d", &t1, &t2, &t3 ) != 3)) + buf[ll] = 0; + int tn; + uint t1, t2, t3; + if ((c = buf[0]) == '#' ? + (tn = 0, (sscanf( buf + 2, "%u %u %n", &t1, &t2, &tn ) < 2) || !tn || (ll - tn != TUIDL + 2)) : + c == 'S' || c == '!' ? + (sscanf( buf + 2, "%u", &t1 ) != 1) : + c == 'F' || c == 'T' || c == '+' || c == '&' || c == '-' || c == '=' || c == '|' ? + (sscanf( buf + 2, "%u %u", &t1, &t2 ) != 2) : + (sscanf( buf + 2, "%u %u %u", &t1, &t2, &t3 ) != 3)) { error( "Error: malformed journal entry at %s:%d\n", svars->jname, line ); goto jbail; } - if (buf[0] == '(') - svars->maxuid[M] = t1; - else if (buf[0] == ')') - svars->maxuid[S] = t1; - else if (buf[0] == '{') - svars->newuid[M] = t1; - else if (buf[0] == '}') - svars->newuid[S] = t1; - else if (buf[0] == '!') - svars->smaxxuid = t1; - else if (buf[0] == '|') { + if (c == 'S') + svars->maxuid[t1] = svars->newmaxuid[t1]; + else if (c == 'F') + svars->newuid[t1] = t2; + else if (c == 'T') + *uint_array_append( &svars->trashed_msgs[t1] ) = t2; + else if (c == '!') + svars->mmaxxuid = t1; + else if (c == '|') { svars->uidval[M] = t1; svars->uidval[S] = t2; - } else if (buf[0] == '+') { + } else if (c == '+') { srec = nfmalloc( sizeof(*srec) ); srec->uid[M] = t1; srec->uid[S] = t2; @@ -847,9 +893,10 @@ svars->newmaxuid[M] = t1; if (svars->newmaxuid[S] < t2) svars->newmaxuid[S] = t2; - debug( " new entry(%d,%d)\n", t1, t2 ); + debug( " new entry(%u,%u)\n", t1, t2 ); srec->msg[M] = srec->msg[S] = 0; - srec->status = 0; + srec->status = S_PENDING; + srec->wstate = 0; srec->flags = 0; srec->tuid[0] = 0; srec->next = 0; @@ -866,17 +913,20 @@ error( "Error: journal entry at %s:%d refers to non-existing sync state entry\n", svars->jname, line ); goto jbail; syncfnd: - debugn( " entry(%d,%d,%u) ", srec->uid[M], srec->uid[S], srec->flags ); - switch (buf[0]) { + debugn( " entry(%u,%u,%u) ", srec->uid[M], srec->uid[S], srec->flags ); + switch (c) { case '-': debug( "killed\n" ); - if (srec->msg[M]) - srec->msg[M]->srec = 0; + srec->status = S_DEAD; + break; + case '=': + debug( "aborted\n" ); + svars->mmaxxuid = srec->uid[M]; srec->status = S_DEAD; break; case '#': - debug( "TUID now %." stringify(TUIDL) "s\n", buf + t3 + 2 ); - memcpy( srec->tuid, buf + t3 + 2, TUIDL ); + memcpy( srec->tuid, buf + tn + 2, TUIDL ); + debug( "TUID now %." stringify(TUIDL) "s\n", srec->tuid ); break; case '&': debug( "TUID %." stringify(TUIDL) "s lost\n", srec->tuid ); @@ -884,43 +934,24 @@ srec->tuid[0] = 0; break; case '<': - debug( "master now %d\n", t3 ); + debug( "master now %u\n", t3 ); srec->uid[M] = t3; + srec->status &= ~S_PENDING; srec->tuid[0] = 0; break; case '>': - debug( "slave now %d\n", t3 ); + debug( "slave now %u\n", t3 ); srec->uid[S] = t3; + srec->status &= ~S_PENDING; srec->tuid[0] = 0; break; case '*': - debug( "flags now %d\n", t3 ); + debug( "flags now %u\n", t3 ); srec->flags = t3; break; case '~': - debug( "expire now %d\n", t3 ); - if (t3) - srec->status |= S_EXPIRE; - else - srec->status &= ~S_EXPIRE; - break; - case '\\': - t3 = (srec->status & S_EXPIRED); - debug( "expire back to %d\n", t3 / S_EXPIRED ); - if (t3) - srec->status |= S_EXPIRE; - else - srec->status &= ~S_EXPIRE; - break; - case '/': - t3 = (srec->status & S_EXPIRE); - debug( "expired now %d\n", t3 / S_EXPIRE ); - if (t3) { - if (svars->smaxxuid < srec->uid[S]) - svars->smaxxuid = srec->uid[S]; - srec->status |= S_EXPIRED; - } else - srec->status &= ~S_EXPIRED; + debug( "status now %#x\n", t3 ); + srec->status = t3; break; default: error( "Error: unrecognized journal entry at %s:%d\n", svars->jname, line ); @@ -932,35 +963,278 @@ fclose( jfp ); } else { if (errno != ENOENT) { - error( "Error: cannot read journal %s\n", svars->jname ); - goto bail; + sys_error( "Error: cannot read journal %s", svars->jname ); + return 0; } } + svars->replayed = line; - t1 = 0; - for (t = 0; t < 2; t++) - if (svars->uidval[t] >= 0 && svars->uidval[t] != ctx[t]->uidvalidity) { - error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", - str_ms[t], ctx[t]->uidvalidity, svars->uidval[t] ); - t1++; + return 1; +} + +static void +delete_state( sync_vars_t *svars ) +{ + unlink( svars->nname ); + unlink( svars->jname ); + if (unlink( svars->dname ) || unlink( svars->lname )) { + sys_error( "Error: channel %s: sync state cannot be deleted", svars->chan->name ); + svars->ret = SYNC_FAIL; + } +} + +static void box_confirmed( int sts, int uidvalidity, void *aux ); +static void box_confirmed2( sync_vars_t *svars, int t ); +static void box_deleted( int sts, void *aux ); +static void box_created( int sts, void *aux ); +static void box_opened( int sts, int uidvalidity, void *aux ); +static void box_opened2( sync_vars_t *svars, int t ); +static void load_box( sync_vars_t *svars, int t, uint minwuid, uint_array_t mexcs ); + +void +sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t *chan, + void (*cb)( int sts, void *aux ), void *aux ) +{ + sync_vars_t *svars; + int t; + + svars = nfcalloc( sizeof(*svars) ); + svars->t[1] = 1; + svars->ref_count = 1; + svars->cb = cb; + svars->aux = aux; + svars->ctx[0] = ctx[0]; + svars->ctx[1] = ctx[1]; + svars->chan = chan; + svars->lfd = -1; + svars->uidval[0] = svars->uidval[1] = UIDVAL_BAD; + svars->srecadd = &svars->srecs; + + for (t = 0; t < 2; t++) { + svars->orig_name[t] = + (!names[t] || (ctx[t]->conf->map_inbox && !strcmp( ctx[t]->conf->map_inbox, names[t] ))) ? + "INBOX" : names[t]; + if (!ctx[t]->conf->flat_delim) { + svars->box_name[t] = nfstrdup( svars->orig_name[t] ); + } else if (map_name( svars->orig_name[t], &svars->box_name[t], 0, "/", ctx[t]->conf->flat_delim ) < 0) { + error( "Error: canonical mailbox name '%s' contains flattened hierarchy delimiter\n", svars->orig_name[t] ); + bail3: + svars->ret = SYNC_FAIL; + sync_bail3( svars ); + return; } - if (t1) - goto bail; + svars->drv[t] = ctx[t]->driver; + svars->drv[t]->set_bad_callback( ctx[t], store_bad, AUX ); + } + /* Both boxes must be fully set up at this point, so that error exit paths + * don't run into uninitialized variables. */ + for (t = 0; t < 2; t++) { + switch (svars->drv[t]->select_box( ctx[t], svars->box_name[t] )) { + case DRV_CANCELED: + store_bad( AUX ); + return; + case DRV_BOX_BAD: + goto bail3; + } + } + + if (!prepare_state( svars )) { + svars->ret = SYNC_FAIL; + sync_bail2( svars ); + return; + } + if (!load_state( svars )) { + svars->ret = SYNC_FAIL; + sync_bail( svars ); + return; + } + + sync_ref( svars ); + for (t = 0; ; t++) { + info( "Opening %s box %s...\n", str_ms[t], svars->orig_name[t] ); + if (present[t] == BOX_ABSENT) + box_confirmed2( svars, t ); + else + svars->drv[t]->open_box( ctx[t], box_confirmed, AUX ); + if (t || check_cancel( svars )) + break; + } + sync_deref( svars ); +} +static void +box_confirmed( int sts, int uidvalidity, void *aux ) +{ + DECL_SVARS; + + if (sts == DRV_CANCELED) + return; + INIT_SVARS(aux); + if (check_cancel( svars )) + return; + + if (sts == DRV_OK) { + svars->state[t] |= ST_PRESENT; + svars->newuidval[t] = uidvalidity; + } + box_confirmed2( svars, t ); +} + +static void +box_confirmed2( sync_vars_t *svars, int t ) +{ + svars->state[t] |= ST_CONFIRMED; + if (!(svars->state[1-t] & ST_CONFIRMED)) + return; + + sync_ref( svars ); + for (t = 0; ; t++) { + if (!(svars->state[t] & ST_PRESENT)) { + if (!(svars->state[1-t] & ST_PRESENT)) { + if (!svars->existing) { + error( "Error: channel %s: both master %s and slave %s cannot be opened.\n", + svars->chan->name, svars->orig_name[M], svars->orig_name[S] ); + bail: + svars->ret = SYNC_FAIL; + } else { + /* This can legitimately happen if a deletion propagation was interrupted. + * We have no place to record this transaction, so we just assume it. + * Of course this bears the danger of clearing the state if both mailboxes + * temorarily cannot be opened for some weird reason (while the stores can). */ + delete_state( svars ); + } + done: + sync_bail( svars ); + break; + } + if (svars->existing) { + if (!(svars->chan->ops[1-t] & OP_REMOVE)) { + error( "Error: channel %s: %s %s cannot be opened.\n", + svars->chan->name, str_ms[t], svars->orig_name[t] ); + goto bail; + } + if (svars->drv[1-t]->confirm_box_empty( svars->ctx[1-t] ) != DRV_OK) { + warn( "Warning: channel %s: %s %s cannot be opened and %s %s not empty.\n", + svars->chan->name, str_ms[t], svars->orig_name[t], str_ms[1-t], svars->orig_name[1-t] ); + goto done; + } + info( "Deleting %s %s...\n", str_ms[1-t], svars->orig_name[1-t] ); + svars->drv[1-t]->delete_box( svars->ctx[1-t], box_deleted, INV_AUX ); + } else { + if (!(svars->chan->ops[t] & OP_CREATE)) { + box_opened( DRV_BOX_BAD, UIDVAL_BAD, AUX ); + } else { + info( "Creating %s %s...\n", str_ms[t], svars->orig_name[t] ); + svars->drv[t]->create_box( svars->ctx[t], box_created, AUX ); + } + } + } else { + box_opened2( svars, t ); + } + if (t || check_cancel( svars )) + break; + } + sync_deref( svars ); +} + +static void +box_deleted( int sts, void *aux ) +{ + DECL_SVARS; + + if (check_ret( sts, aux )) + return; + INIT_SVARS(aux); + + delete_state( svars ); + svars->drv[t]->finish_delete_box( svars->ctx[t] ); + sync_bail( svars ); +} + +static void +box_created( int sts, void *aux ) +{ + DECL_SVARS; + + if (check_ret( sts, aux )) + return; + INIT_SVARS(aux); + + svars->drv[t]->open_box( svars->ctx[t], box_opened, AUX ); +} + +static void +box_opened( int sts, int uidvalidity, void *aux ) +{ + DECL_SVARS; + + if (sts == DRV_CANCELED) + return; + INIT_SVARS(aux); + if (check_cancel( svars )) + return; + + if (sts == DRV_BOX_BAD) { + error( "Error: channel %s: %s %s cannot be opened.\n", + svars->chan->name, str_ms[t], svars->orig_name[t] ); + svars->ret = SYNC_FAIL; + sync_bail( svars ); + } else { + svars->newuidval[t] = uidvalidity; + box_opened2( svars, t ); + } +} + +static void +box_opened2( sync_vars_t *svars, int t ) +{ + store_t *ctx[2]; + channel_conf_t *chan; + sync_rec_t *srec; + uint_array_alloc_t mexcs; + uint minwuid; + int opts[2], fails; + + svars->state[t] |= ST_SELECTED; + if (!(svars->state[1-t] & ST_SELECTED)) + return; + ctx[0] = svars->ctx[0]; + ctx[1] = svars->ctx[1]; + chan = svars->chan; + + fails = 0; + for (t = 0; t < 2; t++) + if (svars->uidval[t] != UIDVAL_BAD && svars->uidval[t] != svars->newuidval[t]) + fails++; + if (fails == 2) { + error( "Error: channel %s: UIDVALIDITY of both master and slave changed\n" + "(master got %u, expected %u; slave got %u, expected %u).\n", + svars->chan->name, + svars->newuidval[M], svars->uidval[M], svars->newuidval[S], svars->uidval[S] ); + bail: + svars->ret = SYNC_FAIL; + sync_bail( svars ); + return; + } + + if (!lock_state( svars )) + goto bail; if (!(svars->nfp = fopen( svars->nname, "w" ))) { - error( "Error: cannot write new sync state %s\n", svars->nname ); + sys_error( "Error: cannot create new sync state %s", svars->nname ); goto bail; } if (!(svars->jfp = fopen( svars->jname, "a" ))) { - error( "Error: cannot write journal %s\n", svars->jname ); + sys_error( "Error: cannot create journal %s", svars->jname ); fclose( svars->nfp ); goto bail; } setlinebuf( svars->jfp ); - if (!line) - Fprintf( svars->jfp, JOURNAL_VERSION "\n" ); + if (!svars->replayed) + jFprintf( svars, JOURNAL_VERSION "\n" ); opts[M] = opts[S] = 0; + if (fails) + opts[M] = opts[S] = OPEN_OLD|OPEN_OLD_IDS; for (t = 0; t < 2; t++) { if (chan->ops[t] & (OP_DELETE|OP_FLAGS)) { opts[t] |= OPEN_SETFLAGS; @@ -976,8 +1250,12 @@ opts[1-t] |= OPEN_NEW; if (chan->ops[t] & OP_EXPUNGE) opts[1-t] |= OPEN_FLAGS; - if (chan->stores[t]->max_size != INT_MAX) - opts[1-t] |= OPEN_SIZE; + if (chan->stores[t]->max_size != INT_MAX) { + if (chan->ops[t] & OP_RENEW) + opts[1-t] |= OPEN_OLD_SIZE; + if (chan->ops[t] & OP_NEW) + opts[1-t] |= OPEN_NEW_SIZE; + } } if (chan->ops[t] & OP_EXPUNGE) { opts[t] |= OPEN_EXPUNGE; @@ -991,107 +1269,94 @@ } if ((chan->ops[S] & (OP_NEW|OP_RENEW|OP_FLAGS)) && chan->max_messages) opts[S] |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; - if (line) + if (svars->replayed) for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; if (srec->tuid[0]) { - if (srec->uid[M] == -2) + if (!srec->uid[M]) opts[M] |= OPEN_NEW|OPEN_FIND, svars->state[M] |= ST_FIND_OLD; - else if (srec->uid[S] == -2) + else if (!srec->uid[S]) opts[S] |= OPEN_NEW|OPEN_FIND, svars->state[S] |= ST_FIND_OLD; else assert( !"sync record with stray TUID" ); } } - svars->drv[M]->prepare_opts( ctx[M], opts[M] ); - svars->drv[S]->prepare_opts( ctx[S], opts[S] ); + svars->opts[M] = svars->drv[M]->prepare_load_box( ctx[M], opts[M] ); + svars->opts[S] = svars->drv[S]->prepare_load_box( ctx[S], opts[S] ); - mexcs = 0; - nmexcs = rmexcs = 0; - if (svars->ctx[M]->opts & OPEN_OLD) { + ARRAY_INIT( &mexcs ); + if (svars->opts[M] & OPEN_OLD) { if (chan->max_messages) { /* When messages have been expired on the slave, the master fetch is split into * two ranges: The bulk fetch which corresponds with the most recent messages, and an * exception list of messages which would have been expired if they weren't important. */ - debug( "preparing master selection - max expired slave uid is %d\n", svars->smaxxuid ); + debug( "preparing master selection - max expired master uid is %u\n", svars->mmaxxuid ); /* First, find out the lower bound for the bulk fetch. */ - minwuid = INT_MAX; - for (srec = svars->srecs; srec; srec = srec->next) { - if ((srec->status & S_DEAD) || srec->uid[M] <= 0) - continue; - if (srec->status & S_EXPIRED) { - if (!srec->uid[S]) { - /* The expired message was already gone. */ - continue; - } - /* The expired message was not expunged yet, so re-examine it. - * This will happen en masse, so just extend the bulk fetch. */ - } else { - if (svars->smaxxuid >= srec->uid[S]) { - /* The non-expired message is in the generally expired range, so don't - * make it contribute to the bulk fetch. */ - continue; - } - /* Usual non-expired message. */ - } - if (minwuid > srec->uid[M]) - minwuid = srec->uid[M]; - } - debug( " min non-orphaned master uid is %d\n", minwuid ); + minwuid = svars->mmaxxuid + 1; /* Next, calculate the exception fetch. */ for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; - if (srec->uid[M] > 0 && srec->uid[S] > 0 && minwuid > srec->uid[M] && - (!(svars->ctx[M]->opts & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) { + if (!srec->uid[M]) // No message; other state is irrelevant + continue; + if (minwuid > srec->uid[M] && (!(svars->opts[M] & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) { + if (!srec->uid[S] && !(srec->status & S_PENDING)) // Only actually paired up messages matter + continue; /* The pair is alive, but outside the bulk range. */ - if (nmexcs == rmexcs) { - rmexcs = rmexcs * 2 + 100; - mexcs = nfrealloc( mexcs, rmexcs * sizeof(int) ); - } - mexcs[nmexcs++] = srec->uid[M]; + *uint_array_append( &mexcs ) = srec->uid[M]; } } - debugn( " exception list is:" ); - for (t = 0; t < nmexcs; t++) - debugn( " %d", mexcs[t] ); - debug( "\n" ); + sort_uint_array( mexcs.array ); } else { minwuid = 1; } } else { - minwuid = INT_MAX; + minwuid = UINT_MAX; } sync_ref( svars ); - load_box( svars, M, minwuid, mexcs, nmexcs ); + load_box( svars, M, minwuid, mexcs.array ); if (!check_cancel( svars )) - load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 ); + load_box( svars, S, (svars->opts[S] & OPEN_OLD) ? 1 : UINT_MAX, (uint_array_t){ 0, 0 } ); sync_deref( svars ); } -static void box_loaded( int sts, void *aux ); +static int +get_seenuid( sync_vars_t *svars, int t ) +{ + uint seenuid = 0; + for (sync_rec_t *srec = svars->srecs; srec; srec = srec->next) + if (!(srec->status & S_DEAD) && seenuid < srec->uid[t]) + seenuid = srec->uid[t]; + return seenuid; +} + +static void box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ); static void -load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) +load_box( sync_vars_t *svars, int t, uint minwuid, uint_array_t mexcs ) { - sync_rec_t *srec; - int maxwuid; + uint maxwuid, seenuid; - if (svars->ctx[t]->opts & OPEN_NEW) { + if (svars->opts[t] & OPEN_NEW) { if (minwuid > svars->maxuid[t] + 1) minwuid = svars->maxuid[t] + 1; - maxwuid = INT_MAX; - } else if (svars->ctx[t]->opts & OPEN_OLD) { - maxwuid = 0; - for (srec = svars->srecs; srec; srec = srec->next) - if (!(srec->status & S_DEAD) && srec->uid[t] > maxwuid) - maxwuid = srec->uid[t]; + maxwuid = UINT_MAX; + if (svars->opts[t] & (OPEN_OLD_IDS|OPEN_OLD_SIZE)) + seenuid = get_seenuid( svars, t ); + else + seenuid = 0; + } else if (svars->opts[t] & OPEN_OLD) { + maxwuid = seenuid = get_seenuid( svars, t ); } else - maxwuid = 0; + maxwuid = seenuid = 0; + if (seenuid < svars->maxuid[t]) { + /* We cannot rely on the maxuid, as uni-directional syncing does not update it. + * But if it is there, use it to avoid a possible gap in the fetched range. */ + seenuid = svars->maxuid[t]; + } info( "Loading %s...\n", str_ms[t] ); - debug( maxwuid == INT_MAX ? "loading %s [%d,inf]\n" : "loading %s [%d,%d]\n", str_ms[t], minwuid, maxwuid ); - svars->drv[t]->load( svars->ctx[t], minwuid, maxwuid, svars->newuid[t], mexcs, nmexcs, box_loaded, AUX ); + svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, svars->newuid[t], seenuid, mexcs, box_loaded, AUX ); } typedef struct { @@ -1101,40 +1366,38 @@ } flag_vars_t; typedef struct { - int uid; + uint uid; sync_rec_t *srec; } sync_rec_map_t; static void flags_set( int sts, void *aux ); static void flags_set_p2( sync_vars_t *svars, sync_rec_t *srec, int t ); static void msgs_flags_set( sync_vars_t *svars, int t ); -static void msg_copied( int sts, int uid, copy_vars_t *vars ); -static void msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, int uid ); +static void msg_copied( int sts, uint uid, copy_vars_t *vars ); static void msgs_copied( sync_vars_t *svars, int t ); static void -box_loaded( int sts, void *aux ) +box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ) { DECL_SVARS; sync_rec_t *srec; sync_rec_map_t *srecmap; message_t *tmsg; - copy_vars_t *cv; flag_vars_t *fv; - int uid, no[2], del[2], alive, todel, t1, t2; - int sflags, nflags, aflags, dflags, nex; - unsigned hashsz, idx; - char fbuf[16]; /* enlarge when support for keywords is added */ + int no[2], del[2], alive, todel; + int sflags, nflags, aflags, dflags; + uint hashsz, idx; if (check_ret( sts, aux )) return; INIT_SVARS(aux); svars->state[t] |= ST_LOADED; - info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, svars->ctx[t]->recent ); + svars->msgs[t] = msgs; + info( "%s: %d messages, %d recent\n", str_ms[t], total_msgs, recent_msgs ); if (svars->state[t] & ST_FIND_OLD) { debug( "matching previously copied messages on %s\n", str_ms[t] ); - match_tuids( svars, t ); + match_tuids( svars, t, msgs ); } debug( "matching messages on %s against sync records\n", str_ms[t] ); @@ -1143,23 +1406,21 @@ for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; - uid = srec->uid[t]; - idx = (unsigned)((unsigned)uid * 1103515245U) % hashsz; + uint uid = srec->uid[t]; + if (!uid) + continue; + idx = (uint)(uid * 1103515245U) % hashsz; while (srecmap[idx].uid) if (++idx == hashsz) idx = 0; srecmap[idx].uid = uid; srecmap[idx].srec = srec; } - for (tmsg = svars->ctx[t]->msgs; tmsg; tmsg = tmsg->next) { + for (tmsg = svars->msgs[t]; tmsg; tmsg = tmsg->next) { if (tmsg->srec) /* found by TUID */ continue; - uid = tmsg->uid; - if (DFlags & DEBUG) { - make_flags( tmsg->flags, fbuf ); - printf( svars->ctx[t]->opts & OPEN_SIZE ? " message %5d, %-4s, %6lu: " : " message %5d, %-4s: ", uid, fbuf, tmsg->size ); - } - idx = (unsigned)((unsigned)uid * 1103515245U) % hashsz; + uint uid = tmsg->uid; + idx = (uint)(uid * 1103515245U) % hashsz; while (srecmap[idx].uid) { if (srecmap[idx].uid == uid) { srec = srecmap[idx].srec; @@ -1168,22 +1429,61 @@ if (++idx == hashsz) idx = 0; } - debug( "new\n" ); continue; found: tmsg->srec = srec; srec->msg[t] = tmsg; - debug( "pairs %5d\n", srec->uid[1-t] ); } free( srecmap ); if (!(svars->state[1-t] & ST_LOADED)) return; - if (svars->uidval[M] < 0 || svars->uidval[S] < 0) { - svars->uidval[M] = svars->ctx[M]->uidvalidity; - svars->uidval[S] = svars->ctx[S]->uidvalidity; - Fprintf( svars->jfp, "| %d %d\n", svars->uidval[M], svars->uidval[S] ); + for (t = 0; t < 2; t++) { + if (svars->uidval[t] != UIDVAL_BAD && svars->uidval[t] != svars->newuidval[t]) { + unsigned need = 0, got = 0; + debug( "trying to re-approve uid validity of %s\n", str_ms[t] ); + for (srec = svars->srecs; srec; srec = srec->next) { + if (srec->status & S_DEAD) + continue; + if (!srec->msg[t]) + continue; // Message disappeared. + need++; // Present paired messages require re-validation. + if (!srec->msg[t]->msgid) + continue; // Messages without ID are useless for re-validation. + if (!srec->msg[1-t]) + continue; // Partner disappeared. + if (!srec->msg[1-t]->msgid || strcmp( srec->msg[M]->msgid, srec->msg[S]->msgid )) { + error( "Error: channel %s, %s %s: UIDVALIDITY genuinely changed (at UID %u).\n", + svars->chan->name, str_ms[t], svars->orig_name[t], srec->uid[t] ); + uvchg: + svars->ret |= SYNC_FAIL; + cancel_sync( svars ); + return; + } + got++; + } + if (got < 20 && got * 5 < need * 4) { + // Too few confirmed messages. This is very likely in the drafts folder. + // A proper fallback would be fetching more headers (which potentially need + // normalization) or the message body (which should be truncated for sanity) + // and comparing. + error( "Error: channel %s, %s %s: Unable to recover from UIDVALIDITY change\n" + "(got %u, expected %u).\n", + svars->chan->name, str_ms[t], svars->orig_name[t], + svars->newuidval[t], svars->uidval[t] ); + goto uvchg; + } + notice( "Notice: channel %s, %s %s: Recovered from change of UIDVALIDITY.\n", + svars->chan->name, str_ms[t], svars->orig_name[t] ); + svars->uidval[t] = UIDVAL_BAD; + } + } + + if (svars->uidval[M] == UIDVAL_BAD || svars->uidval[S] == UIDVAL_BAD) { + svars->uidval[M] = svars->newuidval[M]; + svars->uidval[S] = svars->newuidval[S]; + jFprintf( svars, "| %u %u\n", svars->uidval[M], svars->uidval[S] ); } info( "Synchronizing...\n" ); @@ -1192,52 +1492,60 @@ for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; - debug( "pair (%d,%d)\n", srec->uid[M], srec->uid[S] ); - no[M] = !srec->msg[M] && (svars->ctx[M]->opts & OPEN_OLD); - no[S] = !srec->msg[S] && (svars->ctx[S]->opts & OPEN_OLD); + debug( "pair (%u,%u)\n", srec->uid[M], srec->uid[S] ); + assert( !srec->tuid[0] ); + // no[] means that a message is known to be not there. + no[M] = !srec->msg[M] && (svars->opts[M] & OPEN_OLD); + no[S] = !srec->msg[S] && (svars->opts[S] & OPEN_OLD); if (no[M] && no[S]) { + // It does not matter whether one side was already known to be missing + // (never stored [skipped or failed] or expunged [possibly expired]) - + // now both are missing, so the entry is superfluous. debug( " vanished\n" ); - /* d.1) d.5) d.6) d.10) d.11) */ srec->status = S_DEAD; - Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] ); + jFprintf( svars, "- %u %u\n", srec->uid[M], srec->uid[S] ); } else { - del[M] = no[M] && (srec->uid[M] > 0); - del[S] = no[S] && (srec->uid[S] > 0); + // del[] means that a message becomes known to have been expunged. + del[M] = no[M] && srec->uid[M]; + del[S] = no[S] && srec->uid[S]; for (t = 0; t < 2; t++) { srec->aflags[t] = srec->dflags[t] = 0; if (srec->msg[t] && (srec->msg[t]->flags & F_DELETED)) - srec->status |= S_DEL(t); - /* excludes (push) c.3) d.2) d.3) d.4) / (pull) b.3) d.7) d.8) d.9) */ - if (!srec->uid[t]) { - /* b.1) / c.1) */ - debug( " no more %s\n", str_ms[t] ); + srec->wstate |= W_DEL(t); + if (del[t]) { + // The target was newly expunged, so there is nothing to update. + // The deletion is propagated in the opposite iteration. + } else if (!srec->uid[t]) { + // The target was never stored, or was previously expunged, so there + // is nothing to update. + // Note: the opposite UID must be valid, as otherwise the entry would + // have been pruned already. } else if (del[1-t]) { - /* c.4) d.9) / b.4) d.4) */ + // The source was newly expunged, so possibly propagate the deletion. + // The target may be in an unknown state (not fetched). if ((t == M) && (srec->status & (S_EXPIRE|S_EXPIRED))) { /* Don't propagate deletion resulting from expiration. */ debug( " slave expired, orphaning master\n" ); - Fprintf( svars->jfp, "> %d %d 0\n", srec->uid[M], srec->uid[S] ); + jFprintf( svars, "> %u %u 0\n", srec->uid[M], srec->uid[S] ); srec->uid[S] = 0; } else { if (srec->msg[t] && (srec->msg[t]->status & M_FLAGS) && srec->msg[t]->flags != srec->flags) - info( "Info: conflicting changes in (%d,%d)\n", srec->uid[M], srec->uid[S] ); + notice( "Notice: conflicting changes in (%u,%u)\n", srec->uid[M], srec->uid[S] ); if (svars->chan->ops[t] & OP_DELETE) { debug( " %sing delete\n", str_hl[t] ); srec->aflags[t] = F_DELETED; - srec->status |= S_DELETE; + srec->wstate |= W_DELETE; } else { debug( " not %sing delete\n", str_hl[t] ); } } - } else if (!srec->msg[1-t]) - /* c.1) c.2) d.7) d.8) / b.1) b.2) d.2) d.3) */ - ; - else if (srec->uid[t] < 0) - /* b.2) / c.2) */ - ; /* handled as new messages (sort of) */ - else if (!del[t]) { - /* a) & b.3) / c.3) */ + } else if (!srec->msg[1-t]) { + // We have no source to work with, because it was never stored, + // it was previously expunged, or we did not fetch it. + debug( " no %s\n", str_ms[1-t] ); + } else { + // We have a source. The target may be in an unknown state. if (svars->chan->ops[t] & OP_FLAGS) { sflags = srec->msg[1-t]->flags; if ((t == M) && (srec->status & (S_EXPIRE|S_EXPIRED))) { @@ -1247,83 +1555,82 @@ } srec->aflags[t] = sflags & ~srec->flags; srec->dflags[t] = ~sflags & srec->flags; - if (DFlags & DEBUG) { + if ((DFlags & DEBUG_SYNC) && (srec->aflags[t] || srec->dflags[t])) { char afbuf[16], dfbuf[16]; /* enlarge when support for keywords is added */ make_flags( srec->aflags[t], afbuf ); make_flags( srec->dflags[t], dfbuf ); debug( " %sing flags: +%s -%s\n", str_hl[t], afbuf, dfbuf ); } - } else - debug( " not %sing flags\n", str_hl[t] ); - } /* else b.4) / c.4) */ + } + } } } } debug( "synchronizing new entries\n" ); for (t = 0; t < 2; t++) { - for (tmsg = svars->ctx[1-t]->msgs; tmsg; tmsg = tmsg->next) { - /* If we have a srec: - * - message is old (> 0) or expired (0) => ignore - * - message was skipped (-1) => ReNew - * - message was attempted, but failed (-2) => New - * If new have no srec, the message is always New. If messages were previously ignored - * due to being excessive, they would now appear to be newer than the messages that - * got actually synced, so make sure to look only at the newest ones. As some messages - * may be already propagated before an interruption, and maxuid logging is delayed, - * we need to track the newmaxuid separately. */ + for (tmsg = svars->msgs[1-t]; tmsg; tmsg = tmsg->next) { + // If new have no srec, the message is always New. If we have a srec: + // - message is paired or expired => ignore + // - message was skipped => ReNew + // - message was attempted, but is still pending or failed => New + // + // If messages were previously ignored due to being excessive, they would now + // appear to be newer than the messages that got actually synced, so increment + // newmaxuid immediately to make sure we always look only at the newest ones. + // However, committing it to maxuid must be delayed until all messages were + // propagated, to ensure that all pending messages are still loaded next time + // in case of interruption - in particular skipping big messages would otherwise + // up the limit too early. srec = tmsg->srec; - if (srec ? srec->uid[t] < 0 && (svars->chan->ops[t] & (srec->uid[t] == -1 ? OP_RENEW : OP_NEW)) + if (srec ? !srec->uid[t] && + (((srec->status & S_PENDING) && (svars->chan->ops[t] & OP_NEW)) || + ((srec->status & S_SKIPPED) && (svars->chan->ops[t] & OP_RENEW))) : svars->newmaxuid[1-t] < tmsg->uid && (svars->chan->ops[t] & OP_NEW)) { - debug( "new message %d on %s\n", tmsg->uid, str_ms[1-t] ); + debug( "new message %u on %s\n", tmsg->uid, str_ms[1-t] ); if ((svars->chan->ops[t] & OP_EXPUNGE) && (tmsg->flags & F_DELETED)) { debug( " -> not %sing - would be expunged anyway\n", str_hl[t] ); } else { if (srec) { - debug( " -> pair(%d,%d) exists\n", srec->uid[M], srec->uid[S] ); + debug( " -> pair(%u,%u) exists\n", srec->uid[M], srec->uid[S] ); } else { srec = nfmalloc( sizeof(*srec) ); srec->next = 0; *svars->srecadd = srec; svars->srecadd = &srec->next; svars->nsrecs++; - srec->status = 0; + srec->status = S_PENDING; + srec->wstate = 0; srec->flags = 0; srec->tuid[0] = 0; srec->uid[1-t] = tmsg->uid; - srec->uid[t] = -2; + srec->uid[t] = 0; srec->msg[1-t] = tmsg; srec->msg[t] = 0; tmsg->srec = srec; if (svars->newmaxuid[1-t] < tmsg->uid) svars->newmaxuid[1-t] = tmsg->uid; - Fprintf( svars->jfp, "+ %d %d\n", srec->uid[M], srec->uid[S] ); - debug( " -> pair(%d,%d) created\n", srec->uid[M], srec->uid[S] ); - } - if (svars->maxuid[1-t] < tmsg->uid) { - /* We do this here for simplicity. However, logging must be delayed until - * all messages were propagated, as skipped messages could otherwise be - * logged before the propagation of messages with lower UIDs completes. */ - svars->maxuid[1-t] = tmsg->uid; + jFprintf( svars, "+ %u %u\n", srec->uid[M], srec->uid[S] ); + debug( " -> pair(%u,%u) created\n", srec->uid[M], srec->uid[S] ); } if ((tmsg->flags & F_FLAGGED) || tmsg->size <= svars->chan->stores[t]->max_size) { - if (tmsg->flags) { + if (tmsg->flags != srec->flags) { srec->flags = tmsg->flags; - Fprintf( svars->jfp, "* %d %d %u\n", srec->uid[M], srec->uid[S], srec->flags ); + jFprintf( svars, "* %u %u %u\n", srec->uid[M], srec->uid[S], srec->flags ); debug( " -> updated flags to %u\n", tmsg->flags ); } - for (t1 = 0; t1 < TUIDL; t1++) { - t2 = arc4_getbyte() & 0x3f; - srec->tuid[t1] = t2 < 26 ? t2 + 'A' : t2 < 52 ? t2 + 'a' - 26 : t2 < 62 ? t2 + '0' - 52 : t2 == 62 ? '+' : '/'; + if (srec->status != S_PENDING) { + debug( " -> not too big any more\n" ); + srec->status = S_PENDING; + jFprintf( svars, "~ %d %d %u\n", srec->uid[M], srec->uid[S], srec->status ); } - Fprintf( svars->jfp, "# %d %d %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid ); - debug( " -> %sing message, TUID %." stringify(TUIDL) "s\n", str_hl[t], srec->tuid ); } else { - if (srec->uid[t] == -1) { + if (srec->status == S_SKIPPED) { debug( " -> not %sing - still too big\n", str_hl[t] ); } else { debug( " -> not %sing - too big\n", str_hl[t] ); - msg_copied_p2( svars, srec, t, -1 ); + srec->status = S_SKIPPED; + jFprintf( svars, "~ %d %d %u\n", srec->uid[M], srec->uid[S], srec->status ); } } } @@ -1337,10 +1644,10 @@ * older than the first not expired message are not counted towards the total. */ debug( "preparing message expiration\n" ); alive = 0; - for (tmsg = svars->ctx[S]->msgs; tmsg; tmsg = tmsg->next) { + for (tmsg = svars->msgs[S]; tmsg; tmsg = tmsg->next) { if (tmsg->status & M_DEAD) continue; - if ((srec = tmsg->srec) && srec->uid[M] > 0 && + if ((srec = tmsg->srec) && srec->uid[M] && ((tmsg->flags | srec->aflags[S]) & ~srec->dflags[S] & F_DELETED) && !(srec->status & (S_EXPIRE|S_EXPIRED))) { /* Message was not propagated yet, or is deleted. */ @@ -1348,19 +1655,19 @@ alive++; } } - for (tmsg = svars->ctx[M]->msgs; tmsg; tmsg = tmsg->next) { - if ((srec = tmsg->srec) && srec->tuid[0] && !(tmsg->flags & F_DELETED)) + for (tmsg = svars->msgs[M]; tmsg; tmsg = tmsg->next) { + if ((srec = tmsg->srec) && (srec->status & S_PENDING) && !(tmsg->flags & F_DELETED)) alive++; } todel = alive - svars->chan->max_messages; debug( "%d alive messages, %d excess - expiring\n", alive, todel ); alive = 0; - for (tmsg = svars->ctx[S]->msgs; tmsg; tmsg = tmsg->next) { + for (tmsg = svars->msgs[S]; tmsg; tmsg = tmsg->next) { if (tmsg->status & M_DEAD) continue; - if (!(srec = tmsg->srec) || srec->uid[M] <= 0) { + if (!(srec = tmsg->srec) || !srec->uid[M]) { /* We did not push the message, so it must be kept. */ - debug( " old pair(%d,%d) unpropagated\n", srec->uid[M], srec->uid[S] ); + debug( " message %u unpropagated\n", tmsg->uid ); todel--; } else { nflags = (tmsg->flags | srec->aflags[S]) & ~srec->dflags[S]; @@ -1368,42 +1675,42 @@ /* The message is not deleted, or is already (being) expired. */ if ((nflags & F_FLAGGED) || !((nflags & F_SEEN) || ((void)(todel > 0 && alive++), svars->chan->expire_unread > 0))) { /* Important messages are always kept. */ - debug( " old pair(%d,%d) important\n", srec->uid[M], srec->uid[S] ); + debug( " old pair(%u,%u) important\n", srec->uid[M], srec->uid[S] ); todel--; } else if (todel > 0 || ((srec->status & (S_EXPIRE|S_EXPIRED)) == (S_EXPIRE|S_EXPIRED)) || ((srec->status & (S_EXPIRE|S_EXPIRED)) && (tmsg->flags & F_DELETED))) { /* The message is excess or was already (being) expired. */ - srec->status |= S_NEXPIRE; - debug( " old pair(%d,%d) expired\n", srec->uid[M], srec->uid[S] ); + srec->wstate |= W_NEXPIRE; + debug( " old pair(%u,%u) expired\n", srec->uid[M], srec->uid[S] ); + if (svars->mmaxxuid < srec->uid[M]) + svars->mmaxxuid = srec->uid[M]; todel--; } } } } - for (tmsg = svars->ctx[M]->msgs; tmsg; tmsg = tmsg->next) { - if ((srec = tmsg->srec) && srec->tuid[0]) { + for (tmsg = svars->msgs[M]; tmsg; tmsg = tmsg->next) { + if ((srec = tmsg->srec) && (srec->status & S_PENDING)) { nflags = tmsg->flags; if (!(nflags & F_DELETED)) { if ((nflags & F_FLAGGED) || !((nflags & F_SEEN) || ((void)(todel > 0 && alive++), svars->chan->expire_unread > 0))) { /* Important messages are always fetched. */ - debug( " new pair(%d,%d) important\n", srec->uid[M], srec->uid[S] ); + debug( " new pair(%u,%u) important\n", srec->uid[M], srec->uid[S] ); todel--; } else if (todel > 0) { /* The message is excess. */ - srec->status |= S_NEXPIRE; - debug( " new pair(%d,%d) expired\n", srec->uid[M], srec->uid[S] ); - svars->mmaxxuid = srec->uid[M]; + srec->wstate |= W_NEXPIRE; todel--; } } } } debug( "%d excess messages remain\n", todel ); - if (svars->chan->expire_unread < 0 && (unsigned)alive * 2 > svars->chan->max_messages) { + if (svars->chan->expire_unread < 0 && (uint)alive * 2 > svars->chan->max_messages) { error( "%s: %d unread messages in excess of MaxMessages (%d).\n" "Please set ExpireUnread to decide outcome. Skipping mailbox.\n", - svars->ctx[S]->orig_name, alive, svars->chan->max_messages ); + svars->orig_name[S], alive, svars->chan->max_messages ); svars->ret |= SYNC_FAIL; cancel_sync( svars ); return; @@ -1411,29 +1718,33 @@ for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; - if (!srec->tuid[0]) { + if (!(srec->status & S_PENDING)) { if (!srec->msg[S]) continue; - nex = (srec->status / S_NEXPIRE) & 1; + uint nex = (srec->wstate / W_NEXPIRE) & 1; if (nex != ((srec->status / S_EXPIRED) & 1)) { /* The record needs a state change ... */ if (nex != ((srec->status / S_EXPIRE) & 1)) { /* ... and we need to start a transaction. */ - Fprintf( svars->jfp, "~ %d %d %d\n", srec->uid[M], srec->uid[S], nex ); - debug( " pair(%d,%d): %d (pre)\n", srec->uid[M], srec->uid[S], nex ); + debug( " pair(%u,%u): %u (pre)\n", srec->uid[M], srec->uid[S], nex ); srec->status = (srec->status & ~S_EXPIRE) | (nex * S_EXPIRE); + jFprintf( svars, "~ %u %u %u\n", srec->uid[M], srec->uid[S], srec->status ); } else { /* ... but the "right" transaction is already pending. */ - debug( " pair(%d,%d): %d (pending)\n", srec->uid[M], srec->uid[S], nex ); + debug( " pair(%u,%u): %d (pending)\n", srec->uid[M], srec->uid[S], nex ); } } else { /* Note: the "wrong" transaction may be pending here, - * e.g.: S_NEXPIRE = 0, S_EXPIRE = 1, S_EXPIRED = 0. */ + * e.g.: W_NEXPIRE = 0, S_EXPIRE = 1, S_EXPIRED = 0. */ } } else { - if (srec->status & S_NEXPIRE) { - Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] ); - debug( " pair(%d,%d): 1 (abort)\n", srec->uid[M], srec->uid[S] ); + if (srec->wstate & W_NEXPIRE) { + jFprintf( svars, "= %u %u\n", srec->uid[M], srec->uid[S] ); + debug( " pair(%u,%u): 1 (abort)\n", srec->uid[M], srec->uid[S] ); + // If we have so many new messages that some of them are instantly expired, + // but some are still propagated because they are important, we need to + // ensure explicitly that the bulk fetch limit is upped. + svars->mmaxxuid = srec->uid[M]; srec->msg[M]->srec = 0; srec->status = S_DEAD; } @@ -1445,21 +1756,21 @@ debug( "synchronizing flags\n" ); for (srec = svars->srecs; srec; srec = srec->next) { - if ((srec->status & S_DEAD) || srec->uid[M] <= 0 || srec->uid[S] <= 0) + if ((srec->status & S_DEAD) || !srec->uid[M] || !srec->uid[S]) continue; for (t = 0; t < 2; t++) { aflags = srec->aflags[t]; dflags = srec->dflags[t]; - if (srec->status & S_DELETE) { + if (srec->wstate & W_DELETE) { if (!aflags) { /* This deletion propagation goes the other way round. */ continue; } } else { /* The trigger is an expiration transaction being ongoing ... */ - if ((t == S) && ((mvBit(srec->status, S_EXPIRE, S_EXPIRED) ^ srec->status) & S_EXPIRED)) { + if ((t == S) && ((shifted_bit(srec->status, S_EXPIRE, S_EXPIRED) ^ srec->status) & S_EXPIRED)) { /* ... but the actual action derives from the wanted state. */ - if (srec->status & S_NEXPIRE) + if (srec->wstate & W_NEXPIRE) aflags |= F_DELETED; else dflags |= F_DELETED; @@ -1479,14 +1790,15 @@ dflags &= srec->msg[t]->flags; } if (aflags | dflags) { - svars->flags_total[t]++; - stats( svars ); + flags_total[t]++; + stats(); + svars->flags_pending[t]++; fv = nfmalloc( sizeof(*fv) ); fv->aux = AUX; fv->srec = srec; fv->aflags = aflags; fv->dflags = dflags; - svars->drv[t]->set_flags( svars->ctx[t], srec->msg[t], srec->uid[t], aflags, dflags, flags_set, fv ); + svars->drv[t]->set_msg_flags( svars->ctx[t], srec->msg[t], srec->uid[t], aflags, dflags, flags_set, fv ); if (check_cancel( svars )) goto out; } else @@ -1494,7 +1806,7 @@ } } for (t = 0; t < 2; t++) { - svars->drv[t]->commit( svars->ctx[t] ); + svars->drv[t]->commit_cmds( svars->ctx[t] ); svars->state[t] |= ST_SENT_FLAGS; msgs_flags_set( svars, t ); if (check_cancel( svars )) @@ -1505,22 +1817,9 @@ if (UseFSync) fdatasync( fileno( svars->jfp ) ); for (t = 0; t < 2; t++) { - Fprintf( svars->jfp, "%c %d\n", "{}"[t], svars->ctx[t]->uidnext ); - for (tmsg = svars->ctx[1-t]->msgs; tmsg; tmsg = tmsg->next) { - if ((srec = tmsg->srec) && srec->tuid[0]) { - svars->new_total[t]++; - stats( svars ); - cv = nfmalloc( sizeof(*cv) ); - cv->cb = msg_copied; - cv->aux = AUX; - cv->srec = srec; - cv->msg = tmsg; - copy_msg( cv ); - if (check_cancel( svars )) - goto out; - } - } - svars->state[t] |= ST_SENT_NEW; + svars->newuid[t] = svars->drv[t]->get_uidnext( svars->ctx[t] ); + jFprintf( svars, "F %d %u\n", t, svars->newuid[t] ); + svars->new_msgs[t] = svars->msgs[1-t]; msgs_copied( svars, t ); if (check_cancel( svars )) goto out; @@ -1531,19 +1830,25 @@ } static void -msg_copied( int sts, int uid, copy_vars_t *vars ) +msg_copied( int sts, uint uid, copy_vars_t *vars ) { SVARS_CHECK_CANCEL_RET; switch (sts) { case SYNC_OK: - if (uid < 0) + if (!uid) { // Stored to a non-UIDPLUS mailbox svars->state[t] |= ST_FIND_NEW; - msg_copied_p2( svars, vars->srec, t, uid ); + } else { + debug( " -> new UID %u on %s\n", uid, str_ms[t] ); + jFprintf( svars, "%c %u %u %u\n", "<>"[t], vars->srec->uid[M], vars->srec->uid[S], uid ); + vars->srec->uid[t] = uid; + vars->srec->status &= ~S_PENDING; + vars->srec->tuid[0] = 0; + } break; case SYNC_NOGOOD: - debug( " -> killing (%d,%d)\n", vars->srec->uid[M], vars->srec->uid[S] ); + debug( " -> killing (%u,%u)\n", vars->srec->uid[M], vars->srec->uid[S] ); vars->srec->status = S_DEAD; - Fprintf( svars->jfp, "- %d %d\n", vars->srec->uid[M], vars->srec->uid[S] ); + jFprintf( svars, "- %u %u\n", vars->srec->uid[M], vars->srec->uid[S] ); break; default: cancel_sync( svars ); @@ -1551,59 +1856,73 @@ return; } free( vars ); - svars->new_done[t]++; - stats( svars ); + new_done[t]++; + stats(); + svars->new_pending[t]--; msgs_copied( svars, t ); } -static void -msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, int uid ) -{ - /* Possible previous UIDs: - * - -2 when the entry is new - * - -1 when re-newing an entry - * Possible new UIDs: - * - a real UID when storing a message to a UIDPLUS mailbox - * - -2 when storing a message to a dumb mailbox - * - -1 when not actually storing a message */ - if (srec->uid[t] != uid) { - debug( " -> new UID %d on %s\n", uid, str_ms[t] ); - Fprintf( svars->jfp, "%c %d %d %d\n", "<>"[t], srec->uid[M], srec->uid[S], uid ); - srec->uid[t] = uid; - srec->tuid[0] = 0; - } - if (t == S && svars->mmaxxuid < srec->uid[M]) { - /* If we have so many new messages that some of them are instantly expired, - * but some are still propagated because they are important, we need to - * ensure explicitly that the bulk fetch limit is upped. */ - svars->mmaxxuid = INT_MAX; - if (svars->smaxxuid < srec->uid[S] - 1) { - svars->smaxxuid = srec->uid[S] - 1; - Fprintf( svars->jfp, "! %d\n", svars->smaxxuid ); - } - } -} - -static void msgs_found_new( int sts, void *aux ); +static void msgs_found_new( int sts, message_t *msgs, void *aux ); static void msgs_new_done( sync_vars_t *svars, int t ); static void sync_close( sync_vars_t *svars, int t ); static void msgs_copied( sync_vars_t *svars, int t ) { - if (!(svars->state[t] & ST_SENT_NEW) || svars->new_done[t] < svars->new_total[t]) + message_t *tmsg; + sync_rec_t *srec; + copy_vars_t *cv; + + if (svars->state[t] & ST_SENDING_NEW) return; sync_ref( svars ); - Fprintf( svars->jfp, "%c %d\n", ")("[t], svars->maxuid[1-t] ); + if (!(svars->state[t] & ST_SENT_NEW)) { + for (tmsg = svars->new_msgs[t]; tmsg; tmsg = tmsg->next) { + if ((srec = tmsg->srec) && (srec->status & S_PENDING)) { + if (svars->drv[t]->get_memory_usage( svars->ctx[t] ) >= BufferLimit) { + svars->new_msgs[t] = tmsg; + goto out; + } + for (uint i = 0; i < TUIDL; i++) { + uchar c = arc4_getbyte() & 0x3f; + srec->tuid[i] = c < 26 ? c + 'A' : c < 52 ? c + 'a' - 26 : c < 62 ? c + '0' - 52 : c == 62 ? '+' : '/'; + } + jFprintf( svars, "# %u %u %." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid ); + debug( "%sing message %u, TUID %." stringify(TUIDL) "s\n", str_hl[t], tmsg->uid, srec->tuid ); + new_total[t]++; + stats(); + svars->new_pending[t]++; + svars->state[t] |= ST_SENDING_NEW; + cv = nfmalloc( sizeof(*cv) ); + cv->cb = msg_copied; + cv->aux = AUX; + cv->srec = srec; + cv->msg = tmsg; + copy_msg( cv ); + svars->state[t] &= ~ST_SENDING_NEW; + if (check_cancel( svars )) + goto out; + } + } + svars->state[t] |= ST_SENT_NEW; + } + + if (svars->new_pending[t]) + goto out; + + if (svars->maxuid[1-t] != svars->newmaxuid[1-t]) { + svars->maxuid[1-t] = svars->newmaxuid[1-t]; + jFprintf( svars, "S %d\n", 1-t ); + } sync_close( svars, 1-t ); if (check_cancel( svars )) goto out; if (svars->state[t] & ST_FIND_NEW) { debug( "finding just copied messages on %s\n", str_ms[t] ); - svars->drv[t]->find_new_msgs( svars->ctx[t], msgs_found_new, AUX ); + svars->drv[t]->find_new_msgs( svars->ctx[t], svars->newuid[t], msgs_found_new, AUX ); } else { msgs_new_done( svars, t ); } @@ -1613,7 +1932,7 @@ } static void -msgs_found_new( int sts, void *aux ) +msgs_found_new( int sts, message_t *msgs, void *aux ) { SVARS_CHECK_RET; switch (sts) { @@ -1624,7 +1943,7 @@ warn( "Warning: cannot find newly stored messages on %s.\n", str_ms[t] ); break; } - match_tuids( svars, t ); + match_tuids( svars, t, msgs ); msgs_new_done( svars, t ); } @@ -1642,59 +1961,64 @@ switch (sts) { case DRV_OK: if (vars->aflags & F_DELETED) - vars->srec->status |= S_DEL(t); + vars->srec->wstate |= W_DEL(t); else if (vars->dflags & F_DELETED) - vars->srec->status &= ~S_DEL(t); + vars->srec->wstate &= ~W_DEL(t); flags_set_p2( svars, vars->srec, t ); break; } free( vars ); - svars->flags_done[t]++; - stats( svars ); + flags_done[t]++; + stats(); + svars->flags_pending[t]--; msgs_flags_set( svars, t ); } static void flags_set_p2( sync_vars_t *svars, sync_rec_t *srec, int t ) { - if (srec->status & S_DELETE) { - debug( " pair(%d,%d): resetting %s UID\n", srec->uid[M], srec->uid[S], str_ms[1-t] ); - Fprintf( svars->jfp, "%c %d %d 0\n", "><"[t], srec->uid[M], srec->uid[S] ); + if (srec->wstate & W_DELETE) { + debug( " pair(%u,%u): resetting %s UID\n", srec->uid[M], srec->uid[S], str_ms[1-t] ); + jFprintf( svars, "%c %u %u 0\n", "><"[t], srec->uid[M], srec->uid[S] ); srec->uid[1-t] = 0; } else { - int nflags = (srec->flags | srec->aflags[t]) & ~srec->dflags[t]; + uint nflags = (srec->flags | srec->aflags[t]) & ~srec->dflags[t]; if (srec->flags != nflags) { - debug( " pair(%d,%d): updating flags (%u -> %u; %sed)\n", srec->uid[M], srec->uid[S], srec->flags, nflags, str_hl[t] ); + debug( " pair(%u,%u): updating flags (%u -> %u; %sed)\n", srec->uid[M], srec->uid[S], srec->flags, nflags, str_hl[t] ); srec->flags = nflags; - Fprintf( svars->jfp, "* %d %d %u\n", srec->uid[M], srec->uid[S], nflags ); + jFprintf( svars, "* %u %u %u\n", srec->uid[M], srec->uid[S], nflags ); } if (t == S) { - int nex = (srec->status / S_NEXPIRE) & 1; + uint nex = (srec->wstate / W_NEXPIRE) & 1; if (nex != ((srec->status / S_EXPIRED) & 1)) { - if (nex && (svars->smaxxuid < srec->uid[S])) - svars->smaxxuid = srec->uid[S]; - Fprintf( svars->jfp, "/ %d %d\n", srec->uid[M], srec->uid[S] ); - debug( " pair(%d,%d): expired %d (commit)\n", srec->uid[M], srec->uid[S], nex ); + debug( " pair(%u,%u): expired %d (commit)\n", srec->uid[M], srec->uid[S], nex ); srec->status = (srec->status & ~S_EXPIRED) | (nex * S_EXPIRED); + jFprintf( svars, "~ %u %u %u\n", srec->uid[M], srec->uid[S], srec->status ); } else if (nex != ((srec->status / S_EXPIRE) & 1)) { - Fprintf( svars->jfp, "\\ %d %d\n", srec->uid[M], srec->uid[S] ); - debug( " pair(%d,%d): expire %d (cancel)\n", srec->uid[M], srec->uid[S], nex ); + debug( " pair(%u,%u): expire %d (cancel)\n", srec->uid[M], srec->uid[S], nex ); srec->status = (srec->status & ~S_EXPIRE) | (nex * S_EXPIRE); + jFprintf( svars, "~ %u %u %u\n", srec->uid[M], srec->uid[S], srec->status ); } } } } +typedef struct { + void *aux; + message_t *msg; +} trash_vars_t; + static void msg_trashed( int sts, void *aux ); -static void msg_rtrashed( int sts, int uid, copy_vars_t *vars ); +static void msg_rtrashed( int sts, uint uid, copy_vars_t *vars ); static void msgs_flags_set( sync_vars_t *svars, int t ) { message_t *tmsg; + trash_vars_t *tv; copy_vars_t *cv; - if (!(svars->state[t] & ST_SENT_FLAGS) || svars->flags_done[t] < svars->flags_total[t]) + if (!(svars->state[t] & ST_SENT_FLAGS) || svars->flags_pending[t]) return; sync_ref( svars ); @@ -1702,24 +2026,30 @@ if ((svars->chan->ops[t] & OP_EXPUNGE) && (svars->ctx[t]->conf->trash || (svars->ctx[1-t]->conf->trash && svars->ctx[1-t]->conf->trash_remote_new))) { debug( "trashing in %s\n", str_ms[t] ); - for (tmsg = svars->ctx[t]->msgs; tmsg; tmsg = tmsg->next) - if ((tmsg->flags & F_DELETED) && (t == M || !tmsg->srec || !(tmsg->srec->status & (S_EXPIRE|S_EXPIRED)))) { + for (tmsg = svars->msgs[t]; tmsg; tmsg = tmsg->next) + if ((tmsg->flags & F_DELETED) && !find_uint_array( svars->trashed_msgs[t].array, tmsg->uid ) && + (t == M || !tmsg->srec || !(tmsg->srec->status & (S_EXPIRE|S_EXPIRED)))) { if (svars->ctx[t]->conf->trash) { - if (!svars->ctx[t]->conf->trash_only_new || !tmsg->srec || tmsg->srec->uid[1-t] < 0) { - debug( "%s: trashing message %d\n", str_ms[t], tmsg->uid ); - svars->trash_total[t]++; - stats( svars ); - svars->drv[t]->trash_msg( svars->ctx[t], tmsg, msg_trashed, AUX ); + if (!svars->ctx[t]->conf->trash_only_new || !tmsg->srec || (tmsg->srec->status & (S_PENDING | S_SKIPPED))) { + debug( "%s: trashing message %u\n", str_ms[t], tmsg->uid ); + trash_total[t]++; + stats(); + svars->trash_pending[t]++; + tv = nfmalloc( sizeof(*tv) ); + tv->aux = AUX; + tv->msg = tmsg; + svars->drv[t]->trash_msg( svars->ctx[t], tmsg, msg_trashed, tv ); if (check_cancel( svars )) goto out; } else - debug( "%s: not trashing message %d - not new\n", str_ms[t], tmsg->uid ); + debug( "%s: not trashing message %u - not new\n", str_ms[t], tmsg->uid ); } else { - if (!tmsg->srec || tmsg->srec->uid[1-t] < 0) { + if (!tmsg->srec || (tmsg->srec->status & (S_PENDING | S_SKIPPED))) { if (tmsg->size <= svars->ctx[1-t]->conf->max_size) { - debug( "%s: remote trashing message %d\n", str_ms[t], tmsg->uid ); - svars->trash_total[t]++; - stats( svars ); + debug( "%s: remote trashing message %u\n", str_ms[t], tmsg->uid ); + trash_total[t]++; + stats(); + svars->trash_pending[t]++; cv = nfmalloc( sizeof(*cv) ); cv->cb = msg_rtrashed; cv->aux = INV_AUX; @@ -1729,9 +2059,9 @@ if (check_cancel( svars )) goto out; } else - debug( "%s: not remote trashing message %d - too big\n", str_ms[t], tmsg->uid ); + debug( "%s: not remote trashing message %u - too big\n", str_ms[t], tmsg->uid ); } else - debug( "%s: not remote trashing message %d - not new\n", str_ms[t], tmsg->uid ); + debug( "%s: not remote trashing message %u - not new\n", str_ms[t], tmsg->uid ); } } } @@ -1745,20 +2075,25 @@ static void msg_trashed( int sts, void *aux ) { + trash_vars_t *vars = (trash_vars_t *)aux; DECL_SVARS; if (sts == DRV_MSG_BAD) sts = DRV_BOX_BAD; - if (check_ret( sts, aux )) + if (check_ret( sts, vars->aux )) return; - INIT_SVARS(aux); - svars->trash_done[t]++; - stats( svars ); + INIT_SVARS(vars->aux); + debug( " -> trashed %s %u\n", str_ms[t], vars->msg->uid ); + jFprintf( svars, "T %d %u\n", t, vars->msg->uid ); + free( vars ); + trash_done[t]++; + stats(); + svars->trash_pending[t]--; sync_close( svars, t ); } static void -msg_rtrashed( int sts, int uid ATTR_UNUSED, copy_vars_t *vars ) +msg_rtrashed( int sts, uint uid ATTR_UNUSED, copy_vars_t *vars ) { SVARS_CHECK_CANCEL_RET; switch (sts) { @@ -1770,10 +2105,13 @@ free( vars ); return; } - free( vars ); t ^= 1; - svars->trash_done[t]++; - stats( svars ); + debug( " -> remote trashed %s %u\n", str_ms[t], vars->msg->uid ); + jFprintf( svars, "T %d %u\n", t, vars->msg->uid ); + free( vars ); + trash_done[t]++; + stats(); + svars->trash_pending[t]--; sync_close( svars, t ); } @@ -1783,8 +2121,8 @@ static void sync_close( sync_vars_t *svars, int t ) { - if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_done[t] < svars->trash_total[t] || - !(svars->state[1-t] & ST_SENT_NEW) || svars->new_done[1-t] < svars->new_total[1-t]) + if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_pending[t] || + !(svars->state[1-t] & ST_SENT_NEW) || svars->new_pending[1-t]) return; if (svars->state[t] & ST_CLOSING) @@ -1793,7 +2131,7 @@ if ((svars->chan->ops[t] & OP_EXPUNGE) /*&& !(svars->state[t] & ST_TRASH_BAD)*/) { debug( "expunging %s\n", str_ms[t] ); - svars->drv[t]->close( svars->ctx[t], box_closed, AUX ); + svars->drv[t]->close_box( svars->ctx[t], box_closed, AUX ); } else { box_closed_p2( svars, t ); } @@ -1811,73 +2149,46 @@ box_closed_p2( sync_vars_t *svars, int t ) { sync_rec_t *srec; - int minwuid; - char fbuf[16]; /* enlarge when support for keywords is added */ svars->state[t] |= ST_CLOSED; if (!(svars->state[1-t] & ST_CLOSED)) return; + // All the journalling done in this function is merely for the autotest - + // the operations are idempotent, and we're about to commit the new state + // right afterwards anyway. + if (((svars->state[M] | svars->state[S]) & ST_DID_EXPUNGE) || svars->chan->max_messages) { debug( "purging obsolete entries\n" ); - - minwuid = INT_MAX; - if (svars->chan->max_messages) { - debug( " max expired slave uid is %d\n", svars->smaxxuid ); - for (srec = svars->srecs; srec; srec = srec->next) { - if (srec->status & S_DEAD) - continue; - if (!((srec->uid[S] <= 0 || ((srec->status & S_DEL(S)) && (svars->state[S] & ST_DID_EXPUNGE))) && - (srec->uid[M] <= 0 || ((srec->status & S_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE)) || (srec->status & S_EXPIRED))) && - svars->smaxxuid < srec->uid[S] && minwuid > srec->uid[M]) - minwuid = srec->uid[M]; - } - debug( " min non-orphaned master uid is %d\n", minwuid ); - } - for (srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) continue; - if (srec->uid[S] <= 0 || ((srec->status & S_DEL(S)) && (svars->state[S] & ST_DID_EXPUNGE))) { - if (srec->uid[M] <= 0 || ((srec->status & S_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE)) || - ((srec->status & S_EXPIRED) && svars->maxuid[M] >= srec->uid[M] && minwuid > srec->uid[M])) { - debug( " -> killing (%d,%d)\n", srec->uid[M], srec->uid[S] ); + if (!srec->uid[S] || ((srec->wstate & W_DEL(S)) && (svars->state[S] & ST_DID_EXPUNGE))) { + if (!srec->uid[M] || ((srec->wstate & W_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE)) || + ((srec->status & S_EXPIRED) && svars->maxuid[M] >= srec->uid[M] && svars->mmaxxuid >= srec->uid[M])) { + debug( " -> killing (%u,%u)\n", srec->uid[M], srec->uid[S] ); + jFprintf( svars, "- %u %u\n", srec->uid[M], srec->uid[S] ); srec->status = S_DEAD; - Fprintf( svars->jfp, "- %d %d\n", srec->uid[M], srec->uid[S] ); - } else if (srec->uid[S] > 0) { - debug( " -> orphaning (%d,[%d])\n", srec->uid[M], srec->uid[S] ); - Fprintf( svars->jfp, "> %d %d 0\n", srec->uid[M], srec->uid[S] ); + } else if (srec->uid[S]) { + debug( " -> orphaning (%u,[%u])\n", srec->uid[M], srec->uid[S] ); + jFprintf( svars, "> %u %u 0\n", srec->uid[M], srec->uid[S] ); srec->uid[S] = 0; } - } else if (srec->uid[M] > 0 && ((srec->status & S_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE))) { - debug( " -> orphaning ([%d],%d)\n", srec->uid[M], srec->uid[S] ); - Fprintf( svars->jfp, "< %d %d 0\n", srec->uid[M], srec->uid[S] ); + } else if (srec->uid[M] && ((srec->wstate & W_DEL(M)) && (svars->state[M] & ST_DID_EXPUNGE))) { + debug( " -> orphaning ([%u],%u)\n", srec->uid[M], srec->uid[S] ); + jFprintf( svars, "< %u %u 0\n", srec->uid[M], srec->uid[S] ); srec->uid[M] = 0; } } } - Fprintf( svars->nfp, - "MasterUidValidity %d\nSlaveUidValidity %d\nMaxPulledUid %d\nMaxPushedUid %d\n", - svars->uidval[M], svars->uidval[S], svars->maxuid[M], svars->maxuid[S] ); - if (svars->smaxxuid) - Fprintf( svars->nfp, "MaxExpiredSlaveUid %d\n", svars->smaxxuid ); - Fprintf( svars->nfp, "\n" ); - for (srec = svars->srecs; srec; srec = srec->next) { - if (srec->status & S_DEAD) - continue; - make_flags( srec->flags, fbuf ); - Fprintf( svars->nfp, "%d %d %s%s\n", srec->uid[M], srec->uid[S], - srec->status & S_EXPIRED ? "X" : "", fbuf ); - } + // This is just an optimization, so it needs no journaling of intermediate states. + // However, doing it before the entry purge would require ensuring that the + // exception list includes all relevant messages. + debug( "max expired uid on master is now %d\n", svars->mmaxxuid ); + jFprintf( svars, "! %d\n", svars->mmaxxuid ); - Fclose( svars->nfp, 1 ); - Fclose( svars->jfp, 0 ); - if (!(DFlags & KEEPJOURNAL)) { - /* order is important! */ - rename( svars->nname, svars->dname ); - unlink( svars->jname ); - } + save_state( svars ); sync_bail( svars ); } @@ -1887,18 +2198,16 @@ { sync_rec_t *srec, *nsrec; + free( svars->trashed_msgs[M].array.data ); + free( svars->trashed_msgs[S].array.data ); for (srec = svars->srecs; srec; srec = nsrec) { nsrec = srec->next; free( srec ); } - unlink( svars->lname ); - sync_bail1( svars ); -} - -static void -sync_bail1( sync_vars_t *svars ) -{ - close( svars->lfd ); + if (svars->lfd >= 0) { + unlink( svars->lname ); + close( svars->lfd ); + } sync_bail2( svars ); } @@ -1909,15 +2218,14 @@ free( svars->nname ); free( svars->jname ); free( svars->dname ); - flushn(); sync_bail3( svars ); } static void sync_bail3( sync_vars_t *svars ) { - free( svars->ctx[M]->name ); - free( svars->ctx[S]->name ); + free( svars->box_name[M] ); + free( svars->box_name[S] ); sync_deref( svars ); } diff -Nru isync-1.1.0/src/sync.h isync-1.2.1-1.812.20170514/src/sync.h --- isync-1.1.0/src/sync.h 2013-12-13 17:54:37.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/sync.h 2017-05-26 14:36:31.000000000 +0000 @@ -35,12 +35,14 @@ #define OP_MASK_TYPE (OP_NEW|OP_RENEW|OP_DELETE|OP_FLAGS) /* asserted in the target ops */ #define OP_EXPUNGE (1<<4) #define OP_CREATE (1<<5) -#define XOP_PUSH (1<<6) -#define XOP_PULL (1<<7) +#define OP_REMOVE (1<<6) +#define XOP_PUSH (1<<8) +#define XOP_PULL (1<<9) #define XOP_MASK_DIR (XOP_PUSH|XOP_PULL) -#define XOP_HAVE_TYPE (1<<8) -#define XOP_HAVE_EXPUNGE (1<<9) -#define XOP_HAVE_CREATE (1<<10) +#define XOP_HAVE_TYPE (1<<10) +#define XOP_HAVE_EXPUNGE (1<<11) +#define XOP_HAVE_CREATE (1<<12) +#define XOP_HAVE_REMOVE (1<<13) typedef struct channel_conf { struct channel_conf *next; @@ -50,7 +52,7 @@ char *sync_state; string_list_t *patterns; int ops[2]; - unsigned max_messages; /* for slave only */ + uint max_messages; /* for slave only */ signed char expire_unread; char use_internal_date; } channel_conf_t; @@ -69,13 +71,16 @@ #define SYNC_OK 0 /* assumed to be 0 */ #define SYNC_FAIL 1 -#define SYNC_FAIL_ALL 2 #define SYNC_BAD(ms) (4<<(ms)) #define SYNC_NOGOOD 16 /* internal */ #define SYNC_CANCELED 32 /* internal */ +#define BOX_POSSIBLE -1 +#define BOX_ABSENT 0 +#define BOX_PRESENT 1 + /* All passed pointers must stay alive until cb is called. */ -void sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, +void sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t *chan, void (*cb)( int sts, void *aux ), void *aux ); #endif diff -Nru isync-1.1.0/src/tst_timers.c isync-1.2.1-1.812.20170514/src/tst_timers.c --- isync-1.1.0/src/tst_timers.c 1970-01-01 00:00:00.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/tst_timers.c 2017-05-26 14:36:31.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * mbsync - mailbox synchronizer + * Copyright (C) 2014 Oswald Buddenhagen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception, mbsync may be linked with the OpenSSL library, + * despite that library's more restrictive license. + */ + +#include "common.h" + +#include +#include +#include + +/* Just to satisfy the references in util.c */ +int DFlags; +const char *Home; + +typedef struct { + int id; + int first, other, morph_at, morph_to; + time_t start; + wakeup_t timer; + wakeup_t morph_timer; +} tst_t; + +static void +timer_start( tst_t *timer, int to ) +{ + printf( "starting timer %d, should expire after %d\n", timer->id, to ); + time( &timer->start ); + conf_wakeup( &timer->timer, to ); +} + +static void +timed_out( void *aux ) +{ + tst_t *timer = (tst_t *)aux; + + printf( "timer %d expired after %d, repeat %d\n", + timer->id, (int)(time( 0 ) - timer->start), timer->other ); + if (timer->other >= 0) { + timer_start( timer, timer->other ); + } else { + wipe_wakeup( &timer->timer ); + wipe_wakeup( &timer->morph_timer ); + free( timer ); + } +} + +static void +morph_timed_out( void *aux ) +{ + tst_t *timer = (tst_t *)aux; + + printf( "morphing timer %d after %d\n", + timer->id, (int)(time( 0 ) - timer->start) ); + timer_start( timer, timer->morph_to ); +} + +static int nextid; + +int +main( int argc, char **argv ) +{ + int i; + + for (i = 1; i < argc; i++) { + char *val = argv[i]; + tst_t *timer = nfmalloc( sizeof(*timer) ); + init_wakeup( &timer->timer, timed_out, timer ); + init_wakeup( &timer->morph_timer, morph_timed_out, timer ); + timer->id = ++nextid; + timer->first = strtol( val, &val, 0 ); + if (*val == '@') { + timer->other = timer->first; + timer->first = strtol( ++val, &val, 0 ); + } else { + timer->other = -1; + } + if (*val == ':') { + timer->morph_to = strtol( ++val, &val, 0 ); + if (*val != '@') + goto fail; + timer->morph_at = strtol( ++val, &val, 0 ); + } else { + timer->morph_at = -1; + } + if (*val) { + fail: + fprintf( stderr, "Fatal: syntax error in %s, use [@][:@]\n", argv[i] ); + return 1; + } + timer_start( timer, timer->first ); + if (timer->morph_at >= 0) { + printf( "timer %d, should morph after %d\n", timer->id, timer->morph_at ); + conf_wakeup( &timer->morph_timer, timer->morph_at ); + } + } + + main_loop(); + return 0; +} diff -Nru isync-1.1.0/src/util.c isync-1.2.1-1.812.20170514/src/util.c --- isync-1.1.0/src/util.c 2013-12-18 19:10:58.000000000 +0000 +++ isync-1.2.1-1.812.20170514/src/util.c 2017-05-26 14:36:31.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include static int need_nl; @@ -53,39 +54,43 @@ } void -debug( const char *msg, ... ) +vdebug( int cat, const char *msg, va_list va ) { - va_list va; - - if (DFlags & DEBUG) { - va_start( va, msg ); + if (DFlags & cat) { vprintf( msg, va ); - va_end( va ); fflush( stdout ); need_nl = 0; } } void -debugn( const char *msg, ... ) +vdebugn( int cat, const char *msg, va_list va ) { - va_list va; - - if (DFlags & DEBUG) { - va_start( va, msg ); + if (DFlags & cat) { vprintf( msg, va ); - va_end( va ); fflush( stdout ); need_nl = 1; } } void +progress( const char *msg, ... ) +{ + va_list va; + + va_start( va, msg ); + vprintf( msg, va ); + va_end( va ); + fflush( stdout ); + need_nl = 1; +} + +void info( const char *msg, ... ) { va_list va; - if (!(DFlags & QUIET)) { + if (DFlags & VERBOSE) { va_start( va, msg ); printn( msg, va ); va_end( va ); @@ -98,7 +103,7 @@ { va_list va; - if (!(DFlags & QUIET)) { + if (DFlags & VERBOSE) { va_start( va, msg ); printn( msg, va ); va_end( va ); @@ -107,6 +112,19 @@ } void +notice( const char *msg, ... ) +{ + va_list va; + + if (!(DFlags & QUIET)) { + va_start( va, msg ); + printn( msg, va ); + va_end( va ); + need_nl = 0; + } +} + +void warn( const char *msg, ... ) { va_list va; @@ -138,7 +156,7 @@ flushn(); va_start( va, msg ); - if ((unsigned)vsnprintf( buf, sizeof(buf), msg, va ) >= sizeof(buf)) + if ((uint)vsnprintf( buf, sizeof(buf), msg, va ) >= sizeof(buf)) oob(); va_end( va ); perror( buf ); @@ -203,6 +221,112 @@ } #endif +#ifndef HAVE_STRNLEN +size_t +strnlen( const char *str, size_t maxlen ) +{ + const char *estr = memchr( str, 0, maxlen ); + return estr ? (size_t)(estr - str) : maxlen; +} + +#endif + +int +starts_with( const char *str, int strl, const char *cmp, int cmpl ) +{ + if (strl < 0) + strl = strnlen( str, cmpl + 1 ); + return (strl >= cmpl) && !memcmp( str, cmp, cmpl ); +} + +int +starts_with_upper( const char *str, int strl, const char *cmp, int cmpl ) +{ + int i; + + if (strl < 0) + strl = strnlen( str, cmpl + 1 ); + if (strl < cmpl) + return 0; + for (i = 0; i < cmpl; i++) + if (str[i] != cmp[i] && toupper( str[i] ) != cmp[i]) + return 0; + return 1; +} + +int +equals( const char *str, int strl, const char *cmp, int cmpl ) +{ + if (strl < 0) + strl = strnlen( str, cmpl + 1 ); + return (strl == cmpl) && !memcmp( str, cmp, cmpl ); +} + +#ifndef HAVE_TIMEGM +/* + Converts struct tm to time_t, assuming the data in tm is UTC rather + than local timezone. + + mktime is similar but assumes struct tm, also known as the + "broken-down" form of time, is in local time zone. timegm + uses mktime to make the conversion understanding that an offset + will be introduced by the local time assumption. + + mktime_from_utc then measures the introduced offset by applying + gmtime to the initial result and applying mktime to the resulting + "broken-down" form. The difference between the two mktime results + is the measured offset which is then subtracted from the initial + mktime result to yield a calendar time which is the value returned. + + tm_isdst in struct tm is set to 0 to force mktime to introduce a + consistent offset (the non DST offset) since tm and tm+o might be + on opposite sides of a DST change. + + Some implementations of mktime return -1 for the nonexistent + localtime hour at the beginning of DST. In this event, use + mktime(tm - 1hr) + 3600. + + Schematically + mktime(tm) --> t+o + gmtime(t+o) --> tm+o + mktime(tm+o) --> t+2o + t+o - (t+2o - t+o) = t + + Contributed by Roger Beeman , with the help of + Mark Baushke and the rest of the Gurus at CISCO. + Further improved by Roger with assistance from Edward J. Sabol + based on input by Jamie Zawinski. +*/ + +static time_t +my_mktime( struct tm *t ) +{ + time_t tl = mktime( t ); + if (tl == -1) { + t->tm_hour--; + tl = mktime( t ); + if (tl != -1) + tl += 3600; + } + return tl; +} + +time_t +timegm( struct tm *t ) +{ + time_t tl, tb; + struct tm *tg; + + if ((tl = my_mktime( t )) == -1) + return tl; + tg = gmtime( &tl ); + tg->tm_isdst = 0; + if ((tb = my_mktime( tg )) == -1) + return tb; + return tl - (tb - tl); +} +#endif + void oob( void ) { @@ -217,7 +341,7 @@ va_list va; va_start( va, fmt ); - if (blen <= 0 || (unsigned)(ret = vsnprintf( buf, blen, fmt, va )) >= (unsigned)blen) + if (blen <= 0 || (uint)(ret = vsnprintf( buf, blen, fmt, va )) >= (uint)blen) oob(); va_end( va ); return ret; @@ -261,15 +385,20 @@ } char * -nfstrdup( const char *str ) +nfstrndup( const char *str, size_t nchars ) { - char *ret; - - if (!(ret = strdup( str ))) - oom(); + char *ret = nfmalloc( nchars + 1 ); + memcpy( ret, str, nchars ); + ret[nchars] = 0; return ret; } +char * +nfstrdup( const char *str ) +{ + return nfstrndup( str, strlen( str ) ); +} + int nfvasprintf( char **str, const char *fmt, va_list va ) { @@ -311,15 +440,6 @@ } */ -static char * -my_strndup( const char *s, size_t nchars ) -{ - char *r = nfmalloc( nchars + 1 ); - memcpy( r, s, nchars ); - r[nchars] = 0; - return r; -} - char * expand_strdup( const char *s ) { @@ -337,7 +457,7 @@ q = Home; } else { if ((p = strchr( s, '/' ))) { - r = my_strndup( s, (int)(p - s) ); + r = nfstrndup( s, (int)(p - s) ); pw = getpwnam( r ); free( r ); } else @@ -399,7 +519,15 @@ for (ll = 0; ll < inl; ll++) if (arg[i + ll] != in[ll]) goto rnexti; +#ifdef __GNUC__ +# pragma GCC diagnostic push +/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42145 */ +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif memcpy( p, out, outl ); +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif p += outl; i += inl; continue; @@ -411,27 +539,44 @@ } static int -compare_ints( const void *l, const void *r ) +compare_uints( const void *l, const void *r ) { - return *(int *)l - *(int *)r; + return *(uint *)l - *(uint *)r; } void -sort_ints( int *arr, int len ) +sort_uint_array( uint_array_t array ) { - qsort( arr, len, sizeof(int), compare_ints ); + qsort( array.data, array.size, sizeof(uint), compare_uints ); +} + +int +find_uint_array( uint_array_t array, uint value ) +{ + int bot = 0, top = array.size - 1; + while (bot <= top) { + int i = (bot + top) / 2; + uint elt = array.data[i]; + if (elt == value) + return 1; + if (elt < value) + bot = i + 1; + else + top = i - 1; + } + return 0; } static struct { - unsigned char i, j, s[256]; + uchar i, j, s[256]; } rs; void arc4_init( void ) { int i, fd; - unsigned char j, si, dat[128]; + uchar j, si, dat[128]; if ((fd = open( "/dev/urandom", O_RDONLY )) < 0 && (fd = open( "/dev/random", O_RDONLY )) < 0) { error( "Fatal: no random number source available.\n" ); @@ -457,10 +602,10 @@ arc4_getbyte(); } -unsigned char +uchar arc4_getbyte( void ) { - unsigned char si, sj; + uchar si, sj; rs.i++; si = rs.s[rs.i]; @@ -471,9 +616,9 @@ return rs.s[(si + sj) & 0xff]; } -static const unsigned char prime_deltas[] = { - 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3, - 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0 +static const uchar prime_deltas[] = { + 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 17, 27, 3, + 1, 29, 3, 21, 7, 17, 15, 9, 43, 35, 15, 0, 0, 0, 0, 0 }; int @@ -490,146 +635,235 @@ } } +static void +list_prepend( list_head_t *head, list_head_t *to ) +{ + assert( !head->next ); + assert( to->next ); + assert( to->prev->next == to ); + head->next = to; + head->prev = to->prev; + head->prev->next = head; + to->prev = head; +} + +static void +list_unlink( list_head_t *head ) +{ + assert( head->next ); + assert( head->next->prev == head); + assert( head->prev->next == head); + head->next->prev = head->prev; + head->prev->next = head->next; + head->next = head->prev = 0; +} + +static notifier_t *notifiers; +static int changed; /* Iterator may be invalid now. */ #ifdef HAVE_SYS_POLL_H static struct pollfd *pollfds; +static int npolls, rpolls; #else # ifdef HAVE_SYS_SELECT_H # include # endif -# define pollfds fdparms #endif -static struct { - void (*cb)( int what, void *aux ); - void *aux; -#ifndef HAVE_SYS_POLL_H - int fd, events; -#endif - int faked; -} *fdparms; -static int npolls, rpolls, changed; -static int -find_fd( int fd ) +void +init_notifier( notifier_t *sn, int fd, void (*cb)( int, void * ), void *aux ) { - int n; - - for (n = 0; n < npolls; n++) - if (pollfds[n].fd == fd) - return n; - return -1; +#ifdef HAVE_SYS_POLL_H + int idx = npolls++; + if (rpolls < npolls) { + rpolls = npolls; + pollfds = nfrealloc( pollfds, npolls * sizeof(*pollfds) ); + } + pollfds[idx].fd = fd; + pollfds[idx].events = 0; /* POLLERR & POLLHUP implicit */ + sn->index = idx; +#else + sn->fd = fd; + sn->events = 0; +#endif + sn->cb = cb; + sn->aux = aux; + sn->next = notifiers; + notifiers = sn; } void -add_fd( int fd, void (*cb)( int events, void *aux ), void *aux ) +conf_notifier( notifier_t *sn, int and_events, int or_events ) { - int n; +#ifdef HAVE_SYS_POLL_H + int idx = sn->index; + pollfds[idx].events = (pollfds[idx].events & and_events) | or_events; +#else + sn->events = (sn->events & and_events) | or_events; +#endif +} - assert( find_fd( fd ) < 0 ); - n = npolls++; - if (rpolls < npolls) { - rpolls = npolls; +void +wipe_notifier( notifier_t *sn ) +{ + notifier_t **snp; #ifdef HAVE_SYS_POLL_H - pollfds = nfrealloc(pollfds, npolls * sizeof(*pollfds)); + int idx; #endif - fdparms = nfrealloc(fdparms, npolls * sizeof(*fdparms)); - } - pollfds[n].fd = fd; - pollfds[n].events = 0; /* POLLERR & POLLHUP implicit */ - fdparms[n].faked = 0; - fdparms[n].cb = cb; - fdparms[n].aux = aux; + + for (snp = ¬ifiers; *snp != sn; snp = &(*snp)->next) + assert( *snp ); + *snp = sn->next; + sn->next = 0; changed = 1; + +#ifdef HAVE_SYS_POLL_H + idx = sn->index; + memmove( pollfds + idx, pollfds + idx + 1, (--npolls - idx) * sizeof(*pollfds) ); + for (sn = notifiers; sn; sn = sn->next) { + if (sn->index > idx) + sn->index--; + } +#endif } -void -conf_fd( int fd, int and_events, int or_events ) +static time_t +get_now( void ) { - int n = find_fd( fd ); - assert( n >= 0 ); - pollfds[n].events = (pollfds[n].events & and_events) | or_events; + return time( 0 ); } +static list_head_t timers = { &timers, &timers }; + void -fake_fd( int fd, int events ) +init_wakeup( wakeup_t *tmr, void (*cb)( void * ), void *aux ) { - int n = find_fd( fd ); - assert( n >= 0 ); - fdparms[n].faked |= events; + tmr->cb = cb; + tmr->aux = aux; + tmr->links.next = tmr->links.prev = 0; } void -del_fd( int fd ) +wipe_wakeup( wakeup_t *tmr ) { - int n = find_fd( fd ); - assert( n >= 0 ); - npolls--; -#ifdef HAVE_SYS_POLL_H - memmove(pollfds + n, pollfds + n + 1, (npolls - n) * sizeof(*pollfds)); -#endif - memmove(fdparms + n, fdparms + n + 1, (npolls - n) * sizeof(*fdparms)); - changed = 1; + if (tmr->links.next) + list_unlink( &tmr->links ); } -#define shifted_bit(in, from, to) \ - (((unsigned)(in) & from) \ - / (from > to ? from / to : 1) \ - * (to > from ? to / from : 1)) +void +conf_wakeup( wakeup_t *tmr, int to ) +{ + list_head_t *head, *succ; + + if (to < 0) { + if (tmr->links.next) + list_unlink( &tmr->links ); + } else { + time_t timeout = to; + if (!to) { + /* We always prepend null timers, to cluster related events. */ + succ = timers.next; + } else { + timeout += get_now(); + /* We start at the end in the expectation that the newest timer is likely to fire last + * (which will be true only if all timeouts are equal, but it's an as good guess as any). */ + for (succ = &timers; (head = succ->prev) != &timers; succ = head) { + if (head != &tmr->links && timeout > ((wakeup_t *)head)->timeout) + break; + } + assert( head != &tmr->links ); + } + tmr->timeout = timeout; + if (succ != &tmr->links) { + if (tmr->links.next) + list_unlink( &tmr->links ); + list_prepend( &tmr->links, succ ); + } + } +} static void event_wait( void ) { - int m, n; + list_head_t *head; + notifier_t *sn; + int m; #ifdef HAVE_SYS_POLL_H int timeout = -1; - for (n = 0; n < npolls; n++) - if (fdparms[n].faked) { - timeout = 0; - break; + if ((head = timers.next) != &timers) { + wakeup_t *tmr = (wakeup_t *)head; + time_t delta = tmr->timeout; + if (!delta || (delta -= get_now()) <= 0) { + list_unlink( head ); + tmr->cb( tmr->aux ); + return; } - if (poll( pollfds, npolls, timeout ) < 0) { + timeout = (int)delta * 1000; + } + switch (poll( pollfds, npolls, timeout )) { + case 0: + return; + case -1: perror( "poll() failed in event loop" ); abort(); + default: + break; } - for (n = 0; n < npolls; n++) - if ((m = pollfds[n].revents | fdparms[n].faked)) { + for (sn = notifiers; sn; sn = sn->next) { + int n = sn->index; + if ((m = pollfds[n].revents)) { assert( !(m & POLLNVAL) ); - fdparms[n].faked = 0; - fdparms[n].cb( m | shifted_bit( m, POLLHUP, POLLIN ), fdparms[n].aux ); + sn->cb( m | shifted_bit( m, POLLHUP, POLLIN ), sn->aux ); if (changed) { changed = 0; break; } } + } #else struct timeval *timeout = 0; - static struct timeval null_tv; + struct timeval to_tv; fd_set rfds, wfds, efds; int fd; + if ((head = timers.next) != &timers) { + wakeup_t *tmr = (wakeup_t *)head; + time_t delta = tmr->timeout; + if (!delta || (delta -= get_now()) <= 0) { + list_unlink( head ); + tmr->cb( tmr->aux ); + return; + } + to_tv.tv_sec = delta; + to_tv.tv_usec = 0; + timeout = &to_tv; + } FD_ZERO( &rfds ); FD_ZERO( &wfds ); FD_ZERO( &efds ); m = -1; - for (n = 0; n < npolls; n++) { - if (fdparms[n].faked) - timeout = &null_tv; - fd = fdparms[n].fd; - if (fdparms[n].events & POLLIN) + for (sn = notifiers; sn; sn = sn->next) { + fd = sn->fd; + if (sn->events & POLLIN) FD_SET( fd, &rfds ); - if (fdparms[n].events & POLLOUT) + if (sn->events & POLLOUT) FD_SET( fd, &wfds ); FD_SET( fd, &efds ); if (fd > m) m = fd; } - if (select( m + 1, &rfds, &wfds, &efds, timeout ) < 0) { + switch (select( m + 1, &rfds, &wfds, &efds, timeout )) { + case 0: + return; + case -1: perror( "select() failed in event loop" ); abort(); + default: + break; } - for (n = 0; n < npolls; n++) { - fd = fdparms[n].fd; - m = fdparms[n].faked; + for (sn = notifiers; sn; sn = sn->next) { + fd = sn->fd; + m = 0; if (FD_ISSET( fd, &rfds )) m |= POLLIN; if (FD_ISSET( fd, &wfds )) @@ -637,8 +871,7 @@ if (FD_ISSET( fd, &efds )) m |= POLLERR; if (m) { - fdparms[n].faked = 0; - fdparms[n].cb( m, fdparms[n].aux ); + sn->cb( m, sn->aux ); if (changed) { changed = 0; break; @@ -651,6 +884,6 @@ void main_loop( void ) { - while (npolls) + while (notifiers || timers.next != &timers) event_wait(); } diff -Nru isync-1.1.0/TODO isync-1.2.1-1.812.20170514/TODO --- isync-1.1.0/TODO 2013-12-15 13:06:14.000000000 +0000 +++ isync-1.2.1-1.812.20170514/TODO 2017-05-26 14:36:31.000000000 +0000 @@ -1,19 +1,8 @@ f{,data}sync() usage could be optimized by batching the calls. -add some marker about message being already [remotely] trashed. -real transactions would be certainly not particularly useful ... - -make sync_chans() aware of servers, so a bad server (e.g., wrong password) -won't cause the same error message for every attached store. - -add support for more authentication methods: oauth, ntlm, ... use SASL? -possibly by calling an external command. that might be overkill, and -wouldn't be very user-friendly, though. - make SSL (connect) timeouts produce a bit more than "Unidentified socket error". -network timeout handling in general would be a good idea. -lock timeout handling, too. +uidvalidity lock timeout handling would be a good idea. add message expiration based on arrival date (message date would be too unreliable). MaxAge; probably mutually exclusive to MaxMessages. @@ -22,11 +11,6 @@ (delete messages like now), Keep (just don't sync) and Archive (move to separate folder - ArchiveSuffix, default .archive). -unify maildir locking between the two UID storage schemes. -re-opening the db may be expensive, so keep it open. -but keeping lock for too long (e.g., big message downloads) may block other -clients. auto-release lock after 500 ms? - kill the concept of an INBOX, it is a relic from single-channel operation. if somebody needs it, he can have two stores with different Paths. the path can name a single (in-)box (curr. broken with maildir). an empty box name @@ -60,8 +44,6 @@ flagging the dummy would fetch the real message. possibly remove --renew. note that all interaction needs to happen on the slave side probably. -propagate folder deletions. for safety, the target must be empty. - don't SELECT boxes unless really needed; in particular not for appending, and in write-only mode not before changes are made. problem: UIDVALIDITY change detection is delayed, significantly complicating