dovecot-pigeonhole-2.4.2/0000755000175100001700000000000015100335671017000 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/configure0000755000175100001700000204460415100335627020722 0ustar00buildbotbuildbot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for dovecot-pigeonhole 2.4.2. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 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="as_nop=: if test \${ZSH_VERSION+y} && (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 \$as_nop 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 \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || 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 -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: dovecot@dovecot.org about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: 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_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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=`printf "%s\n" "$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 || printf "%s\n" 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_nop 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_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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 || printf "%s\n" 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" || { printf "%s\n" "$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 } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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'" SHELL=${CONFIG_SHELL-/bin/sh} 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='dovecot-pigeonhole' PACKAGE_TARNAME='dovecot-pigeonhole' PACKAGE_VERSION='2.4.2' PACKAGE_STRING='dovecot-pigeonhole 2.4.2' PACKAGE_BUGREPORT='dovecot@dovecot.org' PACKAGE_URL='' ac_unique_file="src" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS AR_FLAGS SETTING_LINKED_FILES SETTING_FILES LDAP_PLUGIN_FALSE LDAP_PLUGIN_TRUE LDAP_LIBS LDAP_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG BUILD_MANAGESIEVE_FALSE BUILD_MANAGESIEVE_TRUE BUILD_DOCS_FALSE BUILD_DOCS_TRUE BUILD_UNFINISHED_FALSE BUILD_UNFINISHED_TRUE WGET sieve_docdir PIGEONHOLE_ASSET_URL PIGEONHOLE_ASSET_VERSION BINARY_LDFLAGS BINARY_CFLAGS AM_CFLAGS moduledir RUN_TEST VALGRIND DOVECOT_PLUGIN_DEPS_FALSE DOVECOT_PLUGIN_DEPS_TRUE DOVECOT_INSTALLED_FALSE DOVECOT_INSTALLED_TRUE LIBDOVECOT_LUA_DEPS LIBDOVECOT_LUA DOVECOT_LUA_CFLAGS DOVECOT_LUA_LIBS LIBDOVECOT_LUA_INCLUDE LIBDOVECOT_LIBLANG_INCLUDE LIBDOVECOT_ACL_INCLUDE LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE LIBDOVECOT_NOTIFY_INCLUDE LIBDOVECOT_FTS_INCLUDE LIBDOVECOT_IMAPC_INCLUDE LIBDOVECOT_DSYNC_INCLUDE LIBDOVECOT_LMTP_INCLUDE LIBDOVECOT_SUBMISSION_INCLUDE LIBDOVECOT_POP3_INCLUDE LIBDOVECOT_IMAP_INCLUDE LIBDOVECOT_CONFIG_INCLUDE LIBDOVECOT_IMAP_LOGIN_INCLUDE LIBDOVECOT_LDAP_INCLUDE LIBDOVECOT_SQL_INCLUDE LIBDOVECOT_LOGIN_INCLUDE LIBDOVECOT_STORAGE_INCLUDE LIBDOVECOT_SERVICE_INCLUDE LIBDOVECOT_DOVEADM_INCLUDE LIBDOVECOT_AUTH_INCLUDE LIBDOVECOT_LDA_INCLUDE LIBDOVECOT_INCLUDE LIBDOVECOT_GSSAPI_DEPS LIBDOVECOT_LIBLANG_DEPS LIBDOVECOT_DSYNC_DEPS LIBDOVECOT_STORAGE_DEPS LIBDOVECOT_LDA_DEPS LIBDOVECOT_COMPRESS_DEPS LIBDOVECOT_OPENSSL_DEPS LIBDOVECOT_LDAP_DEPS LIBDOVECOT_SQL_DEPS LIBDOVECOT_LOGIN_DEPS LIBDOVECOT_DEPS LIBDOVECOT_GSSAPI LIBDOVECOT_LIBLANG LIBDOVECOT_DSYNC LIBDOVECOT_STORAGE LIBDOVECOT_LDA LIBDOVECOT_COMPRESS LIBDOVECOT_OPENSSL LIBDOVECOT_LDAP LIBDOVECOT_SQL LIBDOVECOT_LOGIN LIBDOVECOT DOVECOT_BINARY_LDFLAGS DOVECOT_BINARY_CFLAGS DOVECOT_COMPRESS_LIBS DOVECOT_LDAP_LIBS DOVECOT_SQL_LIBS DOVECOT_SSL_LIBS DOVECOT_LIBS DOVECOT_CFLAGS DOVECOT_INSTALLED dovecot_statedir dovecot_docdir dovecot_pkglibdir dovecot_pkglibexecdir dovecot_pkgincludedir dovecot_installed_moduledir dovecot_moduledir dovecotdir DISTCHECK_CONFIGURE_FLAGS RELRO_LDFLAGS PIE_LDFLAGS PIE_CFLAGS WARN_CFLAGS abs_dovecotdir LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP FILECMD LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE 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 CSCOPE ETAGS CTAGS 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 runstatedir 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 am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock with_dovecot with_dovecot_install_dirs enable_hardening with_retpoline enable_ubsan with_moduledir with_unfinished_features with_docs with_managesieve with_ldap ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP LT_SYS_LIBRARY_PATH VALGRIND PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR LDAP_CFLAGS LDAP_LIBS' # 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' runstatedir='${localstatedir}/run' 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 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=`printf "%s\n" "$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=`printf "%s\n" "$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 ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -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=`printf "%s\n" "$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=`printf "%s\n" "$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. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$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" ;; *) printf "%s\n" "$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 runstatedir 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 || printf "%s\n" 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 dovecot-pigeonhole 2.4.2 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] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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/dovecot-pigeonhole] --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 System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of dovecot-pigeonhole 2.4.2:";; 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") --enable-maintainer-mode enable 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 --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-hardening=yes Enable various hardenings (default: yes) --enable-ubsan Enable undefined behaviour sanitizes (default=no) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-dovecot=DIR Dovecot base directory --with-dovecot-install-dirs Use install directories configured for Dovecot (default) --with-retpoline= Retpoline mitigation choice (default: keep) --with-moduledir=DIR Base directory for dynamically loadable modules --with-unfinished-features Build unfinished new features/extensions (default=no) --with-docs Install documentation (default=yes) --with-managesieve Build ManageSieve service (default=yes) --with-ldap=yes|plugin Build with LDAP support (default=no) 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 LT_SYS_LIBRARY_PATH User-defined run-time library search path. VALGRIND Path to valgrind PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path LDAP_CFLAGS C compiler flags for LDAP, overriding pkg-config LDAP_LIBS linker flags for LDAP, overriding pkg-config 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 . _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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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 configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. 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 printf "%s\n" "$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 dovecot-pigeonhole configure 2.4.2 generated by GNU Autoconf 2.71 Copyright (C) 2021 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 conftest.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop 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 $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ #include #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 (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac 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 dovecot-pigeonhole $as_me 2.4.2, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "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=`printf "%s\n" "$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=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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 printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$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 printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*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 do not provoke an error unfortunately, instead are silently treated as an "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 is necessary to write \x00 == 0 to get something that is 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 **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="run-test.sh.in config.guess config.sub ltmain.sh compile missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}/build-aux" # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$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. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" 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,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-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 printf "%s\n" "#define PIGEONHOLE_ABI_VERSION \"2.4.ABIv2\"" >>confdefs.h # Autoheader is not needed and does more harm than good for this package. However, it is # tightly integrated in autoconf/automake and therefore it is difficult not to use it. As # a workaround we give autoheader a dummy config header to chew on and we handle the # real config header ourselves. ac_config_headers="$ac_config_headers dummy-config.h pigeonhole-config.h" printf "%s\n" "#define PIGEONHOLE_NAME \"Pigeonhole\"" >>confdefs.h printf "%s\n" "#define PIGEONHOLE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h am__api_version='1.16' # 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. 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+y}; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$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' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "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=`printf "%s\n" "$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 MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 ('*'coreutils) '* | \ 'BusyBox '* | \ '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+y}; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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+y} 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} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$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='dovecot-pigeonhole' VERSION='2.4.2' # 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 (and possibly the TAP driver). 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 plaintar pax cpio none' # 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` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether UID '$am_uid' is supported by ustar format" >&5 printf %s "checking whether UID '$am_uid' is supported by ustar format... " >&6; } if test $am_uid -le $am_max_uid; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } _am_tools=none fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GID '$am_gid' is supported by ustar format" >&5 printf %s "checking whether GID '$am_gid' is supported by ustar format... " >&6; } if test $am_gid -le $am_max_gid; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } _am_tools=none fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5 printf %s "checking how to create a ustar tar archive... " >&6; } # 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_ustar-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar -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 ustar -w "$$tardir"' am__tar_='pax -L -x ustar -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H ustar -L' am__tar_='find "$tardir" -print | cpio -o -H ustar -L' am__untar='cpio -i -H ustar -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_ustar}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: cat conftest.dir/file" >&5 (cat conftest.dir/file) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if test ${am_cv_prog_tar_ustar+y} then : printf %s "(cached) " >&6 else $as_nop am_cv_prog_tar_ustar=$_am_tool fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5 printf "%s\n" "$am_cv_prog_tar_ustar" >&6; } # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # 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 # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$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='\' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else $as_nop USE_MAINTAINER_MODE=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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}clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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="clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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. printf "%s\n" "$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 -version; 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\"" printf "%s\n" "$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 printf "%s\n" "$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 (void) { ; 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$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+y} && 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 $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$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 (void) { 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$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 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$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_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; 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 ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _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 conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} 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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$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 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "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 test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" 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. # 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. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$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. # 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. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_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 do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "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_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_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_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "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_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_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_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$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 DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DUMPBIN="$ac_prog" printf "%s\n" "$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_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$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 FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_FILECMD="file" printf "%s\n" "$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_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$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 OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OBJDUMP="objdump" printf "%s\n" "$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_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$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 DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DLLTOOL="dlltool" printf "%s\n" "$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_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$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 AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_AR="$ac_prog" printf "%s\n" "$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_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$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 RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_RANLIB="ranlib" printf "%s\n" "$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_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_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 do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop 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 cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext 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 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$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 MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_MANIFEST_TOOL="mt" printf "%s\n" "$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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$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 DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DSYMUTIL="dsymutil" printf "%s\n" "$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_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$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 NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_NMEDIT="nmedit" printf "%s\n" "$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_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$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 LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_LIPO="lipo" printf "%s\n" "$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_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$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 OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OTOOL="otool" printf "%s\n" "$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_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$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 OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OTOOL64="otool64" printf "%s\n" "$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_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_shared=yes fi # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC 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 # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $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. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $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. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } 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 CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: # Couple with Dovecot # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Werror -Wunknown-warning-option" >&5 printf %s "checking whether C compiler handles -Werror -Wunknown-warning-option... " >&6; } if test ${gl_cv_warn_c__Werror__Wunknown_warning_option+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Werror -Wunknown-warning-option" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__Werror__Wunknown_warning_option=yes else $as_nop gl_cv_warn_c__Werror__Wunknown_warning_option=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Werror__Wunknown_warning_option" >&5 printf "%s\n" "$gl_cv_warn_c__Werror__Wunknown_warning_option" >&6; } if test "x$gl_cv_warn_c__Werror__Wunknown_warning_option" = xyes then : gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror' else $as_nop gl_unknown_warnings_are_errors= fi # Check whether --with-dovecot was given. if test ${with_dovecot+y} then : withval=$with_dovecot; dovecotdir="$withval" else $as_nop dc_prefix=$prefix test "x$dc_prefix" = xNONE && dc_prefix=$ac_default_prefix dovecotdir="$dc_prefix/lib/dovecot" fi # Check whether --with-dovecot-install-dirs was given. if test ${with_dovecot_install_dirs+y} then : withval=$with_dovecot_install_dirs; if test x$withval = xno then : use_install_dirs=no else $as_nop use_install_dirs=yes fi else $as_nop use_install_dirs=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for \"$dovecotdir/dovecot-config\"" >&5 printf %s "checking for \"$dovecotdir/dovecot-config\"... " >&6; } if test -f "$dovecotdir/dovecot-config" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dovecotdir/dovecot-config" >&5 printf "%s\n" "$dovecotdir/dovecot-config" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5 printf "%s\n" "not found" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5 printf "%s\n" "$as_me: " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Use --with-dovecot=DIR to provide the path to the dovecot-config file." >&5 printf "%s\n" "$as_me: Use --with-dovecot=DIR to provide the path to the dovecot-config file." >&6;} as_fn_error $? "dovecot-config not found" "$LINENO" 5 fi old=`pwd` cd $dovecotdir abs_dovecotdir=`pwd` cd $old DISTCHECK_CONFIGURE_FLAGS="--with-dovecot=$abs_dovecotdir --without-dovecot-install-dirs" ORIG_CFLAGS="$CFLAGS" ORIG_LDFLAGS="$LDFLAGS" ORIG_BINARY_CFLAGS="$BINARY_CFLAGS" ORIG_BINARY_LDFLAGS="$BINARY_LDFLAGS" eval `$GREP -i '^dovecot_[a-z_]*=' "$dovecotdir"/dovecot-config` eval `$GREP '^LIBDOVECOT[A-Z0-9_]*=' "$dovecotdir"/dovecot-config` CFLAGS="$ORIG_CFLAGS" LDFLAGS="$ORIG_LDFLAGS" BINARY_CFLAGS="$ORIG_BINARY_CFLAGS" BINARY_LDFLAGS="$ORIG_BINARY_LDFLAGS" dovecot_installed_moduledir="$dovecot_moduledir" if test "$use_install_dirs" = "no" then : dovecot_pkgincludedir='$(pkgincludedir)' dovecot_pkglibdir='$(pkglibdir)' dovecot_pkglibexecdir='$(libexecdir)/dovecot' dovecot_docdir='$(docdir)' dovecot_moduledir='$(moduledir)' dovecot_statedir='$(statedir)' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC is clang 3.3+" >&5 printf %s "checking whether $CC is clang 3.3+... " >&6; } if $CC -dM -E -x c /dev/null | $GREP __clang__ > /dev/null 2>&1 then : have_clang=yes # buffer_t usage triggers this warning { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-default-const-init-field-unsafe" >&5 printf %s "checking whether C compiler handles -Wno-default-const-init-field-unsafe... " >&6; } if test ${gl_cv_warn_c__Wno_default_const_init_field_unsafe+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wdefault-const-init-field-unsafe" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__Wno_default_const_init_field_unsafe=yes else $as_nop gl_cv_warn_c__Wno_default_const_init_field_unsafe=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_default_const_init_field_unsafe" >&5 printf "%s\n" "$gl_cv_warn_c__Wno_default_const_init_field_unsafe" >&6; } if test "x$gl_cv_warn_c__Wno_default_const_init_field_unsafe" = xyes then : as_fn_append WARN_CFLAGS " -Wno-default-const-init-field-unsafe" fi AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS" else $as_nop have_clang=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_clang" >&5 printf "%s\n" "$have_clang" >&6; } if test $have_clang = yes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wstrict-bool" >&5 printf %s "checking whether C compiler handles -Wstrict-bool... " >&6; } if test ${gl_cv_warn_c__Wstrict_bool+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wstrict-bool" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__Wstrict_bool=yes else $as_nop gl_cv_warn_c__Wstrict_bool=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wstrict_bool" >&5 printf "%s\n" "$gl_cv_warn_c__Wstrict_bool" >&6; } if test "x$gl_cv_warn_c__Wstrict_bool" = xyes then : printf "%s\n" "#define HAVE_STRICT_BOOL /**/" >>confdefs.h fi 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 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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}clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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="clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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. printf "%s\n" "$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 -version; 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\"" printf "%s\n" "$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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; 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 ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _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 conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$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 depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$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 "$ac_prog_cc_stdc" = "c89" || test "$ac_prog_cc_std" = "no" || test "$ac_cv_prog_cc_c99" = "no" then : as_fn_error $? "C99 capable compiler required" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Which $CC -std flag to use" >&5 printf %s "checking Which $CC -std flag to use... " >&6; } old_cflags=$CFLAGS std= for mystd in gnu11 gnu99 c11 c99; do CFLAGS="-std=$mystd" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : AM_CFLAGS="$AM_CFLAGS $CFLAGS" std=$mystd break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $std" >&5 printf "%s\n" "$std" >&6; } CFLAGS="$old_cflags" if test "x$ac_cv_c_compiler_gnu" = "xyes" then : AM_CFLAGS="$AM_CFLAGS -Wall -W -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wchar-subscripts -Wformat=2 -Wbad-function-cast" if test "$have_clang" = "yes" then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 3) # error new clang #endif int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop AM_CFLAGS="$AM_CFLAGS -Wno-duplicate-decl-specifier" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext else $as_nop AM_CFLAGS="$AM_CFLAGS -fno-builtin-strftime" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if __GNUC__ < 4 # error old gcc #endif int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : AM_CFLAGS="$AM_CFLAGS -Wstrict-aliasing=2" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext old_cflags=$CFLAGS CFLAGS="$CFLAGS -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ const unsigned char foo[4] __attribute__((nonstring)) = "1234"; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : printf "%s\n" "#define HAVE_ATTR_NONSTRING /**/" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$old_cflags" fi # Check whether --enable-hardening was given. if test ${enable_hardening+y} then : enableval=$enable_hardening; enable_hardening=$enableval else $as_nop enable_hardening=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Whether to enable hardening" >&5 printf %s "checking Whether to enable hardening... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_hardening" >&5 printf "%s\n" "$enable_hardening" >&6; } PIE_CFLAGS= PIE_LDFLAGS= if test "$enable_hardening" = yes then : OLD_CFLAGS=$CFLAGS case "$host" in *-*-mingw* | *-*-msvc* | *-*-cygwin* ) ;; *) CFLAGS="-fPIE -DPIE" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -pie" >&5 printf %s "checking whether C compiler handles -pie... " >&6; } if test ${gl_cv_warn_c__pie+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -pie" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__pie=yes else $as_nop gl_cv_warn_c__pie=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__pie" >&5 printf "%s\n" "$gl_cv_warn_c__pie" >&6; } if test "x$gl_cv_warn_c__pie" = xyes then : PIE_CFLAGS="-fPIE -DPIE" PIE_LDFLAGS="-pie" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wl,-pie" >&5 printf %s "checking whether C compiler handles -Wl,-pie... " >&6; } if test ${gl_cv_warn_c__Wl__pie+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wl,-pie" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__Wl__pie=yes else $as_nop gl_cv_warn_c__Wl__pie=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wl__pie" >&5 printf "%s\n" "$gl_cv_warn_c__Wl__pie" >&6; } if test "x$gl_cv_warn_c__Wl__pie" = xyes then : PIE_CFLAGS="-fPIE -DPIE" PIE_LDFLAGS="-Wl,-pie" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not supported" >&5 printf "%s\n" "not supported" >&6; } fi fi esac CFLAGS=$OLD_CFLAGS fi if test "$enable_hardening" = yes then : case "$host" in *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fstack-protector-strong" >&5 printf %s "checking whether C compiler handles -fstack-protector-strong... " >&6; } if test ${gl_cv_warn_c__fstack_protector_strong+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fstack-protector-strong" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fstack_protector_strong=yes else $as_nop gl_cv_warn_c__fstack_protector_strong=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fstack_protector_strong" >&5 printf "%s\n" "$gl_cv_warn_c__fstack_protector_strong" >&6; } if test "x$gl_cv_warn_c__fstack_protector_strong" = xyes then : AM_CFLAGS="$AM_CFLAGS -fstack-protector-strong" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fstack-protector" >&5 printf %s "checking whether C compiler handles -fstack-protector... " >&6; } if test ${gl_cv_warn_c__fstack_protector+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fstack-protector" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fstack_protector=yes else $as_nop gl_cv_warn_c__fstack_protector=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fstack_protector" >&5 printf "%s\n" "$gl_cv_warn_c__fstack_protector" >&6; } if test "x$gl_cv_warn_c__fstack_protector" = xyes then : AM_CFLAGS="$AM_CFLAGS -fstack-protector" fi fi esac fi if test "$enable_hardening" = yes then : case "$host" in *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" >&5 printf %s "checking whether C compiler handles -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2... " >&6; } if test ${gl_cv_warn_c__O2__U_FORTIFY_SOURCE__D_FORTIFY_SOURCE_2+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__O2__U_FORTIFY_SOURCE__D_FORTIFY_SOURCE_2=yes else $as_nop gl_cv_warn_c__O2__U_FORTIFY_SOURCE__D_FORTIFY_SOURCE_2=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__O2__U_FORTIFY_SOURCE__D_FORTIFY_SOURCE_2" >&5 printf "%s\n" "$gl_cv_warn_c__O2__U_FORTIFY_SOURCE__D_FORTIFY_SOURCE_2" >&6; } if test "x$gl_cv_warn_c__O2__U_FORTIFY_SOURCE__D_FORTIFY_SOURCE_2" = xyes then : AM_CFLAGS="$AM_CFLAGS -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" fi ;; esac fi # Check whether --with-retpoline was given. if test ${with_retpoline+y} then : withval=$with_retpoline; with_retpoline=$withval else $as_nop with_retpoline=keep fi if test "$enable_hardening" = yes then : case "$host" in *) as_gl_Warn=`printf "%s\n" "gl_cv_warn_c_-mfunction-return=$with_retpoline" | $as_tr_sh` gl_positive="-mfunction-return=$with_retpoline" case $gl_positive in -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -mfunction-return=$with_retpoline" >&5 printf %s "checking whether C compiler handles -mfunction-return=$with_retpoline... " >&6; } if eval test \${$as_gl_Warn+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors $gl_positive" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_gl_Warn=yes" else $as_nop eval "$as_gl_Warn=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi eval ac_res=\$$as_gl_Warn { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_gl_Warn"\" = x"yes" then : AM_CFLAGS="$AM_CFLAGS -mfunction-return=$with_retpoline" fi as_gl_Warn=`printf "%s\n" "gl_cv_warn_c_-mindirect-branch=$with_retpoline" | $as_tr_sh` gl_positive="-mindirect-branch=$with_retpoline" case $gl_positive in -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -mindirect-branch=$with_retpoline" >&5 printf %s "checking whether C compiler handles -mindirect-branch=$with_retpoline... " >&6; } if eval test \${$as_gl_Warn+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors $gl_positive" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_gl_Warn=yes" else $as_nop eval "$as_gl_Warn=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi eval ac_res=\$$as_gl_Warn { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_gl_Warn"\" = x"yes" then : AM_CFLAGS="$AM_CFLAGS -mindirect-branch=$with_retpoline" fi esac fi RELRO_LDFLAGS= if test "$enable_hardening" = yes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for how to force completely read-only GOT table" >&5 printf %s "checking for how to force completely read-only GOT table... " >&6; } ld_help=`$CC -Wl,-help 2>&1` case $ld_help in *"-z relro"*) RELRO_LDFLAGS="-Wl,-z -Wl,relro" ;; esac case $ld_help in *"-z now"*) RELRO_LDFLAGS="$RELRO_LDFLAGS -Wl,-z -Wl,now" ;; esac if test "x$RELRO_LDFLAGS" != "x" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RELRO_LDFLAGS" >&5 printf "%s\n" "$RELRO_LDFLAGS" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 printf "%s\n" "unknown" >&6; } fi fi # Check whether --enable-ubsan was given. if test ${enable_ubsan+y} then : enableval=$enable_ubsan; want_ubsan=yes else $as_nop want_ubsan=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we want undefined behaviour sanitizer" >&5 printf %s "checking whether we want undefined behaviour sanitizer... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $want_ubsan" >&5 printf "%s\n" "$want_ubsan" >&6; } if test x$want_ubsan = xyes then : san_flags="" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fsanitize=undefined" >&5 printf %s "checking whether C compiler handles -fsanitize=undefined... " >&6; } if test ${gl_cv_warn_c__fsanitize_undefined+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fsanitize=undefined" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fsanitize_undefined=yes else $as_nop gl_cv_warn_c__fsanitize_undefined=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fsanitize_undefined" >&5 printf "%s\n" "$gl_cv_warn_c__fsanitize_undefined" >&6; } if test "x$gl_cv_warn_c__fsanitize_undefined" = xyes then : san_flags="$san_flags -fsanitize=undefined -fno-sanitize=function,vptr" printf "%s\n" "#define HAVE_FSANITIZE_UNDEFINED 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fno-sanitize=nonnull-attribute" >&5 printf %s "checking whether C compiler handles -fno-sanitize=nonnull-attribute... " >&6; } if test ${gl_cv_warn_c__fno_sanitize_nonnull_attribute+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fno-sanitize=nonnull-attribute" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fno_sanitize_nonnull_attribute=yes else $as_nop gl_cv_warn_c__fno_sanitize_nonnull_attribute=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fno_sanitize_nonnull_attribute" >&5 printf "%s\n" "$gl_cv_warn_c__fno_sanitize_nonnull_attribute" >&6; } if test "x$gl_cv_warn_c__fno_sanitize_nonnull_attribute" = xyes then : san_flags="$san_flags -fno-sanitize=nonnull-attribute" printf "%s\n" "#define HAVE_FNO_SANITIZE_NONNULL_ATTRIBUTE 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fsanitize=implicit-integer-truncation" >&5 printf %s "checking whether C compiler handles -fsanitize=implicit-integer-truncation... " >&6; } if test ${gl_cv_warn_c__fsanitize_implicit_integer_truncation+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fsanitize=implicit-integer-truncation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fsanitize_implicit_integer_truncation=yes else $as_nop gl_cv_warn_c__fsanitize_implicit_integer_truncation=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fsanitize_implicit_integer_truncation" >&5 printf "%s\n" "$gl_cv_warn_c__fsanitize_implicit_integer_truncation" >&6; } if test "x$gl_cv_warn_c__fsanitize_implicit_integer_truncation" = xyes then : san_flags="$san_flags -fsanitize=implicit-integer-truncation" printf "%s\n" "#define HAVE_FSANITIZE_IMPLICIT_INTEGER_TRUNCATION 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fsanitize=local-bounds" >&5 printf %s "checking whether C compiler handles -fsanitize=local-bounds... " >&6; } if test ${gl_cv_warn_c__fsanitize_local_bounds+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fsanitize=local-bounds" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fsanitize_local_bounds=yes else $as_nop gl_cv_warn_c__fsanitize_local_bounds=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fsanitize_local_bounds" >&5 printf "%s\n" "$gl_cv_warn_c__fsanitize_local_bounds" >&6; } if test "x$gl_cv_warn_c__fsanitize_local_bounds" = xyes then : san_flags="$san_flags -fsanitize=local-bounds" printf "%s\n" "#define HAVE_FSANITIZE_LOCAL_BOUNDS 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fsanitize=integer" >&5 printf %s "checking whether C compiler handles -fsanitize=integer... " >&6; } if test ${gl_cv_warn_c__fsanitize_integer+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fsanitize=integer" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fsanitize_integer=yes else $as_nop gl_cv_warn_c__fsanitize_integer=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fsanitize_integer" >&5 printf "%s\n" "$gl_cv_warn_c__fsanitize_integer" >&6; } if test "x$gl_cv_warn_c__fsanitize_integer" = xyes then : san_flags="$san_flags -fsanitize=integer" printf "%s\n" "#define HAVE_FSANITIZE_INTEGER 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fsanitize=nullability" >&5 printf %s "checking whether C compiler handles -fsanitize=nullability... " >&6; } if test ${gl_cv_warn_c__fsanitize_nullability+y} then : printf %s "(cached) " >&6 else $as_nop gl_save_compiler_FLAGS="$CFLAGS" as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fsanitize=nullability" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gl_cv_warn_c__fsanitize_nullability=yes else $as_nop gl_cv_warn_c__fsanitize_nullability=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$gl_save_compiler_FLAGS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fsanitize_nullability" >&5 printf "%s\n" "$gl_cv_warn_c__fsanitize_nullability" >&6; } if test "x$gl_cv_warn_c__fsanitize_nullability" = xyes then : san_flags="$san_flags -fsanitize=nullability" printf "%s\n" "#define HAVE_FSANITIZE_NULLABILITY 1" >>confdefs.h fi if test "$san_flags" != "" then : AM_CFLAGS="$AM_CFLAGS $san_flags -U_FORTIFY_SOURCE -g -ggdb3 -O0 -fno-omit-frame-pointer" printf "%s\n" "#define HAVE_UNDEFINED_SANITIZER 1" >>confdefs.h else $as_nop as_fn_error $? "No undefined sanitizer support in your compiler" "$LINENO" 5 fi san_flags="" fi if test x$DOVECOT_HAVE_MAIL_UTF8 = xyes then : printf "%s\n" "#define DOVECOT_HAVE_MAIL_UTF8 /**/" >>confdefs.h fi if test "$DOVECOT_INSTALLED" = "yes"; then DOVECOT_INSTALLED_TRUE= DOVECOT_INSTALLED_FALSE='#' else DOVECOT_INSTALLED_TRUE='#' DOVECOT_INSTALLED_FALSE= fi _plugin_deps=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether OS supports plugin dependencies" >&5 printf %s "checking whether OS supports plugin dependencies... " >&6; } case "$host_os" in darwin*) _plugin_deps=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $_plugin_deps" >&5 printf "%s\n" "$_plugin_deps" >&6; } if test "x$_plugin_deps" = "xyes"; then DOVECOT_PLUGIN_DEPS_TRUE= DOVECOT_PLUGIN_DEPS_FALSE='#' else DOVECOT_PLUGIN_DEPS_TRUE='#' DOVECOT_PLUGIN_DEPS_FALSE= fi unset _plugin_deps # Extract the first word of "valgrind", so it can be a program name with args. set dummy valgrind; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_VALGRIND+y} then : printf %s "(cached) " >&6 else $as_nop case $VALGRIND in [\\/]* | ?:[\\/]*) ac_cv_path_VALGRIND="$VALGRIND" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_VALGRIND="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$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_VALGRIND" && ac_cv_path_VALGRIND="reject" ;; esac fi VALGRIND=$ac_cv_path_VALGRIND if test -n "$VALGRIND"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $VALGRIND" >&5 printf "%s\n" "$VALGRIND" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "$VALGRIND" != reject then : RUN_TEST='$(LIBTOOL) execute $(SHELL) $(top_builddir)/build-aux/run-test.sh' else $as_nop RUN_TEST='' fi # Check whether --with-moduledir was given. if test ${with_moduledir+y} then : withval=$with_moduledir; moduledir="$withval" else $as_nop moduledir="\$(libdir)/dovecot" fi LIBDOVECOT_INCLUDE="$LIBDOVECOT_INCLUDE $LIBDOVECOT_STORAGE_INCLUDE" AM_CFLAGS="$AM_CFLAGS -I\$(top_srcdir) $EXTRA_CFLAGS" LIBS="$DOVECOT_LIBS" BINARY_LDFLAGS="$PIE_LDFLAGS $RELRO_LDFLAGS" BINARY_CFLAGS="$PIE_CFLAGS" PIGEONHOLE_ASSET_VERSION=2.4.2 if test "$PIGEONHOLE_ASSET_VERSION" = "0.0.0" then : PIGEONHOLE_ASSET_VERSION="main" fi if test "$PIGEONHOLE_ASSET_VERSION" = "" then : PIGEONHOLE_ASSET_VERSION="main" fi if test $DOVECOT_PRO_BUILD = "1" then : PIGEONHOLE_ASSET_URL="doc.dovecotpro.com" else $as_nop PIGEONHOLE_ASSET_URL="doc.dovecot.org" fi # Define Sieve documentation install dir # sieve_docdir='${dovecot_docdir}/sieve' WGET=${WGET-"${am_missing_run}wget"} # Extensions under development # # Check whether --with-unfinished-features was given. if test ${with_unfinished_features+y} then : withval=$with_unfinished_features; want=want_`echo unfinished_features|sed s/-/_/g` if test "$withval" = yes || test "$withval" = no || test "$withval" = auto then : eval $want=$withval elif test "$withval" = plugin then : if test "" = "plugin" then : eval $want=plugin else $as_nop as_fn_error $? "--with-unfinished_features=plugin not supported" "$LINENO" 5 fi elif test "$(echo $withval|grep -c '^/' 2>/dev/null)" -gt 0 then : as_fn_error $? "--with-unfinished_features=path not supported. You may want to use instead: CPPFLAGS=-I$withval/include LDFLAGS=-L$withval/lib ./configure --with-unfinished_features" "$LINENO" 5 else $as_nop as_fn_error $? "--with-unfinished_features: Unknown value: $withval" "$LINENO" 5 fi else $as_nop want_unfinished_features=no fi if test "$want_unfinished_features" = "yes"; then BUILD_UNFINISHED_TRUE= BUILD_UNFINISHED_FALSE='#' else BUILD_UNFINISHED_TRUE='#' BUILD_UNFINISHED_FALSE= fi if test "$want_unfinished_features" = "yes"; then printf "%s\n" "#define HAVE_SIEVE_UNFINISHED /**/" >>confdefs.h fi # Check whether --with-docs was given. if test ${with_docs+y} then : withval=$with_docs; want=want_`echo docs|sed s/-/_/g` if test "$withval" = yes || test "$withval" = no || test "$withval" = auto then : eval $want=$withval elif test "$withval" = plugin then : if test "" = "plugin" then : eval $want=plugin else $as_nop as_fn_error $? "--with-docs=plugin not supported" "$LINENO" 5 fi elif test "$(echo $withval|grep -c '^/' 2>/dev/null)" -gt 0 then : as_fn_error $? "--with-docs=path not supported. You may want to use instead: CPPFLAGS=-I$withval/include LDFLAGS=-L$withval/lib ./configure --with-docs" "$LINENO" 5 else $as_nop as_fn_error $? "--with-docs: Unknown value: $withval" "$LINENO" 5 fi else $as_nop want_docs=yes fi if test "$want_docs" = "yes"; then BUILD_DOCS_TRUE= BUILD_DOCS_FALSE='#' else BUILD_DOCS_TRUE='#' BUILD_DOCS_FALSE= fi # Check whether --with-managesieve was given. if test ${with_managesieve+y} then : withval=$with_managesieve; want=want_`echo managesieve|sed s/-/_/g` if test "$withval" = yes || test "$withval" = no || test "$withval" = auto then : eval $want=$withval elif test "$withval" = plugin then : if test "" = "plugin" then : eval $want=plugin else $as_nop as_fn_error $? "--with-managesieve=plugin not supported" "$LINENO" 5 fi elif test "$(echo $withval|grep -c '^/' 2>/dev/null)" -gt 0 then : as_fn_error $? "--with-managesieve=path not supported. You may want to use instead: CPPFLAGS=-I$withval/include LDFLAGS=-L$withval/lib ./configure --with-managesieve" "$LINENO" 5 else $as_nop as_fn_error $? "--with-managesieve: Unknown value: $withval" "$LINENO" 5 fi else $as_nop want_managesieve=yes fi if test "$want_managesieve" = "yes"; then BUILD_MANAGESIEVE_TRUE= BUILD_MANAGESIEVE_FALSE='#' else BUILD_MANAGESIEVE_TRUE='#' BUILD_MANAGESIEVE_FALSE= fi # Check whether --with-ldap was given. if test ${with_ldap+y} then : withval=$with_ldap; want=want_`echo ldap|sed s/-/_/g` if test "$withval" = yes || test "$withval" = no || test "$withval" = auto then : eval $want=$withval elif test "$withval" = plugin then : if test "plugin" = "plugin" then : eval $want=plugin else $as_nop as_fn_error $? "--with-ldap=plugin not supported" "$LINENO" 5 fi elif test "$(echo $withval|grep -c '^/' 2>/dev/null)" -gt 0 then : as_fn_error $? "--with-ldap=path not supported. You may want to use instead: CPPFLAGS=-I$withval/include LDFLAGS=-L$withval/lib ./configure --with-ldap" "$LINENO" 5 else $as_nop as_fn_error $? "--with-ldap: Unknown value: $withval" "$LINENO" 5 fi else $as_nop want_ldap=no fi # FIXME: Imported this from Dovecot auth for now. We're working on a proper # lib-ldap, but, until then, some code is duplicated. have_ldap=no if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi if test $want_ldap != no then : pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ldap >= 2.4" >&5 printf %s "checking for ldap >= 2.4... " >&6; } if test -n "$LDAP_CFLAGS"; then pkg_cv_LDAP_CFLAGS="$LDAP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ldap >= 2.4\""; } >&5 ($PKG_CONFIG --exists --print-errors "ldap >= 2.4") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LDAP_CFLAGS=`$PKG_CONFIG --cflags "ldap >= 2.4" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LDAP_LIBS"; then pkg_cv_LDAP_LIBS="$LDAP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ldap >= 2.4\""; } >&5 ($PKG_CONFIG --exists --print-errors "ldap >= 2.4") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LDAP_LIBS=`$PKG_CONFIG --libs "ldap >= 2.4" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LDAP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ldap >= 2.4" 2>&1` else LDAP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ldap >= 2.4" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LDAP_PKG_ERRORS" >&5 have_ldap=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } have_ldap=no else LDAP_CFLAGS=$pkg_cv_LDAP_CFLAGS LDAP_LIBS=$pkg_cv_LDAP_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } have_ldap=yes fi if test $have_ldap = no then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ldap_init in -lldap" >&5 printf %s "checking for ldap_init in -lldap... " >&6; } if test ${ac_cv_lib_ldap_ldap_init+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $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. */ char ldap_init (); int main (void) { return ldap_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_ldap_ldap_init=yes else $as_nop ac_cv_lib_ldap_ldap_init=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_init" >&5 printf "%s\n" "$ac_cv_lib_ldap_ldap_init" >&6; } if test "x$ac_cv_lib_ldap_ldap_init" = xyes then : ac_fn_c_check_header_compile "$LINENO" "ldap.h" "ac_cv_header_ldap_h" "$ac_includes_default" if test "x$ac_cv_header_ldap_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ldap_initialize in -lldap" >&5 printf %s "checking for ldap_initialize in -lldap... " >&6; } if test ${ac_cv_lib_ldap_ldap_initialize+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $LDAP_LIBS $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. */ char ldap_initialize (); int main (void) { return ldap_initialize (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_ldap_ldap_initialize=yes else $as_nop ac_cv_lib_ldap_ldap_initialize=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_initialize" >&5 printf "%s\n" "$ac_cv_lib_ldap_ldap_initialize" >&6; } if test "x$ac_cv_lib_ldap_ldap_initialize" = xyes then : : else $as_nop as_fn_error $? " cannot build with LDAP support: function ldap_initialize() not found (OpenLDAP >= 2.4 required) " "$LINENO" 5 fi LDAP_LIBS="-lldap" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ber_free in -lldap" >&5 printf %s "checking for ber_free in -lldap... " >&6; } if test ${ac_cv_lib_ldap_ber_free+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $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. */ char ber_free (); int main (void) { return ber_free (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_ldap_ber_free=yes else $as_nop ac_cv_lib_ldap_ber_free=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ber_free" >&5 printf "%s\n" "$ac_cv_lib_ldap_ber_free" >&6; } if test "x$ac_cv_lib_ldap_ber_free" = xyes then : # do nothing, default is to add -lldap to LIBS : else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ber_free in -llber" >&5 printf %s "checking for ber_free in -llber... " >&6; } if test ${ac_cv_lib_lber_ber_free+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-llber $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. */ char ber_free (); int main (void) { return ber_free (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_lber_ber_free=yes else $as_nop ac_cv_lib_lber_ber_free=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lber_ber_free" >&5 printf "%s\n" "$ac_cv_lib_lber_ber_free" >&6; } if test "x$ac_cv_lib_lber_ber_free" = xyes then : LDAP_LIBS="$LDAP_LIBS -llber" fi fi have_ldap=yes else $as_nop if test $want_ldap != auto then : as_fn_error $? "cannot build with LDAP support: ldap.h not found" "$LINENO" 5 fi fi else $as_nop if test $want_ldap != auto then : as_fn_error $? "cannot build with LDAP support: libldap not found" "$LINENO" 5 fi fi fi fi if test $have_ldap = yes then : orig_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LIBDOVECOT_INCLUDE" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "config.h" #ifndef HAVE_LDAP # error Dovecot core not compiled with LDAP #endif int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop if test $want_ldap != auto then : as_fn_error $? "cannot build with LDAP support: Dovecot core not built with LDAP" "$LINENO" 5 fi have_ldap=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CPPFLAGS=$orig_CPPFLAGS fi if test $have_ldap = no then : not_scriptloc="$not_scriptloc ldap" else $as_nop if test $want_ldap != plugin then : printf "%s\n" "#define SIEVE_BUILTIN_LDAP /**/" >>confdefs.h fi printf "%s\n" "#define STORAGE_LDAP /**/" >>confdefs.h ac_fn_c_check_header_compile "$LINENO" "sasl.h" "ac_cv_header_sasl_h" "$ac_includes_default" if test "x$ac_cv_header_sasl_h" = xyes then : printf "%s\n" "#define HAVE_SASL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sasl/sasl.h" "ac_cv_header_sasl_sasl_h" "$ac_includes_default" if test "x$ac_cv_header_sasl_sasl_h" = xyes then : printf "%s\n" "#define HAVE_SASL_SASL_H 1" >>confdefs.h fi scriptloc="$scriptloc ldap" if test $want_ldap = plugin then : have_ldap_plugin=yes scriptloc="$scriptloc (plugin)" fi fi if test "$have_ldap_plugin" = "yes"; then LDAP_PLUGIN_TRUE= LDAP_PLUGIN_FALSE='#' else LDAP_PLUGIN_TRUE='#' LDAP_PLUGIN_FALSE= fi libsieve_setting_dirs="\ $srcdir/src/lib-sieve/storage/data \ $srcdir/src/lib-sieve/storage/file \ $srcdir/src/lib-sieve/storage/dict \ $srcdir/src/lib-sieve/plugins/vacation \ $srcdir/src/lib-sieve/plugins/subaddress \ $srcdir/src/lib-sieve/plugins/comparator-i-ascii-numeric \ $srcdir/src/lib-sieve/plugins/relational \ $srcdir/src/lib-sieve/plugins/regex \ $srcdir/src/lib-sieve/plugins/copy \ $srcdir/src/lib-sieve/plugins/imap4flags \ $srcdir/src/lib-sieve/plugins/include \ $srcdir/src/lib-sieve/plugins/body \ $srcdir/src/lib-sieve/plugins/variables \ $srcdir/src/lib-sieve/plugins/enotify \ $srcdir/src/lib-sieve/plugins/environment \ $srcdir/src/lib-sieve/plugins/mailbox \ $srcdir/src/lib-sieve/plugins/date \ $srcdir/src/lib-sieve/plugins/spamvirustest \ $srcdir/src/lib-sieve/plugins/ihave \ $srcdir/src/lib-sieve/plugins/editheader \ $srcdir/src/lib-sieve/plugins/extlists \ $srcdir/src/lib-sieve/plugins/duplicate \ $srcdir/src/lib-sieve/plugins/index \ $srcdir/src/lib-sieve/plugins/metadata \ $srcdir/src/lib-sieve/plugins/mime \ $srcdir/src/lib-sieve/plugins/special-use \ $srcdir/src/lib-sieve/plugins/vnd.dovecot/debug \ $srcdir/src/lib-sieve/plugins/vnd.dovecot/environment \ $srcdir/src/lib-sieve/plugins/vnd.dovecot/report" if test $want_ldap != plugin; then libsieve_setting_dirs="$libsieve_setting_dirs \ $srcdir/src/lib-sieve/storage/ldap" fi libsieve_headers= libsieve_c_files= non_libsieve_headers= non_libsieve_c_files= all_files=`find $srcdir/src -name '*.[ch]' | grep -v '/src/plugins/settings/' | grep -v '/src/managesieve' | grep -v '/test-' | xargs grep '\\(struct setting_parser_info [a-z]\\)\\|\\(struct service_settings [a-z]\\)\\|\\(\\)' | sed 's/:.*//' | sort | uniq` for file in $all_files; do dir=`echo "$file" | sed 's:/[^/]*$::'` if echo "$libsieve_setting_dirs" | grep "$dir" >/dev/null; then if echo "$file" | grep '\.h$' >/dev/null; then libsieve_headers="$libsieve_headers $file" else libsieve_c_files="$libsieve_c_files $file" fi else if echo "$file" | grep '\.h$' >/dev/null; then non_libsieve_headers="$non_libsieve_headers $file" else non_libsieve_c_files="$non_libsieve_c_files $file" fi fi done # list headers first, C files last SETTING_FILES=`echo $libsieve_headers $non_libsieve_headers $non_libsieve_c_files | sed -e s,$srcdir/src,./src,g -e 's,./src,$(top_srcdir)/src,g'` SETTING_LINKED_FILES=`echo $libsieve_c_files | sed -e s,$srcdir/src,./src,g -e 's,./src,$(top_srcdir)/src,g'` LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" if test "$AR_FLAGS" = "cru" then : AR_FLAGS="cr" fi ac_config_files="$ac_config_files Makefile doc/Makefile doc/man/Makefile doc/example-config/Makefile doc/example-config/conf.d/Makefile doc/rfc/Makefile doc/extensions/Makefile doc/locations/Makefile doc/plugins/Makefile src/Makefile src/lib-sieve/Makefile src/lib-sieve/util/Makefile src/lib-sieve/storage/Makefile src/lib-sieve/storage/data/Makefile src/lib-sieve/storage/file/Makefile src/lib-sieve/storage/dict/Makefile src/lib-sieve/storage/ldap/Makefile src/lib-sieve/plugins/Makefile src/lib-sieve/plugins/vacation/Makefile src/lib-sieve/plugins/subaddress/Makefile src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile src/lib-sieve/plugins/relational/Makefile src/lib-sieve/plugins/regex/Makefile src/lib-sieve/plugins/imap4flags/Makefile src/lib-sieve/plugins/copy/Makefile src/lib-sieve/plugins/include/Makefile src/lib-sieve/plugins/body/Makefile src/lib-sieve/plugins/variables/Makefile src/lib-sieve/plugins/enotify/Makefile src/lib-sieve/plugins/enotify/mailto/Makefile src/lib-sieve/plugins/environment/Makefile src/lib-sieve/plugins/mailbox/Makefile src/lib-sieve/plugins/date/Makefile src/lib-sieve/plugins/spamvirustest/Makefile src/lib-sieve/plugins/ihave/Makefile src/lib-sieve/plugins/editheader/Makefile src/lib-sieve/plugins/metadata/Makefile src/lib-sieve/plugins/duplicate/Makefile src/lib-sieve/plugins/index/Makefile src/lib-sieve/plugins/mime/Makefile src/lib-sieve/plugins/special-use/Makefile src/lib-sieve/plugins/extlists/Makefile src/lib-sieve/plugins/vnd.dovecot/Makefile src/lib-sieve/plugins/vnd.dovecot/debug/Makefile src/lib-sieve/plugins/vnd.dovecot/environment/Makefile src/lib-sieve/plugins/vnd.dovecot/report/Makefile src/lib-sieve-tool/Makefile src/lib-managesieve/Makefile src/plugins/Makefile src/plugins/doveadm-sieve/Makefile src/plugins/lda-sieve/Makefile src/plugins/sieve-extprograms/Makefile src/plugins/imapsieve/Makefile src/plugins/imap-filter-sieve/Makefile src/plugins/settings/Makefile src/sieve-tools/Makefile src/managesieve/Makefile src/managesieve-login/Makefile src/testsuite/Makefile build-aux/run-test.sh stamp.h" 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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+y} || &/ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "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 "${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 "${DOVECOT_INSTALLED_TRUE}" && test -z "${DOVECOT_INSTALLED_FALSE}"; then as_fn_error $? "conditional \"DOVECOT_INSTALLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DOVECOT_PLUGIN_DEPS_TRUE}" && test -z "${DOVECOT_PLUGIN_DEPS_FALSE}"; then as_fn_error $? "conditional \"DOVECOT_PLUGIN_DEPS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_UNFINISHED_TRUE}" && test -z "${BUILD_UNFINISHED_FALSE}"; then as_fn_error $? "conditional \"BUILD_UNFINISHED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DOCS_TRUE}" && test -z "${BUILD_DOCS_FALSE}"; then as_fn_error $? "conditional \"BUILD_DOCS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MANAGESIEVE_TRUE}" && test -z "${BUILD_MANAGESIEVE_FALSE}"; then as_fn_error $? "conditional \"BUILD_MANAGESIEVE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LDAP_PLUGIN_TRUE}" && test -z "${LDAP_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"LDAP_PLUGIN\" 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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_nop 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_nop 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 || printf "%s\n" 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 # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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=`printf "%s\n" "$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 || printf "%s\n" 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 dovecot-pigeonhole $as_me 2.4.2, which was generated by GNU Autoconf 2.71. 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 ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ dovecot-pigeonhole config.status 2.4.2 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 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 ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$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=`printf "%s\n" "$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 ) printf "%s\n" "$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 \printf "%s\n" "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 printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _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 "dummy-config.h") CONFIG_HEADERS="$CONFIG_HEADERS dummy-config.h" ;; "pigeonhole-config.h") CONFIG_HEADERS="$CONFIG_HEADERS pigeonhole-config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/man/Makefile") CONFIG_FILES="$CONFIG_FILES doc/man/Makefile" ;; "doc/example-config/Makefile") CONFIG_FILES="$CONFIG_FILES doc/example-config/Makefile" ;; "doc/example-config/conf.d/Makefile") CONFIG_FILES="$CONFIG_FILES doc/example-config/conf.d/Makefile" ;; "doc/rfc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/rfc/Makefile" ;; "doc/extensions/Makefile") CONFIG_FILES="$CONFIG_FILES doc/extensions/Makefile" ;; "doc/locations/Makefile") CONFIG_FILES="$CONFIG_FILES doc/locations/Makefile" ;; "doc/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES doc/plugins/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/lib-sieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/Makefile" ;; "src/lib-sieve/util/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/util/Makefile" ;; "src/lib-sieve/storage/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/storage/Makefile" ;; "src/lib-sieve/storage/data/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/storage/data/Makefile" ;; "src/lib-sieve/storage/file/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/storage/file/Makefile" ;; "src/lib-sieve/storage/dict/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/storage/dict/Makefile" ;; "src/lib-sieve/storage/ldap/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/storage/ldap/Makefile" ;; "src/lib-sieve/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/Makefile" ;; "src/lib-sieve/plugins/vacation/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/vacation/Makefile" ;; "src/lib-sieve/plugins/subaddress/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/subaddress/Makefile" ;; "src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile" ;; "src/lib-sieve/plugins/relational/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/relational/Makefile" ;; "src/lib-sieve/plugins/regex/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/regex/Makefile" ;; "src/lib-sieve/plugins/imap4flags/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/imap4flags/Makefile" ;; "src/lib-sieve/plugins/copy/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/copy/Makefile" ;; "src/lib-sieve/plugins/include/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/include/Makefile" ;; "src/lib-sieve/plugins/body/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/body/Makefile" ;; "src/lib-sieve/plugins/variables/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/variables/Makefile" ;; "src/lib-sieve/plugins/enotify/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/enotify/Makefile" ;; "src/lib-sieve/plugins/enotify/mailto/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/enotify/mailto/Makefile" ;; "src/lib-sieve/plugins/environment/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/environment/Makefile" ;; "src/lib-sieve/plugins/mailbox/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/mailbox/Makefile" ;; "src/lib-sieve/plugins/date/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/date/Makefile" ;; "src/lib-sieve/plugins/spamvirustest/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/spamvirustest/Makefile" ;; "src/lib-sieve/plugins/ihave/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/ihave/Makefile" ;; "src/lib-sieve/plugins/editheader/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/editheader/Makefile" ;; "src/lib-sieve/plugins/metadata/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/metadata/Makefile" ;; "src/lib-sieve/plugins/duplicate/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/duplicate/Makefile" ;; "src/lib-sieve/plugins/index/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/index/Makefile" ;; "src/lib-sieve/plugins/mime/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/mime/Makefile" ;; "src/lib-sieve/plugins/special-use/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/special-use/Makefile" ;; "src/lib-sieve/plugins/extlists/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/extlists/Makefile" ;; "src/lib-sieve/plugins/vnd.dovecot/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/vnd.dovecot/Makefile" ;; "src/lib-sieve/plugins/vnd.dovecot/debug/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/vnd.dovecot/debug/Makefile" ;; "src/lib-sieve/plugins/vnd.dovecot/environment/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/vnd.dovecot/environment/Makefile" ;; "src/lib-sieve/plugins/vnd.dovecot/report/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve/plugins/vnd.dovecot/report/Makefile" ;; "src/lib-sieve-tool/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-sieve-tool/Makefile" ;; "src/lib-managesieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-managesieve/Makefile" ;; "src/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/Makefile" ;; "src/plugins/doveadm-sieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/doveadm-sieve/Makefile" ;; "src/plugins/lda-sieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/lda-sieve/Makefile" ;; "src/plugins/sieve-extprograms/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/sieve-extprograms/Makefile" ;; "src/plugins/imapsieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/imapsieve/Makefile" ;; "src/plugins/imap-filter-sieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/imap-filter-sieve/Makefile" ;; "src/plugins/settings/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/settings/Makefile" ;; "src/sieve-tools/Makefile") CONFIG_FILES="$CONFIG_FILES src/sieve-tools/Makefile" ;; "src/managesieve/Makefile") CONFIG_FILES="$CONFIG_FILES src/managesieve/Makefile" ;; "src/managesieve-login/Makefile") CONFIG_FILES="$CONFIG_FILES src/managesieve-login/Makefile" ;; "src/testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES src/testsuite/Makefile" ;; "build-aux/run-test.sh") CONFIG_FILES="$CONFIG_FILES build-aux/run-test.sh" ;; "stamp.h") CONFIG_FILES="$CONFIG_FILES stamp.h" ;; *) 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+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || 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=`printf "%s\n" "$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 '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$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 || printf "%s\n" 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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$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"; } && { printf "%s\n" "$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 printf "%s\n" "$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 { printf "%s\n" "/* $configure_input */" >&1 \ && 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$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 printf "%s\n" "/* $configure_input */" >&1 \ && 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 || printf "%s\n" 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) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$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. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool 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 . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi not_scriptloc=`echo "$not_scriptloc"|sed 's/ / -/g'` echo echo "Install prefix . : $prefix" echo "script drivers . : file dict$scriptloc" if test "$not_scriptloc" != ""; then echo " :$not_scriptloc" fi dovecot-pigeonhole-2.4.2/m4/0000755000175100001700000000000015100335667017325 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/m4/ltsugar.m40000644000175100001700000001045315100335627021247 0ustar00buildbotbuildbot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # 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. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) dovecot-pigeonhole-2.4.2/m4/ltoptions.m40000644000175100001700000003427515100335627021631 0ustar00buildbotbuildbot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # 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. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) dovecot-pigeonhole-2.4.2/m4/dovecot.m40000644000175100001700000005116315100335616021232 0ustar00buildbotbuildbot00000000000000dnl dovecot.m4 - Check presence of dovecot -*-Autoconf-*- dnl dnl Copyright (C) 2010 Dennis Schridde dnl dnl This file is free software; the authors give dnl unlimited permission to copy and/or distribute it, with or without dnl modifications, as long as this notice is preserved. # serial 45 dnl dnl Check for support for D_FORTIFY_SOURCE=2 dnl AC_DEFUN([AC_CC_D_FORTIFY_SOURCE],[ AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) AS_IF([test "$enable_hardening" = yes], [ case "$host" in *) gl_COMPILER_OPTION_IF([-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2], [ AM_CFLAGS="$AM_CFLAGS -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" ], [], [AC_LANG_PROGRAM()] ) ;; esac ]) ]) dnl * gcc specific options AC_DEFUN([DC_DOVECOT_CFLAGS],[ m4_version_prereq(2.70, [AC_PROG_CC], [AC_PROG_CC_C99]) AS_IF([test "$ac_prog_cc_stdc" = "c89" || test "$ac_prog_cc_std" = "no" || test "$ac_cv_prog_cc_c99" = "no"], [ AC_MSG_ERROR(C99 capable compiler required) ]) AC_MSG_CHECKING([Which $CC -std flag to use]) old_cflags=$CFLAGS std= for mystd in gnu11 gnu99 c11 c99; do CFLAGS="-std=$mystd" AC_COMPILE_IFELSE([AC_LANG_PROGRAM() ], [ AM_CFLAGS="$AM_CFLAGS $CFLAGS" std=$mystd break ]) done AC_MSG_RESULT($std) CFLAGS="$old_cflags" AS_IF([test "x$ac_cv_c_compiler_gnu" = "xyes"], [ dnl -Wcast-qual -Wcast-align -Wconversion -Wunreachable-code # too many warnings dnl -Wstrict-prototypes -Wredundant-decls # may give warnings in some systems dnl -Wmissing-format-attribute -Wmissing-noreturn -Wwrite-strings # a couple of warnings AM_CFLAGS="$AM_CFLAGS -Wall -W -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wchar-subscripts -Wformat=2 -Wbad-function-cast" AS_IF([test "$have_clang" = "yes"], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 3) # error new clang #endif ]], [[]])],[],[ dnl clang 3.3+ unfortunately this gives warnings with hash.h AM_CFLAGS="$AM_CFLAGS -Wno-duplicate-decl-specifier" ]) ], [ dnl This is simply to avoid warning when building strftime() wrappers.. AM_CFLAGS="$AM_CFLAGS -fno-builtin-strftime" ]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if __GNUC__ < 4 # error old gcc #endif ]], [[]])],[ dnl gcc4 AM_CFLAGS="$AM_CFLAGS -Wstrict-aliasing=2" ],[]) old_cflags=$CFLAGS CFLAGS="$CFLAGS -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ const unsigned char foo[4] __attribute__((nonstring)) = "1234"; ]], [[]])],[ AC_DEFINE(HAVE_ATTR_NONSTRING,, [define if you have nonstring attribute]) ]) CFLAGS="$old_cflags" ]) ]) AC_DEFUN([AC_LD_WHOLE_ARCHIVE], [ LD_WHOLE_ARCHIVE= LD_NO_WHOLE_ARCHIVE= AC_MSG_CHECKING([for linker option to include whole archive]) ld_help="`$CC -Wl,-help 2>&1`" case "$ld_help" in *"--whole-archive"*) LD_WHOLE_ARCHIVE="--whole-archive" LD_NO_WHOLE_ARCHIVE="--no-whole-archive" ;; esac AS_IF([test "x$LD_WHOLE_ARCHIVE" != "x"], [AC_MSG_RESULT([-Wl,$LD_WHOLE_ARCHIVE])], [AC_MSG_RESULT([not supported])] ) AC_SUBST([LD_WHOLE_ARCHIVE]) AC_SUBST([LD_NO_WHOLE_ARCHIVE]) AM_CONDITIONAL([HAVE_WHOLE_ARCHIVE], [test "x$LD_WHOLE_ARCHIVE" != "x"]) ]) dnl dnl Check for -z now and -z relro linker flags dnl dnl Copyright (C) 2013 Red Hat, Inc. dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Lesser General Public dnl License as published by the Free Software Foundation; either dnl version 2.1 of the License, or (at your option) any later version. dnl dnl This library is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl Lesser General Public License for more details. dnl dnl You should have received a copy of the GNU Lesser General Public dnl License along with this library. If not, see dnl . dnl AC_DEFUN([AC_LD_RELRO],[ RELRO_LDFLAGS= AS_IF([test "$enable_hardening" = yes], [ AC_MSG_CHECKING([for how to force completely read-only GOT table]) ld_help=`$CC -Wl,-help 2>&1` case $ld_help in *"-z relro"*) RELRO_LDFLAGS="-Wl,-z -Wl,relro" ;; esac case $ld_help in *"-z now"*) RELRO_LDFLAGS="$RELRO_LDFLAGS -Wl,-z -Wl,now" ;; esac AS_IF([test "x$RELRO_LDFLAGS" != "x"], [AC_MSG_RESULT([$RELRO_LDFLAGS])], [AC_MSG_RESULT([unknown])] ) ]) AC_SUBST([RELRO_LDFLAGS]) ]) dnl dnl Check for support for position independent executables dnl dnl Copyright (C) 2013 Red Hat, Inc. dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Lesser General Public dnl License as published by the Free Software Foundation; either dnl version 2.1 of the License, or (at your option) any later version. dnl dnl This library is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl Lesser General Public License for more details. dnl dnl You should have received a copy of the GNU Lesser General Public dnl License along with this library. If not, see dnl . dnl AC_DEFUN([AC_CC_PIE],[ AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) PIE_CFLAGS= PIE_LDFLAGS= AS_IF([test "$enable_hardening" = yes], [ OLD_CFLAGS=$CFLAGS case "$host" in *-*-mingw* | *-*-msvc* | *-*-cygwin* ) ;; dnl All code is position independent on Win32 target *) CFLAGS="-fPIE -DPIE" gl_COMPILER_OPTION_IF([-pie], [ PIE_CFLAGS="-fPIE -DPIE" PIE_LDFLAGS="-pie" ], [ dnl some versions of clang require -Wl,-pie instead of -pie gl_COMPILER_OPTION_IF([[-Wl,-pie]], [ PIE_CFLAGS="-fPIE -DPIE" PIE_LDFLAGS="-Wl,-pie" ], [AC_MSG_RESULT([not supported])], [AC_LANG_PROGRAM()] ) ], [AC_LANG_PROGRAM()] ) esac CFLAGS=$OLD_CFLAGS ]) AC_SUBST([PIE_CFLAGS]) AC_SUBST([PIE_LDFLAGS]) ]) dnl dnl Check for support for Retpoline dnl AC_DEFUN([AC_CC_RETPOLINE],[ AC_ARG_WITH(retpoline, AS_HELP_STRING([--with-retpoline=], [Retpoline mitigation choice (default: keep)]), with_retpoline=$withval, with_retpoline=keep) AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) AS_IF([test "$enable_hardening" = yes], [ case "$host" in *) gl_COMPILER_OPTION_IF([-mfunction-return=$with_retpoline], [AM_CFLAGS="$AM_CFLAGS -mfunction-return=$with_retpoline"], [], [AC_LANG_PROGRAM()] ) gl_COMPILER_OPTION_IF([-mindirect-branch=$with_retpoline], [ AM_CFLAGS="$AM_CFLAGS -mindirect-branch=$with_retpoline" ], [], [AC_LANG_PROGRAM()] ) esac ]) ]) dnl dnl Check for support for -fstack-protector or -strong dnl AC_DEFUN([AC_CC_F_STACK_PROTECTOR],[ AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) AS_IF([test "$enable_hardening" = yes], [ case "$host" in *) gl_COMPILER_OPTION_IF([-fstack-protector-strong], [ AM_CFLAGS="$AM_CFLAGS -fstack-protector-strong" ], [ gl_COMPILER_OPTION_IF([-fstack-protector], [ AM_CFLAGS="$AM_CFLAGS -fstack-protector" ], [], [AC_LANG_PROGRAM()]) ], [AC_LANG_PROGRAM()] ) esac ]) ]) AC_DEFUN([DC_DOVECOT_MODULEDIR],[ AC_ARG_WITH(moduledir, [ --with-moduledir=DIR Base directory for dynamically loadable modules], [moduledir="$withval"], [moduledir="\$(libdir)/dovecot"] ) AC_SUBST(moduledir) ]) AC_DEFUN([DC_PLUGIN_DEPS],[ _plugin_deps=yes AC_MSG_CHECKING([whether OS supports plugin dependencies]) case "$host_os" in darwin*) dnl OSX loads the plugins twice, which breaks stuff _plugin_deps=no ;; esac AC_MSG_RESULT([$_plugin_deps]) AM_CONDITIONAL([DOVECOT_PLUGIN_DEPS], [test "x$_plugin_deps" = "xyes"]) unset _plugin_deps ]) AC_DEFUN([DC_DOVECOT_TEST_WRAPPER],[ AC_REQUIRE_AUX_FILE([run-test.sh.in]) AC_ARG_VAR([VALGRIND], [Path to valgrind]) AC_PATH_PROG(VALGRIND, valgrind, reject) AS_IF([test "$VALGRIND" != reject], [ RUN_TEST='$(LIBTOOL) execute $(SHELL) $(top_builddir)/build-aux/run-test.sh' ], [ RUN_TEST='' ]) AC_SUBST(RUN_TEST) ]) dnl Substitute every var in the given comma separated list AC_DEFUN([AX_SUBST_L],[ m4_foreach([__var__], [$@], [AC_SUBST(__var__)]) ]) AC_DEFUN([DC_DOVECOT_HARDENING],[ AC_ARG_ENABLE(hardening, AS_HELP_STRING([--enable-hardening=yes], [Enable various hardenings (default: yes)]), enable_hardening=$enableval, enable_hardening=yes) AC_MSG_CHECKING([Whether to enable hardening]) AC_MSG_RESULT([$enable_hardening]) AC_CC_PIE AC_CC_F_STACK_PROTECTOR AC_CC_D_FORTIFY_SOURCE AC_CC_RETPOLINE AC_LD_RELRO DOVECOT_WANT_UBSAN ]) AC_DEFUN([DC_DOVECOT_FUZZER],[ AC_ARG_WITH(fuzzer, AS_HELP_STRING([--with-fuzzer=clang], [Build with clang fuzzer (default: no)]), with_fuzzer=$withval, with_fuzzer=no) AS_IF([test x$with_fuzzer = xclang], [ AM_CFLAGS="$AM_CFLAGS -fsanitize=fuzzer-no-link" AM_CFLAGS="$AM_CFLAGS -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" # use $LIB_FUZZING_ENGINE for linking if it exists FUZZER_LDFLAGS=${LIB_FUZZING_ENGINE--fsanitize=fuzzer} # May need to use CXXLINK for linking, which wants sources to # be compiled with -fPIE FUZZER_CPPFLAGS='$(AM_CPPFLAGS) -fPIE -DPIE' ], [test x$with_fuzzer != xno], [ AC_MSG_ERROR([Unknown fuzzer $with_fuzzer]) ]) AC_SUBST([FUZZER_CPPFLAGS]) AC_SUBST([FUZZER_LDFLAGS]) AM_CONDITIONAL([USE_FUZZER], [test "x$with_fuzzer" != "xno"]) ]) AC_DEFUN([DC_DOVECOT],[ AC_ARG_WITH(dovecot, [ --with-dovecot=DIR Dovecot base directory], [ dovecotdir="$withval" ], [ dc_prefix=$prefix test "x$dc_prefix" = xNONE && dc_prefix=$ac_default_prefix dovecotdir="$dc_prefix/lib/dovecot" ] ) AC_ARG_WITH(dovecot-install-dirs, [AS_HELP_STRING([--with-dovecot-install-dirs], [Use install directories configured for Dovecot (default)])], AS_IF([test x$withval = xno], [ use_install_dirs=no ], [ use_install_dirs=yes ]), use_install_dirs=yes) AC_MSG_CHECKING([for "$dovecotdir/dovecot-config"]) AS_IF([test -f "$dovecotdir/dovecot-config"], [ AC_MSG_RESULT([$dovecotdir/dovecot-config]) ], [ AC_MSG_RESULT([not found]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Use --with-dovecot=DIR to provide the path to the dovecot-config file.]) AC_MSG_ERROR([dovecot-config not found]) ]) old=`pwd` cd $dovecotdir abs_dovecotdir=`pwd` cd $old AC_SUBST(abs_dovecotdir) DISTCHECK_CONFIGURE_FLAGS="--with-dovecot=$abs_dovecotdir --without-dovecot-install-dirs" dnl Make sure dovecot-config doesn't accidentically override flags ORIG_CFLAGS="$CFLAGS" ORIG_LDFLAGS="$LDFLAGS" ORIG_BINARY_CFLAGS="$BINARY_CFLAGS" ORIG_BINARY_LDFLAGS="$BINARY_LDFLAGS" eval `$GREP -i '^dovecot_[[a-z_]]*=' "$dovecotdir"/dovecot-config` eval `$GREP '^LIBDOVECOT[[A-Z0-9_]]*=' "$dovecotdir"/dovecot-config` CFLAGS="$ORIG_CFLAGS" LDFLAGS="$ORIG_LDFLAGS" BINARY_CFLAGS="$ORIG_BINARY_CFLAGS" BINARY_LDFLAGS="$ORIG_BINARY_LDFLAGS" dovecot_installed_moduledir="$dovecot_moduledir" AS_IF([test "$use_install_dirs" = "no"], [ dnl the main purpose of these is to fix make distcheck for plugins dnl other than that, they don't really make much sense dovecot_pkgincludedir='$(pkgincludedir)' dovecot_pkglibdir='$(pkglibdir)' dovecot_pkglibexecdir='$(libexecdir)/dovecot' dovecot_docdir='$(docdir)' dovecot_moduledir='$(moduledir)' dovecot_statedir='$(statedir)' ]) CC_CLANG CC_STRICT_BOOL DC_DOVECOT_CFLAGS DC_DOVECOT_HARDENING AX_SUBST_L([DISTCHECK_CONFIGURE_FLAGS], [dovecotdir], [dovecot_moduledir], [dovecot_installed_moduledir], [dovecot_pkgincludedir], [dovecot_pkglibexecdir], [dovecot_pkglibdir], [dovecot_docdir], [dovecot_statedir]) AX_SUBST_L([DOVECOT_INSTALLED], [DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS], [DOVECOT_LDAP_LIBS], [DOVECOT_COMPRESS_LIBS], [DOVECOT_BINARY_CFLAGS], [DOVECOT_BINARY_LDFLAGS]) AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_LDAP], [LIBDOVECOT_OPENSSL], [LIBDOVECOT_COMPRESS], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE], [LIBDOVECOT_DSYNC], [LIBDOVECOT_LIBLANG], [LIBDOVECOT_GSSAPI]) AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_LDAP_DEPS], [LIBDOVECOT_OPENSSL_DEPS], [LIBDOVECOT_COMPRESS_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS], [LIBDOVECOT_DSYNC_DEPS], [LIBDOVECOT_LIBLANG_DEPS], [LIBDOVECOT_GSSAPI_DEPS]) AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_AUTH_INCLUDE], [LIBDOVECOT_DOVEADM_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_SQL_INCLUDE], [LIBDOVECOT_LDAP_INCLUDE]) AX_SUBST_L([LIBDOVECOT_IMAP_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE], [LIBDOVECOT_IMAP_INCLUDE], [LIBDOVECOT_POP3_INCLUDE], [LIBDOVECOT_SUBMISSION_INCLUDE], [LIBDOVECOT_LMTP_INCLUDE], [LIBDOVECOT_DSYNC_INCLUDE], [LIBDOVECOT_IMAPC_INCLUDE], [LIBDOVECOT_FTS_INCLUDE]) AX_SUBST_L([LIBDOVECOT_NOTIFY_INCLUDE], [LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE], [LIBDOVECOT_ACL_INCLUDE], [LIBDOVECOT_LIBLANG_INCLUDE], [LIBDOVECOT_LUA_INCLUDE]) AX_SUBST_L([DOVECOT_LUA_LIBS], [DOVECOT_LUA_CFLAGS], [LIBDOVECOT_LUA], [LIBDOVECOT_LUA_DEPS]) AS_IF([test x$DOVECOT_HAVE_MAIL_UTF8 = xyes], [ AC_DEFINE([DOVECOT_HAVE_MAIL_UTF8],,"Define if Dovecot has mail UTF-8 support") ]) AM_CONDITIONAL(DOVECOT_INSTALLED, test "$DOVECOT_INSTALLED" = "yes") DC_PLUGIN_DEPS DC_DOVECOT_TEST_WRAPPER ]) AC_DEFUN([DC_CC_WRAPPER],[ AS_IF([test "$want_shared_libs" != "yes"], [ dnl want_shared_libs=no is for internal use. the liblib.la check is for plugins AS_IF([test "$want_shared_libs" = "no" || echo "$LIBDOVECOT" | $GREP "/liblib.la" > /dev/null], [ AS_IF([test "$with_gnu_ld" = yes], [ dnl libtool can't handle using whole-archive flags, so we need to do this dnl with a CC wrapper.. shouldn't be much of a problem, since most people dnl are building with shared libs. cat > cc-wrapper.sh <<_DC_EOF #!/bin/sh if echo "\$[*]" | $GREP -- -export-dynamic > /dev/null; then # the binary uses plugins. make sure we include everything from .a libs exec $CC -Wl,--whole-archive \$[*] -Wl,--no-whole-archive else exec $CC \$[*] fi _DC_EOF chmod +x cc-wrapper.sh CC=`pwd`/cc-wrapper.sh ]) ]) ]) ]) # warnings.m4 serial 11 dnl Copyright (C) 2008-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Simon Josefsson # gl_AS_VAR_APPEND(VAR, VALUE) # ---------------------------- # Provide the functionality of AS_VAR_APPEND if Autoconf does not have it. m4_ifdef([AS_VAR_APPEND], [m4_copy([AS_VAR_APPEND], [gl_AS_VAR_APPEND])], [m4_define([gl_AS_VAR_APPEND], [AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])]) # gl_COMPILER_OPTION_IF(OPTION, [IF-SUPPORTED], [IF-NOT-SUPPORTED], # [PROGRAM = AC_LANG_PROGRAM()]) # ----------------------------------------------------------------- # Check if the compiler supports OPTION when compiling PROGRAM. # # FIXME: gl_Warn must be used unquoted until we can assume Autoconf # 2.64 or newer. AC_DEFUN([gl_COMPILER_OPTION_IF], [AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl AS_LITERAL_IF([$1], [m4_pushdef([gl_Positive], m4_bpatsubst([$1], [^-Wno-], [-W]))], [gl_positive="$1" case $gl_positive in -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;; esac m4_pushdef([gl_Positive], [$gl_positive])])dnl AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [ gl_save_compiler_FLAGS="$gl_Flags" gl_AS_VAR_APPEND(m4_defn([gl_Flags]), [" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["]) AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])], [AS_VAR_SET(gl_Warn, [yes])], [AS_VAR_SET(gl_Warn, [no])]) gl_Flags="$gl_save_compiler_FLAGS" ]) AS_VAR_IF(gl_Warn, [yes], [$2], [$3]) m4_popdef([gl_Positive])dnl AS_VAR_POPDEF([gl_Flags])dnl AS_VAR_POPDEF([gl_Warn])dnl ]) # gl_UNKNOWN_WARNINGS_ARE_ERRORS # ------------------------------ # Clang doesn't complain about unknown warning options unless one also # specifies -Wunknown-warning-option -Werror. Detect this. AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS], [gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option], [gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'], [gl_unknown_warnings_are_errors=])]) # gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS], # [PROGRAM = AC_LANG_PROGRAM()]) # --------------------------------------------- # Adds parameter to WARN_CFLAGS if the compiler supports it when # compiling PROGRAM. For example, gl_WARN_ADD([-Wparentheses]). # # If VARIABLE is a variable name, AC_SUBST it. AC_DEFUN([gl_WARN_ADD], [AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) gl_COMPILER_OPTION_IF([$1], [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_CFLAGS]], [[$2]]), [" $1"])], [], [$3]) m4_ifval([$2], [AS_LITERAL_IF([$2], [AC_SUBST([$2])])], [AC_SUBST([WARN_CFLAGS])])dnl ]) # Local Variables: # mode: autoconf # End: dnl * clang check AC_DEFUN([CC_CLANG],[ AC_MSG_CHECKING([whether $CC is clang 3.3+]) AS_IF([$CC -dM -E -x c /dev/null | $GREP __clang__ > /dev/null 2>&1], [ AS_VAR_SET([have_clang], [yes]) # buffer_t usage triggers this warning gl_WARN_ADD([-Wno-default-const-init-field-unsafe]) AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS" ], [ AS_VAR_SET([have_clang], [no]) ]) AC_MSG_RESULT([$have_clang]) ]) AC_DEFUN([CC_STRICT_BOOL], [ AS_IF([test $have_clang = yes], [ AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) gl_COMPILER_OPTION_IF([-Wstrict-bool], [ AC_DEFINE(HAVE_STRICT_BOOL,, [we have strict bool]) ]) ]) ]) AC_DEFUN([DOVECOT_WANT_UBSAN], [ AC_ARG_ENABLE(ubsan, AS_HELP_STRING([--enable-ubsan], [Enable undefined behaviour sanitizes (default=no)]), [want_ubsan=yes], [want_ubsan=no]) AC_MSG_CHECKING([whether we want undefined behaviour sanitizer]) AC_MSG_RESULT([$want_ubsan]) AS_IF([test x$want_ubsan = xyes], [ san_flags="" gl_COMPILER_OPTION_IF([-fsanitize=undefined], [ san_flags="$san_flags -fsanitize=undefined -fno-sanitize=function,vptr" AC_DEFINE([HAVE_FSANITIZE_UNDEFINED], [1], [Define if your compiler has -fsanitize=undefined]) ]) gl_COMPILER_OPTION_IF([-fno-sanitize=nonnull-attribute], [ san_flags="$san_flags -fno-sanitize=nonnull-attribute" AC_DEFINE([HAVE_FNO_SANITIZE_NONNULL_ATTRIBUTE], [1], [Define if your compiler has -fno-sanitize=nonnull-attribute]) ]) gl_COMPILER_OPTION_IF([-fsanitize=implicit-integer-truncation], [ san_flags="$san_flags -fsanitize=implicit-integer-truncation" AC_DEFINE([HAVE_FSANITIZE_IMPLICIT_INTEGER_TRUNCATION], [1], [Define if your compiler has -fsanitize=implicit-integer-truncation]) ]) gl_COMPILER_OPTION_IF([-fsanitize=local-bounds], [ san_flags="$san_flags -fsanitize=local-bounds" AC_DEFINE([HAVE_FSANITIZE_LOCAL_BOUNDS], [1], [Define if your compiler has -fsanitize=local-bounds]) ]) gl_COMPILER_OPTION_IF([-fsanitize=integer], [ san_flags="$san_flags -fsanitize=integer" AC_DEFINE([HAVE_FSANITIZE_INTEGER], [1], [Define if your compiler has -fsanitize=integer]) ]) gl_COMPILER_OPTION_IF([-fsanitize=nullability], [ san_flags="$san_flags -fsanitize=nullability" AC_DEFINE([HAVE_FSANITIZE_NULLABILITY], [1], [Define if your compiler has -fsanitize=nullability]) ]) AS_IF([test "$san_flags" != "" ], [ AM_CFLAGS="$AM_CFLAGS $san_flags -U_FORTIFY_SOURCE -g -ggdb3 -O0 -fno-omit-frame-pointer" AC_DEFINE([HAVE_UNDEFINED_SANITIZER], [1], [Define if your compiler supports undefined sanitizers]) ], [ AC_MSG_ERROR([No undefined sanitizer support in your compiler]) ]) san_flags="" ]) ]) dovecot-pigeonhole-2.4.2/m4/test_with.m40000644000175100001700000000112315100335616021570 0ustar00buildbotbuildbot00000000000000dnl TEST_WITH(name, value, [plugin]) AC_DEFUN([TEST_WITH], [ want=want_`echo $1|sed s/-/_/g` AS_IF([test "$2" = yes || test "$2" = no || test "$2" = auto], [ eval $want=$2 ], [test "$2" = plugin], [ AS_IF([test "$3" = "plugin"], [ eval $want=plugin ], [ AC_MSG_ERROR(--with-$1=plugin not supported) ]) ], [test "$(echo $2|grep -c '^/' 2>/dev/null)" -gt 0], [ AC_MSG_ERROR(--with-$1=path not supported. You may want to use instead: CPPFLAGS=-I$2/include LDFLAGS=-L$2/lib ./configure --with-$1) ], [ AC_MSG_ERROR(--with-$1: Unknown value: $2) ]) ]) dovecot-pigeonhole-2.4.2/m4/ltversion.m40000644000175100001700000000131215100335627021605 0ustar00buildbotbuildbot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, # Inc. # Written by Scott James Remnant, 2004 # # 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. # @configure_input@ # serial 4245 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.7]) m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.7' macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) dovecot-pigeonhole-2.4.2/m4/lt~obsolete.m40000644000175100001700000001400715100335627022137 0ustar00buildbotbuildbot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # 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. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) dovecot-pigeonhole-2.4.2/m4/libtool.m40000644000175100001700000113165215100335627021240 0ustar00buildbotbuildbot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool 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 . ]) # serial 59 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS dovecot-pigeonhole-2.4.2/NEWS0000644000175100001700000030562015100335616017504 0ustar00buildbotbuildbot00000000000000v2.4.2 2025-10-24 Aki Tuomi * lib-sieve: Use new regular expression library in core. * managesieve: Add default service_extra_groups=$SET:default_internal_group. + lib-sieve: Add support for "extlists" extension. + lib-sieve: regex - Allow unicode comparator. - lib-sieve-tool: sieve-tool - All sieve_script settings were overriden. - lib-sieve: storage: dict: sieve_script_dict filter was missing from settings. - sieve-ldap-storage: Fix compile without LDAP. v2.4.1 2025-03-28 Aki Tuomi - global: Fix settings handling bugs. Especially %variables weren't working in various settings. - ldap: Pigeonhole could not be built without LDAP. v2.4.0 2025-01-24 Aki Tuomi * Change configuration syntax to match new Dovecot configuration syntax. * vacation: Reduce default days to 60 from infinity * vacation: vacation_max_period=0 is now an error. * Version has been changed to match Dovecot version. + Added i;unicode-casecmp comparator. - Lots of bugs have been fixed. v0.5.21 2023-08-15 Aki Tuomi - sieve: Using the deleteheader action on a message with a broken/invalid header can cause the Sieve interpreter to crash with an assert panic. This can happen e.g. when the message is missing the empty EOH line between the headers and the body of the message. Fixes: Panic: file edit-mail.c: line 820 (edit_mail_headers_parse): assertion failed: (body_offset > 0). - sieve: Pigeonhole added an extra Message-ID header during mail forwarding when the existing one was invalid. Now it adds the Message-ID only if it is entirely missing. Existing Message-ID(s) are left unchanged. v0.5.20 2022-12-12 Aki Tuomi * No changes - release done to keep version numbers synced. v0.5.19 2022-05-10 Aki Tuomi * No changes - release done to keep version numbers synced. v0.5.18 2022-02-03 Aki Tuomi - duplicate: Users without a home directory can crash with Sieve when using duplicate database. v2.3.17 regression. - imapsieve: When mail was expunged when processing imapsieve events, a crash could occur. Fixes Panic: file mail-index-map.c: line 558 (mail_index_map_lookup_seq_range): assertion failed: (first_uid > 0) - managesieve-login: Proxy didn't support forwarding the forward_* passdb fields. - redirect: Sieve would crash if redirect after keep-equivalent action failed. - sieve: Interpreter crashes when the Sieve index extension is used with index zero. - vnd.dovecot.filter: Envelope sender string may become corrupted when Sieve scripts are using vnd.dovecot.filter. This could end up corrupting mbox's From line and return wrong envelope sender string in Sieve tests. v0.5.17.1 2021-12-07 Aki Tuomi - managesieve: Dovecot failed to start if ssl_ca was too large. - lib-sieve-tool: Binaries failed to run if ssl_ca was too large. v0.5.17 2021-10-28 Aki Tuomi - duplicate: The Sieve duplicate test is prone to false negatives when the user receives many e-mails concurrently, meaning that duplicate deliveries can still occur. - fileinto: v2.3.16 regression: Sieve delivery crashes if mail is delivered to non-existing and existing folder. - imap-filter-sieve: v2.3.15 regression: The CPU limits on Sieve execution are too easily exceeded in IMAP context (the IMAPSieve and FILTER=SIEVE capabilities). Changed the default to unlimited CPU time for IMAP context, since similar excessive resource usage can be caused by other means as well. The CPU limits on Sieve scripts executed at LDA/LMTP delivery are still enforced by default. - redirect: The Sieve redirect action has protections against users triggering mail loops. Unfortunately, the detection of a redirect mail loop sometimes causes the message to get lost if no other Sieve action is applied that delivers the message somewhere else. - redirect: v2.3.16 regression: With certain Sieve scripts if redirect fails due to temporary failure, the lmtp process may crash after the delivery. Fixes: Panic: file mail-user.c: line 229 (mail_user_deinit): assertion failed: ((*user)->refcount == 1). v0.5.16 2021-08-06 Timo Sirainen * .dovecot.sieve.log file now includes year in the header. * Change Sieve script result execution to delay definitive action execution to the end of a successful Sieve script execution session. This is part of an effort to solve problems with the Sieve duplicate test. As a side-effect, some rare temporary-error cases yield different results, in which partial failure is more likely. v0.5.15 2021-06-21 Aki Tuomi * CVE-2020-28200: Sieve interpreter is not protected against abusive scripts that claim excessive resource usage. Fixed by limiting the user CPU time per single script execution and cumulatively over several script runs within a configurable timeout period. Sufficiently large CPU time usage is summed in the Sieve script binary and execution is blocked when the sum exceeds the limit within that time. The block is lifted when the script is updated after the resource usage times out. * Disconnection log messages are now more standardized across services. They also always now start with "Disconnected" prefix. - managesieve: Commands pipelined together with and just after the authenticate command cause these commands to be executed twice. v0.5.14 2021-03-04 Aki Tuomi * IMAP FILTER command: cmd-filter-sieve - Do not allow NIL as script name argument. v0.5.13 2021-01-04 Aki Tuomi - duplicate: The test was handled badly in a multiscript (sieve_before, sieve_after) scenario in which an earlier script in the sequence with a duplicate test succeeded, while a later script caused a runtime failure. In that case, the message is recorded for duplicate tracking, while the message may not actually have been delivered in the end. - editheader: Sieve interpreter entered infinite loop at startup when the "editheader" configuration listed an invalid header name. This problem can only be triggered by the administrator. - relational: The Sieve relational extension can cause a segfault at compile time. This is triggered by invalid script syntax. The segfault happens when this match type is the last argument of the test command. This situation is not possible in a valid script; positional arguments are normally present after that, which would prevent the segfault. - sieve: For some Sieve commands the provided mailbox name is not properly checked for UTF-8 validity, which can cause assert crashes at runtime when an invalid mailbox name is encountered. This can be caused by the user by writing a bad Sieve script involving the affected commands ("mailboxexists", "specialuse_exists"). This can be triggered by the remote sender only when the user has written a Sieve script that passes message content to one of the affected commands. - sieve: Large sequences of 8-bit octets passed to certain Sieve commands that create or modify message headers that allow UTF-8 text (vacation, notify and addheader) can cause the delivery or IMAP process (when IMAPSieve is used) to enter a memory-consuming semi-infinite loop that ends when the process exceeds its memory limits. Logged in users can cause these hangs only for their own processes. v0.5.11 2020-08-12 Aki Tuomi * managesieve: managesieve_max_line_length setting is now a "size" type instead of just number of bytes. This allows using e.g. "64k" as the value. - lib-sieve: When folding white space is used in the Message-ID header, it is not stripped away correctly before the message ID value is used, causing e.g. garbled log lines at delivery. v0.5.10 2020-03-06 Aki Tuomi * imap_sieve_filter: Change result action logging to include IMAP UID - vacation: Addresses were compared case-sensitively. v0.5.9 2019-12-04 Aki Tuomi + Added events for Sieve and ManageSieve, see https://doc.dovecot.org/admin_manual/list_of_events/#pigeonhole + Pigeonhole: Implement the Sieve "special-use" extension described in RFC 8579. - duplicate: Test only compared the handles which would cause different values to be cached as the same duplicate test. Fix to also compare the actual hashes. - imap_sieve_filter: IMAP FILTER Command had various bugs in error handling. Errors may have been duplicated for each email, errors may have been missing entirely, command tag and ERRORS/WARNINGS parameters were swapped. v0.5.8 2019-10-08 Aki Tuomi - Sieve may leak resources in rare cases when a redirect, vacation or report action fails to send the message. This mainly applies when Sieve is executed in IMAP context; i.e., for the IMAPSIEVE or FILTER=SIEVE capabilities. v0.5.7.1 2019-07-23 Timo Sirainen - dsync: Sieve script syncing failed if mailbox attributes weren't enabled. v0.5.7 2019-07-12 Aki Tuomi + vacation: Made the subject for the automatic response message produced by the Sieve vacation action configurable. Both the default subject (if the script defines none) and the subject template (e.g. used to add a subject prefix) can be configured. - dsync: dsync-replication does not synchronize Sieve scripts. - imap_sieve_filter: Reduce FILTER=SIEVE verbosity over IMAP connection. - testsuite: Pigeonhole testsuite segfaulted if it was compiled with GCC 9 v0.5.6 2019-04-30 Aki Tuomi + sieve: Redirect loop prevention is sometimes ineffective. Improve existing loop detection by also recognizing the X-Sieve-Redirected-From header in incoming messages and dropping redirect actions when it points to the sending account. This header is already added by the redirect action, so this improvement only adds an additional use of this header. - sieve: Prevent execution of implicit keep upon temporary failure occurring at runtime. v0.5.5 2019-03-05 Stephan Bosch + IMAPSieve: Add new plugin/imapsieve_expunge_discarded setting which causes messages discarded by an IMAPSieve script to be expunged immediately, rather than only being marked as "\Deleted" (which is still the default behavior). - IMAPSieve: Fix panic crash occurring when a COPY command copies messages from a virtual mailbox where the source messages originate from more than a single real mailbox. - imap4flags extension: Fix deleting all keywords. When the action resulted in all keywords being removed, no changes were actually applied. - variables extension: Fix truncation of UTF-8 variable content. The maximum size of Sieve variables was enforced by truncating the variable string content bluntly at the limit, but this does not consider UTF-8 code point boundaries. This resulted in broken UTF-8 strings. This problem also surfaced for variable modifiers, such as the ":encodeurl" modifier provided by the Sieve "enotify" extension. In that case, the resulting URI escaping could also be truncated inappropriately. - IMAPSieve, IMAP FILTER=SIEVE: Fix replacing a modified message. Sieve scripts running in IMAPSIEVE or IMAP FILTER=SIEVE context that modify the message, stored the message a second time, rather than replacing the originally stored unmodified message. - Fix segmentation fault occurring when both the sieve_extprograms plugin (for the Sieve interpreter) and the imap_filter_sieve plugin (for IMAP) are loaded at the same time. A symbol was defined by both plugins, causing a clash when both were loaded. v0.5.4 2018-11-23 Stephan Bosch * Adjustments to several changes in Dovecot v2.3.4 make this Pigeonhole release dependent on that Dovecot release; it will not compile against older Dovecot versions. And, conversely, you need to upgrade Pigeonhole when upgrading Dovecot to v2.3.4. * The changes regarding the default postmaster_address in Dovecot v2.3.4 mainly apply to Pigeonhole. The new default should work for all existing installations, thereby fixing several reported v2.3/v0.5 migration problems. - IMAP FILTER=SIEVE capability: Fix assert crash occurring when running UID FILTER on a Sieve script with errors. v0.5.3 2018-10-01 Stephan Bosch - Fix assertion panic occurring when managesieve service fails to open INBOX while saving a Sieve script. This was caused by a lack of cleanup after failure. - Fix specific messages causing an assert panic with actions that compose a reply (e.g. vacation). With some rather weird input from the original message, the header folding algorithm (as used for composing the References header for the reply) got confused, causing the panic. - IMAP FILTER=SIEVE capability: Fix FILTER SIEVE SCRIPT command parsing. After finishing reading the Sieve script, the command parsing sometimes didn't continue with the search arguments. This is a time- critical bug that likely only occurs when the Sieve script is sent in the next TCP frame. v0.5.2 2018-06-29 Stephan Bosch + Implement plugin for the a vendor-defined IMAP capability called "FILTER=SIEVE". It adds the ability to manually invoke Sieve filtering in IMAP. More information can be found in doc/plugins/imap_filter_sieve.txt. - The Sieve addess test caused an assertion panic for invalid addresses with UTF-8 codepoints in the localpart. Fixed by properly detecting invalid addresses with UTF-8 codepoints in the localpart and skipping these like other invalid addresses while iterating addresses for the address test. - Make the length of the subject header for the vacation response configurable and enforce the limit in UTF-8 codepoints rather than bytes. The subject header for a vacation response was statically truncated to 256 bytes, which is too limited for multi-byte UTF-8 characters. - Sieve editheader extension: Fix assertion panic occurring when it is used to manipulate a message header with a very large header field. - Properly abort execution of the sieve_discard script upon error. Before, the LDA Sieve plugin attempted to execute the sieve_discard script when an error occurs. This can lead to the message being lost. - Fix the interaction between quota and the sieve_discard script. When quota was used together with a sieve_discard script, the message delivery did not bounce when the quota was exceeded. v0.5.1 28-03-2018 Stephan Bosch - Explicitly disallow UTF-8 in localpart in addresses parsed from Sieve script. - editheader extension: Corrected the stream position calculations performed while making the modified message available as a stream. Pigeonhole Sieve crashed in LMTP with an assertion panic when the Sieve editheader extension was used before the message was redirected. Experiments indicate that the problem occurred only with LMTP and that LDA is not affected. - fileinto extension: Fix assert panic occurring when fileinto is used without being listed in the require line, while the copy extension is listed there. This is a very old bug. - imapsieve plugin: Do not assert crash or log an error for messages that disappear concurrently while applying Sieve scripts. This event is now logged as a debug message. - Sieve extprograms plugin: Large output from "execute" command crashed delivery. Fixed buffering issue in code that handles output from the external program. v0.5.0.1 05-01-2018 Stephan Bosch - imap4flags extension: Fix binary corruption occurring when setflag/addflag/removeflag flag-list is a variable. - sieve-extprograms plugin: Fix segfault occurring when used in IMAPSieve context. v0.5.0 24-12-2017 Stephan Bosch * editheader extension: The implementation of header modifications is heavily updated. Although the functionality has not changed, the underlying code was updated to address several static analysis warnings, runtime integer arithmetic warnings (Clang), and to match updates in the Dovecot stream API. + variables extension: Made the maximum scope and variable size configurable. + subaddress: Support multiple recipient_delimiters. - enotify extension: mailto method: Fixed parsing of mailto URI with only a header part. - enotify plugin: mailto method: Make sure the "From:" header is set to a usable address and not "(null)". - Fixed writing address headers to outgoing messages. Sometimes headers were MIME-encoded twice, yielding invalid results. v0.4.23 20-03-2018 Stephan Bosch - editheader extension: Corrected the stream position calculations performed while making the modified message available as a stream. Pigeonhole Sieve crashed in LMTP with an assertion panic when the Sieve editheader extension was used before the message was redirected. Experiments indicate that the problem occurred only with LMTP and that LDA is not affected. - fileinto extension: Fix assert panic occurring when fileinto is used without being listed in the require line, while the copy extension is listed there. This is a very old bug. - imapsieve plugin: Do not log an error for messages that disappear concurrently while applying Sieve scripts. This is a further improvement on the imapsieve fix in the previous release (which fixed a panic). This event is now logged as a debug message. v0.4.22 01-03-2018 Stephan Bosch - Fixed filesystem path handling problem: sieve plugin could have assert-crashed with specific path lengths with: "Panic: file realpath.c: line 86 (path_normalize): assertion failed: (npath_pos + 1 < npath + asize)". - Sieve extprograms plugin: Large output from "execute" command crashed delivery. Fixed buffering issue in code that handles output from the external program. - editheader extension: Extensively reworked the low-level implementation of adding and removing headers. This solves a few integer arithmetic problems reported by Clang runtime checks, but also improves code structure and reliability in general. - imapsieve: Fix assert crash occurring when selected messages are expunged concurrently by the time Sieve filter is to be applied. - imap4flags extension: Fix binary byte-code corruption occurring when the setflag, addflag, or removeflag command's flag-list is a variable. - enotify extension: mailto method: Fixed parsing of mailto URI with only a header part. - enotify extension: mailto method: Make sure "From:" header is set to a usable address and not "(null)". - Fixed writing address headers to outgoing messages. It sometimes erroneously applied another layer of MIME header encoding. v0.4.21 12-10-2017 Stephan Bosch * redirect action: Always set the X-Sieve-Redirected-From header to sieve_user_email if configured. Before, it would use the envelope recipient instead if available, which makes no sense if the primary e-mail address is available. + vacation extension: Allow ignoring the envelope sender while composing the "To:" header for the reply. Normally, the "To:" header is composed from the address found in the "Sender", "Resent-From" or "From" headers that is equal to the envelope sender. If none is then found, the bare envelope sender is used. This change adds a new setting "sieve_vacation_to_header_ignore_envelope". With this setting enabled, the "To:" header is always composed from those headers in the source message. The new setting thus allows ignoring the envelope, which is useful e.g. when SRS is used. + vacation extension: Compose the "To:" header from the full sender address found in the first "Sender:", "From:" or "Resent-From:" header. Before, it would create a "To:" header without a phrase part. The new behavior is nicer, since the reply will be addressed to the sender by name if possible. - LDA Sieve plugin: Fixed sequential execution of LDAP-based scripts. A missing LDAP-based script could cause the script sequence to exit earlier. - sieve-filter: Removed the (now) duplicate utf8 to mutf7 mailbox name conversion. This caused problems with mailbox names containing UTF-8 characters. The Dovecot API was changed years ago, but apparently sieve-filter was never updated. v0.4.20 27-08-2017 Stephan Bosch + Made the retention period for redirect duplicate identifiers configurable. For accounts that perform many redirects, the lda-dupes database could grow to impractical sizes. Changed the default retention period from 24 to 12 hours. - sieve-filter: Fixed memory leak: forgot to clean up script binary at end of execution. Normally, this would merely be an inconsequential memory leak. However, when the script comes from an LDAP storage, this would cause io leak warnings. - managesieve-login: Fixed handling of AUTHENTICATE command. A second authenticate command would be parsed wrong. This problem was caused by changes in the previous release. - LDA Sieve plugin: Fixed minor memory leak caused by not cleaning up the sieve_discard script. v0.4.19 26-06-2017 Stephan Bosch * This release adjusts Pigeonhole to several changes in the Dovecot API, making it depend on Dovecot v2.2.31. Previous versions of Pigeonhole will produce compile warnings with the recent Dovecot releases (but still work ok). - Fixed bug in handling of implicit keep in some cases. Implicit side-effects, such as assigned flags, were not always applied correctly. This is in essence a very old bug, but it was exposed by recent changes. - include extension: Fixed segfault that (sometimes) occurred when the global script location was left unconfigured. v0.4.18 12-04-2017 Stephan Bosch + imapsieve plugin: Implemented the copy_source_after rule action. When this is enabled for a mailbox rule, the specified Sieve script is executed for the message in the source mailbox during a "COPY" event. This happens only after the Sieve script that is executed for the corresponding message in the destination mailbox finishes running successfully. + imapsieve plugin: Added non-standard Sieve environment items for the source and destination mailbox. - multiscript: The execution of the discard script had an implicit "keep", rather than an implicit "discard". v0.4.17 26-02-2017 Stephan Bosch - LDA Sieve plugin: Fixed handling of an early explicit keep during multiscript execution. Action side-effects and the message snapshot would be lost at the final stage where the implicit keep is evaluated. This could result in the IMAP flags assigned to the message to be forgotten or that headers modified by the "editheader" extension would revert to their original state. - file script storage: Amended the up-to-date time stamp comparison for on-disk binaries to include nanoseconds. This will fix problems occurring when both binary and script are saved within the same second. This fix is ineffective on older systems that have no support for nanoseconds in stat() timestamps, which should be pretty rare nowadays. - file script storage: Improve saving and listing permission error to include more details. - imapsieve plugin: Make sure "INBOX" is upper case in static mailbox rules. Otherwise, the mailbox name would never match, since matching is performed case-sensitively and Dovecot only returns the upper-cased "INBOX". - imapsieve plugin: Fixed assert failure occurring when used with virtual mailboxes. - doveadm sieve plugin: Fixed crash when setting Sieve script via attribute's string value. v0.4.16 30-10-2016 Stephan Bosch * Part of the Sieve extprograms implementation was moved to Dovecot, which means that this release depends on Dovecot v2.2.26+. * ManageSieve: The PUTSCRIPT command now allows uploading empty Sieve scripts. There was really no good reason to disallow doing that. + Sieve vnd.dovecot.report extension: + Added a Dovecot-Reporting-User field to the report body, which contains the e-mail address of the user sending the report. + Added support for configuring the "From:" address used in the report. + LDA sieve plugin: Implemented support for a "discard script" that is run when the message is going to be discarded. This allows doing something other than throwing the message away for good. + Sieve vnd.dovecot.environment extension: Added vnd.dovecot.config.* environment items. These environment items map to sieve_env_* settings from the plugin {} section in the configuration. Such values can of course also be returned from userdb. + Sieve vacation extension: Use the Microsoft X-Auto-Response-Suppress header to prevent unwanted responses from and to (older) Microsoft products. + ManageSieve: Added rawlog_dir setting to store ManageSieve traffic logs. This replaces at least partially the rawlog plugin (mimics similar IMAP/POP3 change). - doveadm sieve plugin: synchronization: Prevent setting file timestamps to unix epoch time. This occurred when Dovecot passed the timestamp as 'unknown' during synchronization. - Sieve exprograms plugin: Fixed spurious '+' sometimes returned at the end of socket-based program output. - imapsieve plugin: Fixed crash occurring in specific situations. - Performed various fixes based on static analysis and Clang warnings. v0.4.15 07-07-2016 Stephan Bosch * vacation extension: The sieve_user_email setting is now used in the check for implicit delivery. - imapsieve plugin: For any mail transaction, the mailbox was opened a second time, even if no mailbox rule matched. This was unintentional, useless and caused problems when the imapsieve plugin was used with other plugins like acl. - extprograms plugin: Significantly improved error handling. No stream errors were logged. - extprograms plugin: Fixed bug in handling of result code from remote program (script service). - extprograms plugin: Connection to remote program service was not retried. - Several small fixes based on static analysis. - Fixed handling of quoted string localparts in email addresses. v0.4.14 26-04-2016 Stephan Bosch * The address test now allows specifying the X-Original-To header. + Implemented the Sieve imapsieve extension and its IMAP counterpart (RFC 6785) as a set of plugins. This allows running Sieve scripts at IMAP activity, rather than at delivery. There are also facilities for the familiar sieve_before/sieve_after administrator scripts. A user script is defined for a mailbox using an IMAP METADATA entry, whereas administrator scripts are configured using mailbox matching rules defined in the plugin settings. + Adjusted the Sieve ihave extension to allow capability tests to be performed at runtime. This way, scripts can be written that work both at delivery and from IMAP. + Implemented support for runtime trace debugging. This means that detailed information about which commands, actions and tests are performed is written to a file. That file is created in the configured directory, but only if that directory exists. This way, a particular user can be easily singled out for debugging. This works much like the Dovecot rawlog facility. The trace output is identical to what is produced using sieve-test with its "-t" command line option. + Added a "sieve_user_email" setting that configures the user's primary email address. This is mainly useful to have a user email address available in IMAP, where envelope data is unavailable. + Implemented the dovecot-specific "vnd.dovecot.report" extension. This allows sending report messages in the Message Abuse Reporting Format (RFC 5965). - extprograms plugin: Fixed epoll() panic caused by closing the output FD before the output stream. - Made sure that the local part of a mail address is encoded properly using quoted string syntax when it is not a dot-atom. v0.4.13 18-03-2016 Stephan Bosch * redirect action: Added the list-id header to the duplicate ID for mail loop prevention. This means that the message sent directly to the user and the message coming through the mailing list itself are treated as different messages by the loop detection of the redirect command, even though their Message-ID may be identical. * Changed the Sieve number type to uint64_t, which means that Sieve numbers can now technically range up to 2^64. Some other Sieve implementation allowed this, making this change necessary for successful migration. + Implemented the sieve_implicit_extensions setting. The extensions listed in this setting do not need to be enabled explicitly using the Sieve "require" command. This behavior directly violates the standard, but can be necessary for compatibility with some existing implementations of Sieve. Do not use this setting unless you really need to! - redirect action: Made mail loop detection more robust by forcibly adding a Message-ID header if it is missing. - Prevent logging a useless "script not found" error message for LDAP scripts for which the entry exists but no attribute containing a script. This is not necessarily an error. - extprograms plugin: Changed the communication channel between parent and child process for a directly forked program from a socketpair to a double pipe. Linux does not support /dev/stdin, /dev/stdout and friends for sockets. For some shell program authors this may be confusing, so that is why it is changed. When using the script service, these device nodes are still not usable though. v0.4.12 06-02-2016 Stephan Bosch + Implemented the Sieve extracttext extension (RFC 5703; Section 7). It is now possible to extract body text from a message into a variable. * Increased ABI version due to changes in the Sieve interpreter's object definitions. - multiscript: Fixed bug in handling of (implicit) keep; final keep action was always executed as though there was a failure. This caused the keep action to revert back to the initial message, causing editheader actions to be ignored. - managesieve-login: Fixed proxy to allow SASL mechanisms other than PLAIN. Before, the proxy would fail if the server did not support the PLAIN mechanism. - ldap storage: Prevent segfault occurring when assigning certain (global) configuration options. v0.4.11 08-01-2016 Stephan Bosch - Sieve mime extension: Fixed the header :mime :anychild test to work properly outside a foreverypart loop. - Several fixes in message body part handling: - Fixed assert failure occurring when text extraction is attempted on a empty or broken text part. - Fixed assert failure in handling of body parts that are converted to text. - Fixed header unfolding for (mime) headers parsed from any mime part. - Fixed trimming for (mime) headers parsed from any mime part. - Fixed erroneous changes to the message part tree structure performed when re-parsing the message. - LDA Sieve plugin: Fixed logging of actions; sometimes the configured log format was not followed. - LDA Sieve plugin: Fixed bug in error handling of script storage initialization. - Sieve Extprograms plugin: Ignored ENOTCONN error in shutdown(fd, SHUT_WR) call. - Fixed duplication of discard actions in the script result. Each discard was counted as a separate action, which means that action limit would be crossed too early. - Made sure that quota errors never get logged as errors in syslog. - Fixed handling of implicit keep for a partially executed transaction that yielded a temporary failure. - Fixed handling of global errors. If master and user error handler were identical, in some cases the log message could be lost. - Fixed AIX compile issue in message body parser. v0.4.10 13-12-2015 Stephan Bosch + Implemented the Sieve mime and foreverypart extensions (RFC 5703). These are fully implemented. The interaction with the editheader extension needs some work, but this should not influence most uses; i.e., changes by the editheader extension are not always visible using foreverypart/mime. + Sieve body extension: Properly implemented the `:text' body transform. It now extracts text for HTML message parts. + Sieve enotify extension: mailto method: Implemented the sieve_notify_mailto_envelope_from setting. This allows configuring the source of the notification sender address for e-mail notifications. This is similar to what already can be configured for redirect. + Added a sieve_enabled (defaults to 'yes') setting that allows explicitly disabling Sieve processing for particular users. This used to be possible by setting `sieve=', but ever since the sieve_before, sieve_after and sieve_default settings were added, this method was not reliable anymore. - variables extension: Fixed handling of empty string by the `:length' set modifier. An empty string yielded an empty string rather than "0". - Fixed memory leak in the Sieve script byte code dumping facility. Extension contexts were never actually freed. - Fixed handling of implicit keep when the last Sieve script is a global one. In that case the implicit keep action was executed in global context, which could mean that trivial (quota) errors ended up in the system log file, rather than the user log file. - doveadm sieve plugin: Fixed crashes caused by incorrect context allocation in the sieve command implementations. v0.4.9 04-10-2015 Stephan Bosch * Properly implemented checking of ABI version for Sieve interpreter plugins, much like Dovecot itself does for plugins. This will prevent plugin ABI mismatches. + Implemented a vnd.dovecot.environment extension. This builds upon the standard environment extension and adds a few more environment items, such as username and default mailbox. It also creates a variables namespace so that environment items can be accessed directly. I am still thinking about more environment items that can be added. + Sieve extprograms plugin: Made line endings of the input passed to the external programs configurable. This can be configured separately for each of the three extensions. + ManageSieve: Implemented proxy XCLIENT support. This allows the proxy to pass client information to the back-end. - ManageSieve: Fixed an assert failure occurring when a client disconnects during the GETSCRIPT command. - doveadm sieve plugin: Fixed incorrect initialization of mail user. This caused a few memory leaks. - sieve-filter command line tool: Fixed handling of failure-related implicit keep when there is an explicit default destination folder. This caused message duplication. - lib-sieve: Fixed bug in RFC5322 header folding. Words longer than the optimal line length caused empty lines in the output, which would break the resulting message header. This surfaced in References: headers with very long message IDs. v0.4.8 15-05-2015 Stephan Bosch * LDA Sieve plugin: Dovecot changed the deliver_log_format setting to include %{delivery_time}. This prompted changes in Pigeonhole that make this release dependent on Dovecot v2.2.17. + Implemented magic to make sieve_default script visible from ManageSieve under a configurable name. This way, users can see the default rules, edit them and store a private adjusted version. This could also be achieved by copying the default script into the user's script storage, but updates to the global sieve_default script would be ignored that way. + ManageSieve: Implemented support for reporting command statistics at disconnect. Statistics include the number of bytes and scripts uploaded/ downloaded/checked and the number of scripts deleted/renamed. - Fixed problem in address test: erroneously decoded mime-encoded words in address headers. - extprograms plugin: Fixed failure occurring when connecting to script service without the need to read back the output from the external program. - Fixed bug in script storage path normalization occurring with relative symbolic links below root. - Fixed and updated various parts of the documentation - ManageSieve: Used "managesieve" rather than "sieve" as login service name, which means that all managesieve-specific settings where ignored. - Managesieve: Storage quota was not always enforced properly for scripts uploaded as quoted string. Nobody uses that, but it is allowed in the specification and we support it, so it should work properly. v0.4.7 19-03-2015 Stephan Bosch * editheader extension: Made protection against addition and deletion of headers configurable separately. Also, the `Received' and `Auto-Submitted' headers are no longer protected against addition by default. * Turned message envelope address parse errors into warnings. * The interpreter now accepts non-standard domain names, e.g. containing '_'. + Implemented the Sieve index extension (RFC 5260). + Implemented support for the mboxmetadata and servermetadata extensions (RFC 5490). + Implemented new sieve commands for the doveadm command line utility. These commands are currently limited to ManageSieve operations, but the other current sieve tools will be migrated to doveadm in the near future as well. + Added more debug output about binary up-to-date checking. + Added script metadata to binary dump output. - Fixed Sieve script binary up-to-date checking by normalizing the script location. - The Sieve interpreter now flushes the duplicate database during start phase of result execution rather than commit phase. This makes sure locks on the duplicate database are released as soon as possible, preventing contention. - Performed a few optimizations in the lexical scanner of the language. - Fixed bug in `:matches' match-type that made a pattern without wildcards match as if there were a '*' at the beginning. - Fixed crash in validation of the string parameter of the comparator tag. - extprograms extension: Made sure supplemental group privileges are also dropped. This was a problem reported by Debian lintian. - Fixed bug in handling of binary errors for action side-effects and message overrides. - file script storage: Restructured storage initialization to address backwards compatibility issues. - dict script storage: Fixed small memory allocation bug. v0.4.6 02-11-2014 Stephan Bosch - After make distclean the distributed tarball would fail to recompile. This causes problems for some distribution builds. v0.4.5 30-10-2014 Stephan Bosch + Added a Pigeonhole version banner to doveconf output. This way, future bug reports will also include Pigeonhole version information. - Fixed handling of implicit keep. Last version erroneously reported that implicit keep succeeded after an earlier failure, while it in fact had failed. Particularly occurred for mailbox quota errors. - Fixed segfault occurring on SunOS systems when there is no active script. v0.4.4 28-10-2014 Stephan Bosch * Added support for Japanese mail addresses with dots at non-standard places in localpart. * Changed handling of ENOSPACE into a normal temporary failure and added handling of ENOQUOTA as a user error. * Restructured result execution, so that all actions which involve mail storage are always committed before all others. + Implemented support for generic Sieve storages. Using alternative storages now also possible for sieve_before/sieve_after. + Implemented storage driver for retrieving Sieve scripts from LDAP. This currently cannot be used with ManageSieve. + Implemented sieve_redirect_envelope_from setting, which allows configuring the envelope sender of redirected messages. - Fixed handling of mail storage errors occurring while evaluating the input message. - managesieve-login: - Removed bogus ALERT response code returned for AUTHENTICATE command. - Fixed handling of invalid initial response argument to AUTHENTICATE command. - Fixed handling of stream errors in lexical scanner. - Fixed handling of SMTP errors. Permanent and temporary errors were mixed up. - Fixed several problems reported by CLang 3.4. - duplicate extension: Fixed erroneous compile error about conflicting tags when `:handle' argument was used last. - relational extension: Fixed error handling of `:value' match. - editheader extension: Fixed header unfolding and header iteration. - mailbox extension: Fixed the `:create' tag, which erroneously subscribed an existing folder. - extprograms plugin: Fixed handling of error codes. - doveadm-sieve plugin: Fixed several bugs. Synchronization of symbolic link in the file storage should now also work properly. v0.4.3 12-05-2014 Stephan Bosch * Editheader extension: Made control characters allowed for editheader, except NUL. Before, this would cause a runtime error. + Upgraded Dovecot-specific Sieve "vnd.dovecot.duplicate" extension to match the new draft "duplicate" extension. - Fixed sieve_result_global_log_error to log only as i_info in administrator log (syslog) if executed from multiscript context. - Sieve redirect extension: Adjusted loop detection to show leniency to resent messages. - Sieve include extension: Fixed problem with handling of duplicate includes with different parameters :once or :optional. - Sieve spamtest/virustest extensions: Tests were erroneously performed against the original message. When used together with extprograms filter to add the spam headers, the changes were not being used by the spamtest and virustest extensions. - Deprecated Sieve notify extension: Fixed segfault problems in message string substitution. - ManageSieve: Fixed active link verification to handle redundant path slashes correctly. - Sieve vacation extension: - Fixed interaction of sieve_vacation_dont_check_recipient with sieve_vacation_send_from_recipient setting. - Fixed log message for discarded response. - Sieve extprograms plugin: - Forgot to disable the alarm() timeouts set for script execution. - Fixed fd leak and handling of output shutdown. - Fixed 'Bad filedescriptor' error occurring when disconnecting script client. - Made sure that programs are never forked with root privileges. v0.4.2 26-09-2013 Stephan Bosch * Incompatible change in Sieve doveadm plugin: the root attribute for Sieve scripts is changed. Make sure that you update both sides of a dsync setup simultaneously when Sieve is involved, otherwise synchronization will likely fail. + Added support for sending Sieve vacation replies with an actual sender, rather than the default <> sender. Check the updated doc/extensions/vacation.txt for more information. - Fixed a binary code read problem in the `set' command of the Sieve variables extension. Using the set command with a modifier and an empty string value would cause code corruption problems while running the script. - Various fixes for doveadm-sieve plugin, mostly crashes. These include a fix for the `Invalid value for default sieve attribute' problem. - Various fixes for compiler and static analyzer warnings, e.g. as reported by CLang and on 32 bit systems. - Fixed the implementation of the new :options flag for the Sieve include extension. - Fixed potential segfault bug at deinitialization of the lda-sieve plugin. - Fixed messed up hex output for sieve-dump tool. v0.4.1 03-06-2013 Stephan Bosch + Added support for handling temporary failures. These are passed back to LDA/LTMP to produce an appropriate response towards the MTA. - Sieve storage: Removed PATH_MAX limitation for active symlink. This caused problems for GNU/Hurd. - Fixed line endings in X-Sieve headers added by redirect command. - ManageSieve: Fixed '[' ']' stupidity for response codes (only happened before login). - Fixed setting name in example-config/conf.d/20-managesieve.conf. - Sieve extprograms plugin: Fixed interaction between pipe command and remote script service. The output from the script service was never read, causing a broken pipe error at the script service. Apparently, this was broken since the I/O handling for extprograms was last revised. - Fixed assertion failure due to datastack problem in message header composition. v0.4.0 09-05-2013 Stephan Bosch + Added doveadm-sieve plugin that provides the possibility to synch Sieve scripts using doveadm sync along with the user's mailboxes. + Added the Sieve extprograms plugin to the main Pigeonhole package. It is still a plugin, but it is now included so that a separate compile is no longer necessary and distributors are likely to include it. The extprograms plugin provides Sieve language extensions that allows executing (administrator-controlled) external programs for message delivery, message filtering and string manipulation. Refer to doc/plugins/sieve_extprograms.txt for more information. + Added debug message showing Pigeonhole version at initialization. Makes it very clear that the plugin is properly loaded. + Finished implementation of the Sieve include extension. It should now fully conform to RFC 6609. The main addition is the new :optional tag which makes the include command ignore missing included scripts without an error. + Finished implementation of the Sieve environment extension as much as possible. Environment items "location", "phase" and "domain" now also return a usable value. v0.3.6 26-09-2013 Stephan Bosch - Fixed a binary code read problem in the `set' command of the Sieve variables extension. Using the set command with a modifier and an empty string value would cause code corruption problems while running the script. - Various fixes for compiler and static analyzer warnings, as reported by CLang. - ManageSieve: Fixed '[' ']' stupidity for response codes (only happened before login). - Fixed setting name in example-config/conf.d/20-managesieve.conf. - Fixed messed up hex output for sieve-dump tool. v0.3.5 09-05-2013 Stephan Bosch - Sieve editheader extension: fixed interaction with the Sieve body extension. If used together, the deleteheader action could fail after a body test was performed. - Test suite: fixed a time zone dependency in the Sieve date extension tests. v0.3.4 06-04-2013 Stephan Bosch * Changed error handling to be less of a nuisance for administrators. Strictly user-caused errors are only reported in user log. Some errors are logged as info instead. * Sieve: Changed behavior of redirect in case of a duplicate message delivery or a mail loop. If a duplicate is detected the implicit keep is canceled, as though the redirect was successful. This prevents getting local deliveries. The original SMTP recipient is used when it is available to augment the entry in the LDA duplicate database. This way, duplicates are only detected when (initially) addressed to the same recipient. + Sieve vnd.dovecot.duplicate extension: added new features to the duplicate test, making it possible to manually compose the key value for duplicate checking. This extension is in the process of being standardized (https://tools.ietf.org/html/draft-bosch-sieve-duplicate-01). + Sieve date extension: generate warning when invalid date part is specified. - Sieve editheader extension: fixed crash occurring when addheader :last was used. - Sieve include extension: fixed missing error cleanup that caused a resource leak. - Sieve vacation extension: fixed determination of From: address for when sieve_vacation_dont_check_recipient is active. - Sieve tools: the -D option wasn't enabled and documented for all tools. - Siev dict script storage: fixed potential segfault occurring when dict initialization fails. - ManageSieve: fixed bug in skipping of CRLF at end of AUTHENTICATE command. - ManageSieve: fixed handling of unkown commands pre-login. - Fixed compile on Mageia Linux. v0.3.3 18-09-2012 Stephan Bosch - Fixed compile against installed Dovecot headers. This was broken by the ld.gold fix in the previous release. v0.3.2 18-09-2012 Stephan Bosch + sieve-refilter tool: improved man page documentation by explicitly specifying the syntax used for mailbox arguments. + Sieve: spamtest and virustest extensions: improved trace debugging of score calculation. + Sieve: made error messages about exceeding the maximum number of actions more verbose. - Sieve tools: fixed problems with running as root: sievec and sieve-dump now ignore mail_uid and mail_gid settings when run as root. - Sieve: fixed bug in action accounting (for limit checking): increase action instance count only when an action is actually created. - Sieve: include extension: fixed namespace separation of :global and :personal scripts. - ManageSieve: fixed segfault bug triggered by CHECKSCRIPT command. - Fixed linking with ld.gold. - Fixed several Clang compile warnings and a few potential bugs. v0.3.1 25-05-2012 Stephan Bosch * Added support for retrieving Sieve scripts from dict lookup. This means that Sieve scripts can now be downloaded from a database. Compiled script binaries are still put on disk somewhere if used. The INSTALL documentation is updated with information on this new feature and the (backwards-compatible) changes to the configuration. Note that his feature is currently not supported for sieve_before/sieve_after or script management through ManageSieve. + Incorporated the sieve_duplicate plugin into main Pigeonhole tree as a normal extension (vnd.dovecot.duplicate). This Dovecot-specific extension adds the ability to check for duplicate deliveries based on message ID. Specification can be found in: doc/rfc/spec-bosch-sieve-duplicate.txt + Added support for specifying multiple sieve_before and sieve_after paths. This adds much more flexibility to the multiscript configuration. One application is to have user-specific Sieve scripts outside the user's normal control through ManageSieve. + Added a "session ID" string for managesieve connections, available in %{session} variable (analogous to Dovecot change). - Fixed several small issues, including a few potential segfault bugs, based on static source code analysis. - ManageSieve: changed use of EPROTO error to EIO in ManageSieve string stream implementation because it is apparently not known in BSD. - Gave stamp.h.in (needed for autotools) some content to prevent it from disappearing in patch files. - Fixed bug that caused a SunStudio CC compile failure (reported by Piotr Tarnowski). v0.3.0 16-02-2012 Stephan Bosch * Renamed sieve_global_path setting to sieve_default for clarity. Old name is still recognized for backwards compatibility. Support for the ancient (pre v1.1) name for this setting "global_script_path" is now dropped. * Added means to prohibit use of redirect action. Setting sieve_max_redirects to 0 now means that redirect is disallowed instead of unlimited. Default value remains four. * Fixed interaction of Sieve include extension with ManageSieve. It is updated to match new requirements in the draft include specification. Missing included scripts are no longer an error at upload time. * Updated RFC2822 header field body verification to exclude non-printing characters (RFC5322). Only Sieve actions that can create unstructured header values (currently enotify/mailto and editheader) are affected by this change. + Completed sieve-filter tool to a useful state. The sieve-filter tool provides a means to (re)filter messages in a mailbox through a Sieve script. + Implemented the Sieve editheader extension. It is now possible to add and remove message headers from within Sieve. + ManageSieve: added support for reading quoted and literal strings as a stream. Fixes support for handing large SASL responses (analogous to similar changes in Dovecot). It is now also allowed to use a quoted string for the PUTSCRIPT script argument. + Added code to cleanup tmp directory in Sieve storage directory (sieve_dir) every once in a while. + Added support for substituting the entire message during Sieve processing. This is used for the filter action provided by the new sieve_extprograms plugin (provided separately for now). The filter action allows passing the message through an external program. + Added support for restricting certain Sieve language extensions to (admin-controled) global scripts. Restricted extensions can be configured using the new sieve_global_extensions setting. This is particularly useful for some of the Dovecot-specific (plugin-based) Sieve extensions, that can be somewhat hazardous when under direct control of users (e.g. sieve_extprograms). v0.2.6 13-02-2012 Stephan Bosch * This release fixes unintentional behavior of the include extension. Included scriptnames with a name like "name.sieve" would implicitly map to a script file called "name.sieve" and not "name.sieve.sieve". Keep in mind that the .sieve file extension has no meaning from within the Sieve language. A Sieve script is always stored with an appended .sieve file extension, also when the name already ends with a .sieve suffix. IMPORTANT: Some installations have relied on this unintentional feature, so check your script includes for issues before upgrading. * Matched changes regarding auth_verbose setting in Dovecot. This means that this release will only compile against Dovecot v2.0.18. - Fixed problem in ManageSieve that caused it to omit a WARNINGS response code when the uploaded script compiled with warnings. - Made sure that locations of Sieve error never report `line 0'. - Fixed potential segfault occurring when interpreter initialization fails. v0.2.5 19-11-2011 Stephan Bosch + Sieve vacation extension: made discard message for implicit delivery more verbose - The sieve-test tool: mixed up original and final envelope recipient in implementation of command line arguments. - Sieve vacation extension: resolved FIXME regarding the use of variables in the :handle argument. Variables are now handled correctly. - Sieve body extension: fixed handling of :content "message/rfc822". This now yields the headers of the embedded message as required by the specification. Handling of :content "multipart" remains to be fixed. - LDA Sieve plugin: fixed problem with recipient_delimiter configuration. Now falls back to global recipient_delimiter setting if plugin/recipient_delimiter is not set. v0.2.4 13-09-2011 Stephan Bosch + Vacation extension: finally added support for using the original recipient in vacation address check. It is also possible to disable the recipient address check entirely. Check doc/vacation.txt for configuration information. + Include extension: made limits on the include depth and the total number of included scripts configurable. Check doc/include.txt for configuration information. + Implemented ihave extension. This allows checking for the availability of Sieve language extensions at 'runtime'. Actually, this is checked at compile time. At runtime the interpreter checks whether extensions that were not previously available are still unavailable. If the situation changed, the script is re-compiled and the ihave tests are evaluated again. + Sieve: optimized compilation of tests that yield constant results (i.e. known at compile tme), such as 'true' and 'false'. No code is produced anymore for script sections that are never executed. Also, semantics are not verified anymore in uncompiled script sections. + Made vnd.dovecot.debug extension available to the LDA plugin instead of only the command line tools. + Sieve: redirect action now adds X-Sieve-Redirected-From header (mainly for people using SPF/SRS). - Sieve: fixed bug in handling flags and keywords; in case of error an assertion was triggered. - Script storage: improved handling of unconfigured user home directory. Originally this would produce an unhelpful error message. - Imap4flags extension: prevent forcibly enabling imap4flags when imapflags is enabled. - Fixed various -Wunused-but-set-variable compiler warnings. - Include extension: forgot to check variable identifier syntax for 'global' command. - Sieve: fixed debug mode; no messages were logged in some situations. - sievec tool: forgot to enable -D (debug) parameter. v0.2.3 14-04-2011 Stephan Bosch * Sieve filter tool: finished implementing basic functionality. It is not quite ready yet, but it is available for those willing to experiment with it (needs --with-unfinished-features config to compile). Also includes man page. + Vacation extension now inhibits replies to messages from sender listed in :addresses, thus preventing replies to one of the user's other known addresses. + Vacation extension: implemented the (draft) vacation-seconds extension. This also adds min/max period configuration settings. Refer to doc/vacation.txt for configuration information. - ManageSieve: fixed bug in UTF-8 checking of string values. This is done by discarding the original implementation and migrating to the Dovecot API's UTF-8 functionality. - Sieve command line tools now avoid initializing the mail store unless necessary. This prevents sievec and sieve-dump from failing when executed by root for example. - Enotify extension: fixed inappropriate return type in mailto URI parse function, also fixing ARM compiler warning. - Vacation extension: fixed handling of sendmail errors. It produced an additional confusing success message in case of error. - Removed header MIME-decoding to fix erroneous address parsing. Applies to address test and vacation command. - Fixed segfault bug in extension configuration, triggered when unknown extension is mentioned in sieve_extensions setting. v0.2.2 06-12-2010 Stephan Bosch * LDA Sieve plugin: started using Dovecot LDA reject API for the reject extension. This means that the LDA reject_reason and reject_subject settings now also work for Pigeonhole's LDA Sieve plugin. * Did some work on the new sieve-filter tool. It is mostly functional, but it is not finished yet. * Dovecot change: services' default vsz_limits weren't being enforced correctly in earlier v2.0 releases. Now that they are enforced, you might notice that the default limits are too low and you need to increase them. This problem will show up in logs as "out of memory" errors. See default_vsz_limit and service { vsz_limit } settings. - Imap4flags: fixed segfault bug occurring in multiscript context. - Added version checking to the ManageSieve settings plugin. This plugin was forgotten when the LDA plugin was updated with this change in the previous release. - LDA Sieve plugin: fixed memory leak at deinitialization. v0.2.1 27-09-2010 Stephan Bosch + Incorporated distinction between original and final envelope recipient in Sieve interpreter, as recently introduced in Dovecot. + Regex extension: added support for regex keys composed from variables. - LDA Sieve plugin: added _version symbol to enable Dovecot's plugin version check. Without this check, people can forget to recompile the plugin, which can lead to unexpected effects. - LDA Sieve plugin: turned debug message about an unconfigured home directory into a proper error and added script path information. - Fixed unnecessary reporting of dummy extensions in ManageSieve SIEVE capability; the comparator-i;octet and comparator-i;ascii-numeric 'extensions' were reported explicitly. v0.2.0 10-09-2010 Stephan Bosch * Merged Sieve and ManageSieve packages into a single Pigeonhole package. There is also no need to patch Dovecot anymore to gain ManageSieve support. Version numbering of previous Sieve releases is continued as v0.2.0. The sources originally branched off from Sieve v0.1.5 and ManageSieve v0.11.4, but the NEWS history of much more recent releases for Dovecot v1.2 is included since these changes are all included in this release as well. * The ManageSieve service now binds to TCP port 4190 by default due to the IANA port assignment for the ManageSieve service. When upgrading from v1.2, this should be taken into account. The service can be configured manually to listen on both 2000 and 4190. * The Dovecot configuration now calls the ManageSieve protocol 'sieve' in stead of 'managesieve' because it is registered as such with IANA. The binaries and the services are still called managesieve and managesieve-login. * The binary representation of a compiled Sieve script is updated to include source code locations of all commands and arguments. This is implemented in a similar manner as such debug information is included in some system executables and libraries (DWARF-like). Run-time errors can now always refer to the proper line number in the Sieve source script. * The Sieve plugin is adapted to work properly with the new LMTP service introduced with Dovecot v2.0. The same plugin is used for both LDA and LMTP. * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension is now known as 'recipient_delimiter'. Although the deprecated sieve_subaddress_sep setting is still recognized for backwards compatibility, it is recommended to update the setting to the new name, since the new LMTP service also uses the recipient_delimiter setting. * ManageSieve: changed default IMPLEMENTATION capability to from 'Dovecot' to 'Dovecot Pigeonhole'. * Renamed the sieved tool to sieve-dump. The original name was somewhat confusing. * Updated man pages to match style and structure of new Dovecot man pages. * Made testsuite commands more uniform and cleaned up many of the testsuite scripts. Some minor new tests were added in the process. + Simplified string matching API to use abstract string lists as data sources. This will also make implementing the index extension easier in the future. + Significantly improved trace debugging with the sieve-test tool. The full execution of the script can be examined, including the matched values and keys of the respective Sieve test commands. The executed statements are listed with their line number (and code address when requested). The level of detail is configurable from the command line. + The SIEVE and NOTIFY capabilities reported by the ManageSieve protocol can now be configured manually. If left unconfigured, the capabilities are determined from the default Sieve and ManageSieve configuration. User-specific capabilities aren't reported until after authentication. + Significantly improved file error handling. This means that administrators get a more useful and informative log message when file operations fail. The most notable example is that when the LDA Sieve plugin is trying to store a binary for a global script, the resulting failure message also points the administrator towards pre-compiling the script with sievec. + Added runtime argument value checking for several commands (redirect, date vacation). When variables are used, these checks cannot be performed at compiletime. A proper runtime error now is produced when invalid data is encountered. + UTF8 validity of fileinto command argument is now checked either at compile time or at runtime. Previously, it was not checked until the store action was executed. + Validity of IMAP flags for the imap4flags extension is now checked also at runtime. Previously, it was not checked until the store action was executed. + Simplified and restructured error handling. Also made sure that user-caused errors are no longer written to the Dovecot master/LDA log. - Multiscript: fixed duplicate implicit keep caused by erroneous execution state update. - Prevented assertion failure due to currupt binary string representation. If the string was missing a final \0 character an assertion was produced in stead of a binary corruption error. - Imap4flags: fixed bug in setflag command; when parameter was a stringlist, only the last item was actually set. - Variables extension: fixed :length set modifier to recognize utf8 characters instead of octets. - Testsuite: prevented innocent warning messages, i.e. those that are part of the test, from showing up by default. - ManageSieve/Sieve storage: fixed error handling of PUTSCRIPT commmand; save commit errors would not make the command fail. - ManageSieve: enforced protocol syntax better with some of the commands; some commands allowed spurious extra arguments. - Fixed Sieve script name checking to properly handle length limit and added 0x00ff as invalid character. - Removed spurious old stdio.h (top) includes; these caused compile issues on specific systems. - Fixed default Sieve capability (as reported by ManageSieve): extra extensions spamtest, spamtestplus and virustest were enabled by default. These should, however, only be enabled when properly configured and there is no default configuration. (Fused Dovecot Sieve and ManageSieve packages into a single Pigeonhole release) Dovecot Sieve NEWS history: --------------------------- Dovecot 1.2: v0.1.17 19-06-2010 Stephan Bosch - Made sure source code positions for compiler messages are recorded at start of tokens. - Fixed a few potential memory leaks in the Sieve compiler and the spam/virustest extensions. - Made command line tools return proper exit status upon failure. v0.1.16 30-04-2010 Stephan Bosch * Finished implementation of spamtest, spamtestplus and virustest extensions. These are not enabled by default and need to be activated with the sieve_extensions setting. Documentation available in doc/spamtest-virustest.txt + Vacation extension: the from address of the generated reply is now by default equal to whatever known recipient alias matched the headers of the message. If it is one of the aliases specified with :addresses, it is used instead of the envelope recipient address that was used before. + Restructured and optimized the lexical scanner. + Added --with-docs configure option to allow disabling installation of documentation. - Accidentally omitted 'extern' in two declarations of global variables in header files, causing compile failures on certain systems. - Deprecated imapflags extension: fixed implicit assignment of flags. Turns out this never really worked, but the effect of this bug was obscured by the removeflag bug fixed in the previous release. - Fixed various memset argument mixups in enotify extension. This caused warnings on certain systems, but luckily no adverse effects at runtime. v0.1.15 25-01-2010 Stephan Bosch * Enotify extension: - Adjusted notify method API for addition of new notification methods. - Set default importance level to 'normal' (was 'high'). * Include extension: updated implementation towards most recent specification (all should be backwards compatible): - Implemented global variables namespace. - Global command may now appear anywhere in a script. - Implemented script name checking using the requirements specified in the ManageSieve draft. - One issue remains: ManageSieve currently requires included scripts to be uploaded first, which is not according to specification. * Changed envelope path parser to allow to and from envelope addresses that have no domain part. + Added preliminary support for Sieve plugins and added support for installing Sieve development headers. + Started work on the implementation of the spamtest, spamtestplus and virustest extensions (unfinished). + Deprecated notify extension: implemented denotify command. + Variables extension: added support for variable namespaces. + Added configurable script size limit. Compiler will refuse to compile files larger than sieve_max_script_size. + Testsuite changes: - Added support for changing and testing an extension's configuration. - Added a command line parameter for copying errors to stderr. - Fixed a bug in the i;ascii-numeric comparator. If one of the strings started with a non-digit character, the comparator would always yield less-than. - Imap4flags extension: fixed bug in removeflag: removing a single flag failed due to off-by-one error (bug report by Julian Cowley). - Improved EACCES error messages for stat() and lstat() syscalls and slightly improved error messages that may uccur when saving a binary. - Vacation extension: fixed typo in runtime log message (patch by Julian Cowley). - Fixed use of minus '-' in man pages; it is now properly escaped. - Fixed parser recovery. In particular cases it would trigger spurious errors after an initial valid error and sometimes additional errors were inappropriately ignored. v0.1.14 19-12-2009 Stephan Bosch * Made the imposed limits on the number of redirects and the number of actions configurable. The settings are called sieve_max_actions and sieve_max_redirects. * Did a major rework of extension handling, making sure that no global state is maintained. This change was triggered by problems that global state info would cause for Dovecot v2.0, but it is also important for v1.2 as it significantly cleans up the library implementation. + Made LDA Sieve plugin recognize the deliver_log_format setting. + Message headers produced from user-supplied data are now RFC2047-encoded if necessary for outgoing messages. This is for example important for the :subject argument of the vacation action. + Added support for the $text$ substitution in the deprecated notify extension. + The subaddress extension now also accepts recipient_delimiter setting as an alias for sieve_subaddress_sep setting. This anticipates the recipient_delimiter setting in v2.0. - Fixed logging of mailbox names. It logged the converted mUTF7 version in stead of the original UTF8 version supplied by the user. - Fixed a minor memory leak in the multiscript support. - Fixed a bug in the recompilation of Sieve scripts. Made sure that scripts are only recompiled when the script file - or the symlink pointing to it - is strictly newer. v0.1.13 18-10-2009 Stephan Bosch + Body extension: implemented proper handling of the :raw transform and added various new tests to the test suite. However, :content "multipart" and :content "message/rfc822" are still not working. + Fixed race condition occurring when multiple instances are saving the same binary (patch by Timo Sirainen). + Test suite: added support for testing multiscript execution. - Made compiler more lenient towars missing CRLF at the end of the script in a hash comment. - Body extension: don't give SKIP_BODY_BLOCK flag to message parser, we want the body! (patch by Timo Sirainen). - Fixed handling of implicit side effects for multiscript execution. - Fixed bugs in multiscript support; subsequent keep actions were not always merged correctly and implicit side effects were not always handled correctly. - Fixed a segfault bug in the sieve-test tool occurring when compile fails. - Fixed segfault bug in action procesing. It was triggered while merging side effects in duplicate actions. - Fixed bug in the Sieve plugin that caused it to try to stat() a NULL path, yielding a 'Bad address' error. v0.1.12 21-08-2009 Stephan Bosch + Testsuite: added support for testing binaries stored on disk. + Implemented the new date extension. This allows matching against date values in header fields and the current date at the time of script evaluation. v0.1.11 08-08-2009 Stephan Bosch + Built skeleton implementation for the date extension (RFC 5260). It compiles, but it does not do anything useful yet. Therefore, it is not part of the default compilation. - Fixed ARM portability issues caused by char type not being signed on that platform. Reading optional operands from a binary would fail for action side effects. Also, an accidental mixup of an int return type with bool caused the interpreter to continue on ARM even though an error occured. - Removed direct stdint.h includes to prevent portability issues. - Fixed segfault bug in the handling of script open failures. - Include: improved user error messages and system log messages. - Fixed copy-paste mixup between sieve_after and sieve_before settings in the LDA Sieve plugin. If only a sieve_after script was active, nothing would have been executed. Patch by Mike Abbott. - Include: fixed a bug in HOME substitution in the sieve_dir path. Surfaced in ManageSieve. v0.1.10 03-08-2009 Stephan Bosch * Changed action execution of fileinto and keep. These changes depend on API additions in Dovecot, making this release depend on Dovecot v1.2.2 or newer. * Further developed the sieve-filter command line tool. This required a few changes to the action execution of the Sieve engine. The tool was successfully tested on folders with a few 100k spam messages. However, the commandline options are still incomplete, a man page is missing and it needs much more testing before I can recommend anyone to use this tool. + Added support for the mailbox extension. This allows checking whether a mailbox exists using the mailboxexists command and it adds the :create argument to the fileinto command to create the mailbox when it is missing. The :create feature is useless unless the Deliver LDA is run with the -n option. + Improved the testsuite with tests for message delivery. Messages stored using keep and fileinto can be fed back into the Sieve engine for verification. This includes testing of applied IMAP flags. + Updated the man pages with the new method of specifying the supported extensions using + and - (for the -x parameter of the sieve tools) + Further developed the deprecated notify extension. A dummy for the denotify command exists, meaning that its use does not cause an error anymore. - Fixed a bug in the derivation of the binary path from the script path. A bare filename would yield a path relative to root. - Fixed a bug in the value matching code. The context data now uses a proper pool instead of the data stack. Bug reported by Jan Sechser. - Fixed assertion fail in the include extension caused by missing initialization upon binary load. This bug surfaces only for stored binaries. Bug reported by Tom Hendrikx. - Fixed include error message for failed :global include. It mentioned the wrong config parameter. - Fixed broken wiki reference in an error message of the plugin about the 'sieve' setting. - Fixed behavior of fileinto when delivering into a namespace prefix. Previous fix used the wrong storage. v0.1.9 22-07-2009 Stephan Bosch * Removed the unfinished sieve-filter tool from the default build. It is now only built when the --with-unfinished-features switch is supplied during configure. + Started building support for the ereject version of the reject action, which has a preference to use an SMTP/LMTP protocol error instead of a bounce message. This is to be used to make the Sieve plugin honour Deliver's -e parameter. This is not yet finished and not built by default. + Improved 'Permission denied' error messages just like Dovecot does, precisely specifying what permission is missing to access or create a file. + Added additional headers to the list of allowed headers for the address test. The restrictive nature of the address test is not always appropriate. Still thinking of a better, less restrictive implementation. + Made the deprecated notify extension compatible with the old CMUSieve plugin. However, the denotify command and the $text$ substitution are not yet supported. + Made the discard action log a message to avoid confusion about disappearing messages. - Fixed behavior of fileinto when delivering into a namespace prefix. It now uses silent delivery into INBOX as fallback. - Fixed logging of folder namespace prefix upon delivery into a prefixed namespace. Formerly it only logged the bare folder name. - Fixed a potential segfault in the argument validation. It didn't surface because no command could have a :tag followed by an associated parameter as last argument. - Fixed segfault bug occurring in envelope test when performed on null (<>) envelope path. The fix involves a rather large restructuring of the code to make sure envelope addresses are properly handled everywhere (bug reported by Nikita Koshikov) - Envelope: fixed bug in application of address parts; failure to obtain the part would cause inappropriate match success (bug reported by Ron Lee) - Fixed extension conflict checks during validation. It could sometimes produce useless errormessages. This is currently only used by the deprecated extensions. - Forgot to remove old explicit storage library dependency (patch by Arkadiusz Miskiewicz). - Fixed compiler warnings on certain platforms regarding the use fwrite for outgoing message construction v0.1.8 12-07-2009 Stephan Bosch - Fixed AIX compile problem. For portability, the typeof operator is not used anymore. + Added partial support for the deprecated notify extension. However, it turns out that the implementation provided by cmusieve is even older (2001), meaning that this is currently not backwards compatible with cmusieve. v0.1.7 05-07-2009 Stephan Bosch + Added support for CRLF line breaks in strbuf error handler to fix a ManageSieve problem. + Improved consistency of sieve tool documentation and fixed missing parameters in internal tool help output. + Enhanced extensions configuration, allowing to specify the enabled extensions relatively to the default (patch by Steffen Kaiser). - Forgot to initialize script execution status in Sieve plugin, causing segfaults on compile errors in specific conditions. - Fixed logging in Sieve plugin for execution of default main script (went to STDERR). v0.1.6 18-06-2009 Stephan Bosch * Adjusted to changes in Dovecot to make it compile against v1.2.rc5 * Made default of sieve_dir setting match the ManageSieve implementation. - Fixed a few problems in de body extension that caused assert failures in specific situations. v0.1.5 18-04-2009 Stephan Bosch * Ported the implementation of the Sieve include extension to the latest draft. This means that the import and export commands are replaced by a new command called global. The import and export commands are now DEPRICATED and are mere aliases for the global command. The new specification also adds the :once modifier to the include command. The also newly specified global.* variable namespace is not implemented yet as support for variable namespaces is currently missing. * Did a major rework of the multiscript support for better error handling and made sure that persistent global scripts (sieve_before/sieve_after) are always executed, even when the user does not have a script of his own and a global default is missing. + Provided basic support for the environment extension. Currenly, the name, version and host items are useful. Others are pending. + Improved error message that is presented when an unknown Sieve extension is provided as argument to the require command. It now notifies the user that Sieve core commands do not need to be specified in require. - Fixed bug in includes at levels deeper than one. - Fixed bug in address matching that was caused by the failure to handle group specifications. In dovecot, these are marked by address items with NULL elements, which causes a segfault if not considered. The group 'undisclosed- recipients:;' in particular triggered this bug. Bug reported by Bernhard Schmidt. v0.1.4 21-03-2009 Stephan Bosch * Started work on the sieve-filter tool. With this command line tool it will be possible to (re-)apply Sieve filters on a mail folder. It is currently undocumented and far from functional. + Added a custom debug extension that provides the possibility to print debug messages from scripts executed by the Sieve tools. - Fixed issue with opening relative paths as a mail file. Bug reported by Ian P. Christian. - Fixed MAC OSX compile problem. Turns out the extern modifier was missing at multiple places. Bug reported by Edgar Fuss. - Fixed Solaris compile problem: removed unecessary and unportable linker flags that caused compile to fail. Bug reported by Andrés Yacopino. v0.1.3 12-02-2009 Stephan Bosch * Adapted to changes in Dovecot, making this release dependent on Dovecot >= 1.2.beta1 * Made mail address comparison fully case-insensitive. This is particularly noticeable for the :addresses argument of the vacation command. + Finished enotify extension. Currently, only the mailto notification method is implemented. All still needs to be tested thoroughly. + Implemented multiscript support. It is now possible to execute multiple Sieve scripts sequentially. Administrator-controlled scripts can be executed before and after the user's script. Still needs to be tested thoroughly. + Implemented support for configuring the available Sieve extensions. + Made the subaddress extension (partially) configurable using the sieve_subaddress_sep setting, which allows specifying a (multi-charater) separator other than '+'. + Compiler now warns about invalid header field names used for the header and address tests. + Vacation extension now properly generates a References header for the response message. + Added testing of basic result execution to the test suite. Also added supportfor testing the outgoing messages produced by the Sieve interpreter. + Included execution of the actual result in the sieve-test command line tool. The undocumented sieve-exec tool that existed for this is now removed as planned. + Added support for the now obsolete 'imapflags' extension for backwards compatibility with CMUSieve. This also implements the mark/unmark commands. - Fixed bugs in the regex extension: 1) if an optional match value did not in fact match, subsequent match values would get unexpected indexes. 2) fixed segfault bug occurring when regex is freed. - Fixed bug in the use of the :from agrument for the vacation command. If this address included a phrase part, the response would not be a valid RFC822 message. - Plugged a theoretical security hole occurring when a directory is opened as a Sieve binary. - Cleaned up and fixed various log messages. - Fixed bug in the outgoing address verification. Addresses ending in ',' were erroneously accepted. v0.1.2 26-11-2008 Stephan Bosch - Fixed important bug in the redirect action (and probably other actions like reject and vacation that only send messages). This was a bug in the handling of context information during the execution of actions. It caused the sieve interpreter to crash with a segfault when redirect was executed. v0.1.1 24-11-2008 Stephan Bosch * Re-enabled support for compiling against dovecot headers. Much like cmusieve, command line tools like sievec and sieved are not compiled in this case. * Started implementation of enotify extension. Not anywhere near finished though. * Adapted to changes in Dovecot on various occasions, making this release dependent on Dovecot >= v1.2.alpa4. + Improved logging of errors at specific occasions and added debug messages to find script execution problems quicker. + Removed code duplication between command line tools and the test suite. Also restructured the sources of the tools. + Added UTF-8 to UTF-7 folder name conversion for compatibility with IMAP. + Created man pages for the command line tools. These are automatically installed upon 'make install' + Incorporated Valgrind support into the testsuite and fixed a few memory leaks in the process. - Fixed compile error surfacing for gcc3.4. Forgot mask argument for the open() system call when the O_CREAT flag is specified. Bug found by Sergey Ivanov. - Fixed bug in the sievec tool. -d output was always written to stdout. - Fixed important bug in the imap4flags extension. When no :flags argument is specified, the previous version would always use the final value of the internal variable to set the flags. This means that modifications to the internal variable also affected the bare fileinto/keep actions executed earlier. This does not comply to the RFC. - Fixed bug in the include extension's import/export commands. Duplicate import/exports caused problems. - Fixed bug in the handling of non-existent scripts. Errors were sometimes ignored. - Dovecot omitted unfolding multi-line headers. This was added to the cmusieve plugin after the code was incorporated into the new implementation. This is now mplicitly fixed by concurrent change in Dovecot. v0.1.0 23-10-2008 Stephan Bosch * Initial release Dovecot ManageSieve NEWS history: --------------------------------- Dovecot 1.2: v0.11.11: * This release contains adjustments to match changes in the Sieve API. This means that this release will only compile against Pigeonhole Sieve v0.1.15. + Implemented ManageSieve QUOTA enforcement. + Added MAXREDIRECTS capability after login. + Implemented new script name rules specified in most recent ManageSieve draft. - Fixed assertion failure occurring with challenge-response SASL mechanisms. - Made configure complain about trying to compile against installed Dovecot headers alone. - Fixed compile warning for compilation against CMUSieve. v0.11.10: * This release contains adjustments to match changes in the Sieve API. This means that this release will only compile against Pigeonhole Sieve v0.1.14. - Fixed compilation of ManageSieve against CMUSieve. v0.11.9: * Adjusted to changes in the Dovecot login proxy API. This release therefore depends on Dovecot v1.2.4. + Reintroduced ability to abort SASL with "*" response. Latest ManageSieve specification includes it. v0.11.8: - Fixed TLS support for proxying ManageSieve. The protocol state machine was incorrect. Also added a check that disables ssl when 'starttls' is not enabled for the user. This produces a proper warning in the log file. There is no such thing as a managesieveS protocol which has SSL from the start. v0.11.7: * Adjusted to changes in the Dovecot login API. This release now depends on Dovecot v1.2.1 or newer. * Incorporated various small changes in IMAP into ManageSieve. This includes properly enabling the generation of core dumps. - The previous release implicitly resolved the FreeBSD script truncation error. This release adds a small correction to the code that detects the truncation. - Fixed panic occurring when many errors are produced by the Sieve compiler (bug found by Pascal Volk). - Fixed memory leak in the PUTSCRIPT command. v0.11.6: * Adjusted to changes in Dovecot regarding client idle timeout vs authentication timeout. This release now depends on Dovecot v1.2.rc6 or newer. - Fixed CRLF line breaks in compile errors (bug reported by Pascal Volk). - Corrected directory/file creation behavior with respect to mode bits and gid (bug reported by Pascal Volk). - Improved handling of script truncation bugs: connection is now closed and an error is logged. bug itself not fixed yet). - Prevented temp script name from showing up in error output. v0.11.5: * Incorporated various changes from imap-login into managesieve-login. This includes changes in the proxy support. v0.11.4: * Adjusted to changes in the Dovecot signal handler API. v0.11.3: * Changed the SASL service name from "managesieve" into "sieve" as required in the protocol specification. Don't forget to adjust your configuration if your authentication mechanism depends on this service name. * Adapted to changes in Dovecot, making this release dependent on Dovecot >= v1.2.beta1. * Adapted to changes in the new Sieve implementation, making this release dependent on Dovecot Sieve >= v0.1.3 if used. The old cmusieve plugin is still supported. + Implemented making the SIEVE and NOTIFY capability fully dynamic, meaning that the sieve_extensions setting that was introduced for the new Sieve plugin properly affects the ManageSieve daemon as well. + Added support for the CHECKSCRIPT command. In terms of the supported commands, the ManageSieve daemon now complies with protocol VERSION 1.0 as listed in the CAPABILITY response. - Fixed maximum permissions for uploaded scripts; was 0777. This was shielded however by the default umask (not documented to be configurable), so the actual permissions would never have been 0777. - Fixed a segfault bug in the authentication time-out. Bug report and trace provided by Wolfgang Friebel. - Fixed handling of ~/ in use of mail-data for script location. - Fixed small problems in the login proxy support. v0.11.2: * Adapted to changes in Dovecot, making this release dependent on Dovecot >= v1.2.alpa4. v0.11.1: - Fixed security issue that gives virtual users the ability to read and modify each other's scripts if the directory structure of the sieve storage is known. * Updated NOOP command to match new protocol specification + Improved error handling and implemented the new response codes: ACTIVE, NONEXISTENT, ALREADYEXISTS and WARNINGS v0.11.0: * Upgraded to Dovecot v1.2 * Added support for new ManageSieve extensions RENAME and NOOP * Moved sieve settings to plugin {} section of config file. Now the settings `sieve` and `sieve_dir` in the plugin section are used for the Sieve plugin and the ManageSieve service, avoiding the posibility of accidental differences in configuration. Dovecot 1.1: v0.10.3 * Removed erroneous inline declarations that caused compiler warnings. GCC 4.3 turns out to fail entirely as reported by Joel Johnson. * Fixed auto-dectection of Sieve implementation during ./configure. It now produces a proper error when the directory is invalid. v0.10.2 * Fixed bug that caused SASL mechanisms that require more than a single client response to fail. Reported by Steffen Kaiser and occured when he tried using the (obsolete) LOGIN mechanism. * Updated installation and configuration documentation to match the information provided in the wiki v0.10.1 * Fixed bug introduced in v0.10.0: compiled scripts were also written to disk in the sieve/tmp directory and left there. This accumulates much .sievec junk in that directory over time. * Fixed bug in tmp file generation for sieve-storage: errors other than EEXIST would cause the daemon to sleep() loop indefinitely. + Improved log lines to be more recognizable as being generated from managesieve. + Added short proxy configuration explanation to the README file + Added 'Known Issues' section to the README file - Fixed assert bug in sieve-storage occurring when save is canceled. v0.10.0 * Upgraded to Dovecot 1.1: - The actual managesieve implementation is now a separate package. The dovecot tree still needs to be patched though to make dovecot recognize the new managesieve service. - Incorporated changes to imap/imap-login into the equivalent managesieve processes. - Removed cmusieve implementation from managesieve sources. It is now linked externally from the dovecot-sieve-1.1 package. - Restructured README.managesieve file into separate README, NEWS, TODO, DESIGN and INSTALL files. * Added support for new libsieve implementation (to be released). This package can be compiled with either the new or the old Sieve implementation (autodetected). If the new Sieve becomes stable, this package will be merged with it to make a single package for Dovecot Sieve support. Dovecot 1.0: v9 + Definitively fixed the segfault mentioned in V8. It proved to be very time-constrained and thus hard to reproduce. The error turned out to be related to the input handling of the login daemon during authentication. + Checked for changes in the imap daemon that weren't propagated to the managesieve implementation due to code duplication. + Fixed a bug in the autodetection of the sieve storage location. + Fixed bug in the sieve storage that failed to refresh the symlink if the storage was moved. + Improved error handing in the sieve-storage implementation in various places. + Fixed the situation in which the active script link is located in the sieve storage. + Added managesieve configuration to dovecot-example.conf and made the example in this file more concise. v8 + Fixed a few incompatibilities with 1.0.7 version. For instance, the "Logged in" message is now sent by the -login process and not by the managesieve daemon anymore. This caused a segfault every once in a while. + Probably fixed the settings problem reported by Steffen Kaiser regarding login_dir. 'dovecot -n' now reports correct results, but testing will show whether the whole problem is solved. + The managesieve daemon now accepts the sieve_storage and sieve configuration settings, so it is now possible to explicitly configure the location of the sieve storage and the active script respectively. The daemon still falls back to using the mail_location (MAIL) settings if nothing else is specified. + The cyrus timsieved does not use the + character in string literals and many clients have adopted to this behaviour. The latest managesieve (08) advises to accept a missing + from clients. The server should not send any + characters as well. This behavior is now implemented on the server. + Cleaned up sieve-storage.c: split up the sieve_storage_create function in various sub-functions for obtaining the various paths and directories. + Forced manual intervention if rescueing a non-symlink file at the active script path fails somehow. Previously, this presented the admin with a log message that it had just eaten the script, which is not very nice. + Restructured the README.managesieve file and added some more explanation with regard to the configuration of the daemon. v7 - Robin Breathe indicated that the regex capability was missing in the server's SIEVE listing. It turns out I forgot to make arrangements for setting ENABLE_REGEX in the cmu libsieve sources, so the regex extension was not compiled in. I copied the configure.in section regarding ENABLE_REGEX from dovecot-sieve-1.0.2 and that fixed the problem. v6 - Corked the client output stream while producing the capability greeting and on other some other occasions as well. Some naive client implementations expect to receive this as a single tcp frame and it is a good practice to do so anyway. Using this change the Thunderbird sieve extension (v0.1.1) seemed to work. However, scripts larger than a tcp frame still caused failures. All these issues are fixed in the latest version of the sieve add-on (currently v0.1.4). - Cleaned up the new proxy source. My editor made the indentation a complete mess in terms of TABs vs spaces. - Added TRYLATER response codes to BYE and NO messages where appropriate. - Recopied the libsieve library into this patch to incorporate any changes that were made (only sieve-cmu.c still needs to be compared to the old cmu-sieve.c). This also solves the __attribute__((unused)) GCC dependencies. These were fixed long ago by Timo.... the code duplication beast strikes again. - Removed spurious return value from void function in src/lib-sieve/sieve-implementation.c as reported by Robin Breathe. GCC fails to report these issues. The function involved is currently not used and serves only as an example on how dovecot could support multiple sieve backends... v5 - Applied patch by Uldis Pakuls to fix master_dump_settings bug - Added some compilation/installation info to this README - Moved README to source tree root as README.managesieve - Fixed minor error handling bug in sieve_storage.c with respect to a missing root directory. - Now sieve capabilities are reported as they are specified by the implementing library and not in forced upper case. The sieve RFC now explicitly states that sieve capability identifiers are case-sensitive. This broke compatibility with SquirrelMail/Avelsieve. - Disabled ANONYMOUS login entirely until proper support is implemented. V4 claimed to do so as well, but in fact it only stopped announcing it. - Implemented managesieve-proxy. It is not so much a clean copy of imap-proxy, since the managesieve greeting is much more complex and requires parsing. Configuration is identical to imap-proxy. This seems to be a little under- documented however (http://wiki.dovecot.org/PasswordDatabase/ExtraFields). v4 - Added managesieve_implementation_string setting to the managesieve configuration. This can be used to customize the default "IMPLEMENTATION" capability response. - Denied ANONYMOUS login until proper support is implemented - Fixed problem with authenticate command regarding continued responses. In V3 only initial response would work. Problem was caused by rc2 -> rc28 upgrade. One of the clear reasons why code duplication is a very bad idea. - Fixed readlink bug as indicated by Timo: return value of readlink can also be -1. - Fixed bug in the regular file rescue code, as introduced in the previous version. Used stat instead of lstat. This caused the symlink to be rescued subsequently in the next activation, thus still overwriting the initially rescued script. v3 - Updated source to compile with dovecot 1.0.rc27 - Daemon now uses the same location for .dovecot.sieve as dovecot-lda This is typically ~/.dovecot.sieve - If .dovecot.sieve is a regular file, it is now moved into the script storage as dovecot.orig.sieve, preventing deletion of (important) active scripts upon upgrade. - Changed error handling to yield a BYE message when the managesieve daemon exits unexpectedly (upon login) before any commands are entered. Horde-ingo would wait indefinitely for a response. v2 - Fixed the bug (missing CRLF) in the authenticate command - Modified the sieve storage library making the interface much less crude. - The scripts put on the server using the putscript command are now checked before they are accepted. - The reported SIEVE capability is now directly read from the sieve implementation (in this case cmu), listing much more than "FILEINTO VACATION". - Imported instance of libsieve source into this patch for implementation of script checking and capability listing. THIS NEEDS TO BE CHANGED! - Fixed some minor bugs in the putscript command dovecot-pigeonhole-2.4.2/Makefile.am0000644000175100001700000002002415100335616021031 0ustar00buildbotbuildbot00000000000000aclocaldir = $(datadir)/aclocal if BUILD_DOCS DOCS = doc endif SUBDIRS = \ . \ src \ $(DOCS) ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = \ version \ tests \ examples \ COPYING.LGPL \ ChangeLog \ update-version.sh \ build-aux/git-abi-version-gen \ build-aux/git-version-gen \ tests/test-address.svtest.in dist-hook: rm -rf `find $(distdir)/tests -type f -name '*.svbin'` pkginc_libdir=$(dovecot_pkgincludedir)/sieve dist_pkginc_lib_HEADERS = \ pigeonhole-version.h nodist_pkginc_lib_HEADERS = \ pigeonhole-config.h ChangeLog: git log --name-status \ --pretty="format:%ai %aN <%aE> (%h)%n%n%w(80,4,4)%s%n%n%b" > ChangeLog \ || rm -f ChangeLog dist_aclocal_DATA = dovecot-pigeonhole.m4 pigeonhole-version.h: noop $(SHELL) $(top_srcdir)/update-version.sh $(top_srcdir) $(top_builddir) noop: DISTCLEANFILES = \ $(top_builddir)/pigeonhole-version.h \ $(top_builddir)/run-test.sh # Testsuite tests (FIXME: ugly) TESTSUITE_BIN = $(top_builddir)/src/testsuite/testsuite $(TESTSUITE_OPTIONS) TEST_BIN = $(RUN_TEST) $(TESTSUITE_BIN) if BUILD_UNFINISHED test_unfinished = else test_unfinished = endif test_utf8_cases = \ tests/test-address.svtest test_cases = \ tests/testsuite.svtest \ tests/control-if.svtest \ tests/control-stop.svtest \ tests/test-allof.svtest \ tests/test-anyof.svtest \ tests/test-exists.svtest \ tests/test-header.svtest \ tests/test-address.svtest \ tests/test-size.svtest \ tests/compile/compile.svtest \ tests/compile/errors.svtest \ tests/compile/warnings.svtest \ tests/compile/recover.svtest \ tests/execute/errors.svtest \ tests/execute/errors-cpu-limit.svtest \ tests/execute/actions.svtest \ tests/execute/smtp.svtest \ tests/execute/mailstore.svtest \ tests/execute/address-normalize.svtest \ tests/execute/examples.svtest \ tests/lexer.svtest \ tests/comparators/i-octet.svtest \ tests/comparators/i-ascii-casemap.svtest \ tests/comparators/i-unicode-casemap.svtest \ tests/match-types/is.svtest \ tests/match-types/contains.svtest \ tests/match-types/matches.svtest \ tests/multiscript/basic.svtest \ tests/multiscript/conflicts.svtest \ tests/extensions/encoded-character.svtest \ tests/extensions/envelope.svtest \ tests/extensions/variables/basic.svtest \ tests/extensions/variables/match.svtest \ tests/extensions/variables/modifiers.svtest \ tests/extensions/variables/quoting.svtest \ tests/extensions/variables/string.svtest \ tests/extensions/variables/errors.svtest \ tests/extensions/variables/regex.svtest \ tests/extensions/include/errors.svtest \ tests/extensions/include/variables.svtest \ tests/extensions/include/once.svtest \ tests/extensions/include/twice.svtest \ tests/extensions/include/optional.svtest \ tests/extensions/include/rfc.svtest \ tests/extensions/include/execute.svtest \ tests/extensions/imap4flags/basic.svtest \ tests/extensions/imap4flags/errors.svtest \ tests/extensions/imap4flags/hasflag.svtest \ tests/extensions/imap4flags/execute.svtest \ tests/extensions/imap4flags/multiscript.svtest \ tests/extensions/imap4flags/flagstring.svtest \ tests/extensions/imap4flags/flagstore.svtest \ tests/extensions/body/basic.svtest \ tests/extensions/body/errors.svtest \ tests/extensions/body/raw.svtest \ tests/extensions/body/content.svtest \ tests/extensions/body/text.svtest \ tests/extensions/body/match-values.svtest \ tests/extensions/regex/basic.svtest \ tests/extensions/regex/match-values.svtest \ tests/extensions/regex/errors.svtest \ tests/extensions/reject/execute.svtest \ tests/extensions/reject/smtp.svtest \ tests/extensions/relational/basic.svtest \ tests/extensions/relational/rfc.svtest \ tests/extensions/relational/errors.svtest \ tests/extensions/relational/comparators.svtest \ tests/extensions/subaddress/basic.svtest \ tests/extensions/subaddress/rfc.svtest \ tests/extensions/subaddress/config.svtest \ tests/extensions/vacation/errors.svtest \ tests/extensions/vacation/execute.svtest \ tests/extensions/vacation/message.svtest \ tests/extensions/vacation/smtp.svtest \ tests/extensions/vacation/utf-8.svtest \ tests/extensions/vacation/reply.svtest \ tests/extensions/enotify/basic.svtest \ tests/extensions/enotify/encodeurl.svtest \ tests/extensions/enotify/valid_notify_method.svtest \ tests/extensions/enotify/notify_method_capability.svtest \ tests/extensions/enotify/errors.svtest \ tests/extensions/enotify/execute.svtest \ tests/extensions/enotify/mailto.svtest \ tests/extensions/environment/basic.svtest \ tests/extensions/environment/rfc.svtest \ tests/extensions/mailbox/errors.svtest \ tests/extensions/mailbox/execute.svtest \ tests/extensions/date/basic.svtest \ tests/extensions/date/date-parts.svtest \ tests/extensions/date/zones.svtest \ tests/extensions/index/basic.svtest \ tests/extensions/index/errors.svtest \ tests/extensions/spamvirustest/spamtest.svtest \ tests/extensions/spamvirustest/virustest.svtest \ tests/extensions/spamvirustest/spamtestplus.svtest \ tests/extensions/spamvirustest/errors.svtest \ tests/extensions/ihave/execute.svtest \ tests/extensions/ihave/errors.svtest \ tests/extensions/ihave/restrictions.svtest \ tests/extensions/editheader/addheader.svtest \ tests/extensions/editheader/deleteheader.svtest \ tests/extensions/editheader/alternating.svtest \ tests/extensions/editheader/utf8.svtest \ tests/extensions/editheader/protected.svtest \ tests/extensions/editheader/errors.svtest \ tests/extensions/editheader/execute.svtest \ tests/extensions/extlists/errors.svtest \ tests/extensions/extlists/basic.svtest \ tests/extensions/extlists/multiple.svtest \ tests/extensions/extlists/valid_ext_list.svtest \ tests/extensions/duplicate/errors.svtest \ tests/extensions/duplicate/execute.svtest \ tests/extensions/metadata/execute.svtest \ tests/extensions/metadata/errors.svtest \ tests/extensions/mime/errors.svtest \ tests/extensions/mime/header.svtest \ tests/extensions/mime/exists.svtest \ tests/extensions/mime/address.svtest \ tests/extensions/mime/execute.svtest \ tests/extensions/mime/content-header.svtest \ tests/extensions/mime/foreverypart.svtest \ tests/extensions/mime/extracttext.svtest \ tests/extensions/mime/calendar-example.svtest \ tests/extensions/special-use/errors.svtest \ tests/extensions/special-use/execute.svtest \ tests/extensions/vnd.dovecot/debug/execute.svtest \ tests/extensions/vnd.dovecot/environment/basic.svtest \ tests/extensions/vnd.dovecot/environment/variables.svtest \ tests/extensions/vnd.dovecot/report/errors.svtest \ tests/extensions/vnd.dovecot/report/execute.svtest \ $(test_unfinished) prepare_test_cases: $(AM_V_at)for case in $(test_utf8_cases); do \ if test "$(DOVECOT_HAVE_MAIL_UTF8)" = yes; then \ $(SED) -s -e 's/#UTF8#//' $${case}.in > $$case ; \ else \ $(SED) -s -e 's/#UTF8#.*//' $${case}.in > $$case ; \ fi; \ done $(test_cases): prepare_test_cases @$(TEST_BIN) $(top_srcdir)/$@ failure_test_cases = \ tests/failures/fuzz1.svtest \ tests/failures/fuzz2.svtest \ tests/failures/fuzz3.svtest \ tests/failures/mailbox-bad-utf8.svtest $(failure_test_cases): @$(TEST_BIN) -F $(top_srcdir)/$@ TEST_EXTPROGRAMS_BIN = NOCHILDREN=yes $(TEST_BIN) \ -P src/plugins/sieve-extprograms/.libs/sieve_extprograms extprograms_test_cases = \ tests/plugins/extprograms/errors.svtest \ tests/plugins/extprograms/pipe/command.svtest \ tests/plugins/extprograms/pipe/errors.svtest \ tests/plugins/extprograms/pipe/execute.svtest \ tests/plugins/extprograms/filter/command.svtest \ tests/plugins/extprograms/filter/errors.svtest \ tests/plugins/extprograms/filter/execute.svtest \ tests/plugins/extprograms/execute/command.svtest \ tests/plugins/extprograms/execute/errors.svtest \ tests/plugins/extprograms/execute/execute.svtest $(extprograms_test_cases): @$(TEST_EXTPROGRAMS_BIN) $(top_srcdir)/$@ .PHONY: test test-plugins $(test_cases) $(failure_test_cases) $(extprograms_test_cases) prepare_test_case test: all-am $(test_cases) $(failure_test_cases) test-plugins: all-am $(extprograms_test_cases) check: check-am test version: $(AM_V_GEN)env VERSION=$(PACKAGE_VERSION) $(top_srcdir)/build-aux/git-version-gen > $@ dovecot-pigeonhole-2.4.2/src/0000755000175100001700000000000015100335671017567 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/0000755000175100001700000000000015100335670021445 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-common.h0000644000175100001700000001213715100335616024223 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_COMMON_H #define SIEVE_COMMON_H #include "lib.h" #include "sieve.h" #ifndef SETTINGS_PLUGIN #include "sieve-settings.h" #endif #include /* * Types */ typedef size_t sieve_size_t; typedef uint32_t sieve_offset_t; typedef uint64_t sieve_number_t; #define SIEVE_MAX_NUMBER ((sieve_number_t)-1) #define SIEVE_PRI_NUMBER PRIu64 /* * Forward declarations */ /* sieve-error.h */ struct sieve_error_handler; /* sieve-ast.h */ enum sieve_ast_argument_type; struct sieve_ast; struct sieve_ast_node; struct sieve_ast_argument; /* sieve-commands.h */ struct sieve_argument; struct sieve_argument_def; struct sieve_command; struct sieve_command_def; struct sieve_command_context; struct sieve_command_registration; /* sieve-stringlist.h */ struct sieve_stringlist; /* sieve-code.h */ struct sieve_operation_extension; /* sieve-lexer.h */ struct sieve_lexer; /* sieve-parser.h */ struct sieve_parser; /* sieve-validator.h */ struct sieve_validator; /* sieve-generator.h */ struct sieve_jumplist; struct sieve_generator; struct sieve_codegen_env; /* sieve-runtime.h */ struct sieve_runtime_env; /* sieve-interpreter.h */ struct sieve_interpreter; /* sieve-dump.h */ struct sieve_dumptime_env; /* sieve-binary-dumper.h */ struct sieve_binary_dumper; /* sieve-code-dumper.h */ struct sieve_code_dumper; /* sieve-extension.h */ struct sieve_extension; struct sieve_extension_def; struct sieve_extension_objects; /* sieve-code.h */ struct sieve_operand; struct sieve_operand_def; struct sieve_operand_class; struct sieve_operation; struct sieve_coded_stringlist; /* sieve-binary.h */ struct sieve_binary; struct sieve_binary_block; struct sieve_binary_debug_writer; struct sieve_binary_debug_reader; /* sieve-execute.h */ struct sieve_execute; /* sieve-objects.h */ struct sieve_object_def; struct sieve_object; /* sieve-comparator.h */ struct sieve_comparator; /* sieve-match-types.h */ struct sieve_match_type; /* sieve-match.h */ struct sieve_match_context; /* sieve-address.h */ struct sieve_address_list; /* sieve-address-parts.h */ struct sieve_address_part_def; struct sieve_address_part; /* sieve-result.h */ struct sieve_result; struct sieve_side_effects_list; struct sieve_result_print_env; /* sieve-actions.h */ struct sieve_action_exec_env; struct sieve_action; struct sieve_action_def; struct sieve_side_effect; struct sieve_side_effect_def; /* sieve-script.h */ struct sieve_script; struct sieve_script_sequence; /* sieve-storage.h */ struct sieve_storage_class_registry; struct sieve_storage; /* sieve-message.h */ struct sieve_message_context; struct sieve_message_override; struct sieve_message_override_def; /* sieve-plugins.h */ struct sieve_plugin; /* sieve.c */ struct sieve_ast * sieve_parse(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r); bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, enum sieve_error *error_code_r); /* * Parent category */ extern struct event_category event_category_sieve; /* * Sieve engine instance */ struct sieve_instance { /* Main engine pool */ pool_t pool; /* System environment */ const char *hostname; const char *domainname; const char *base_dir; const char *temp_dir; /* User environment */ const char *username; const char *home_dir; /* Flags */ enum sieve_flag flags; /* Callbacks */ const struct sieve_callbacks *callbacks; void *context; /* Logging, events, and debug */ struct event *event; bool debug; /* Extension registry */ struct sieve_extension_registry *ext_reg; /* Storage class registry */ struct sieve_storage_class_registry *storage_reg; /* Plugin modules */ struct sieve_plugin *plugins; enum sieve_env_location env_location; enum sieve_delivery_phase delivery_phase; /* Settings */ const struct sieve_settings *set; const struct smtp_address *user_email_implicit; }; /* * Errors */ void sieve_error_args_init(enum sieve_error **error_code_r, const char ***error_r); void sieve_error_create_internal(enum sieve_error *error_code_r, const char **error_r); void sieve_error_create_script_not_found(const char *script_name, enum sieve_error *error_code_r, const char **error_r); /* * Script trace log */ void sieve_trace_log_write_line(struct sieve_trace_log *trace_log, const string_t *line); /* * User e-mail address */ const struct smtp_address *sieve_get_user_email (struct sieve_instance *svinst); /* * Postmaster address */ const struct message_address * sieve_get_postmaster(const struct sieve_script_env *senv); const struct smtp_address * sieve_get_postmaster_smtp(const struct sieve_script_env *senv); const char *sieve_get_postmaster_address(const struct sieve_script_env *senv); /* * Home directory */ static inline const char * sieve_environment_get_homedir(struct sieve_instance *svinst) { const struct sieve_callbacks *callbacks = svinst->callbacks; if (svinst->home_dir != NULL) return svinst->home_dir; if (callbacks == NULL || callbacks->get_homedir == NULL) return NULL; return callbacks->get_homedir(svinst, svinst->context); } #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-commands.h0000644000175100001700000002061615100335616024535 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_COMMANDS_H #define SIEVE_COMMANDS_H #include "lib.h" #include "sieve-common.h" #include "sieve-ast.h" /* * Argument definition */ enum sieve_argument_flag { /* More than one of this (type of) tagged argument is allowed */ SIEVE_ARGUMENT_FLAG_MULTIPLE = (1 << 0) }; struct sieve_argument_def { const char *identifier; enum sieve_argument_flag flags; bool (*is_instance_of)(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext, const char *identifier, void **data); bool (*validate)(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); bool (*validate_context)(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_command *cmd); bool (*validate_persistent)(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext); bool (*generate)(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); }; /* * Argument instance */ struct sieve_argument { const struct sieve_argument_def *def; const struct sieve_extension *ext; int id_code; /* Context data */ void *data; }; #define sieve_argument_is(ast_arg, definition) \ ((ast_arg)->argument->def == &(definition)) #define sieve_argument_ext(ast_arg) \ ((ast_arg)->argument->ext) #define sieve_argument_identifier(ast_arg) \ ((ast_arg)->argument->def->identifier) /* Utility macros */ #define sieve_argument_is_string_literal(arg) \ ((arg)->argument->def == &string_argument) /* Error handling */ #define sieve_argument_validate_error(validator, arg_node, ...) \ sieve_validator_error( \ validator, \ ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ __VA_ARGS__) #define sieve_argument_validate_warning(validator, arg_node, ...) \ sieve_validator_warning( \ validator, \ ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ __VA_ARGS__) #define sieve_argument_generate_error(gentr, arg_node, ...) \ sieve_generator_error( \ gentr, \ ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ __VA_ARGS__) #define sieve_argument_generate_warning(gentr, arg_node, ...) \ sieve_generator_warning( \ gentr, \ ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ __VA_ARGS__) /* Argument API */ struct sieve_argument * sieve_argument_create(struct sieve_ast *ast, const struct sieve_argument_def *def, const struct sieve_extension *ext, int id_code); /* Literal arguments */ extern const struct sieve_argument_def number_argument; extern const struct sieve_argument_def string_argument; extern const struct sieve_argument_def string_list_argument; /* Catenated string argument */ bool sieve_arg_catenated_string_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); struct sieve_arg_catenated_string; struct sieve_arg_catenated_string * sieve_arg_catenated_string_create(struct sieve_ast_argument *orig_arg); void sieve_arg_catenated_string_add_element( struct sieve_arg_catenated_string *strdata, struct sieve_ast_argument *element); /* * Command definition */ enum sieve_command_type { SCT_NONE, SCT_COMMAND, SCT_TEST, SCT_HYBRID }; struct sieve_command_def { const char *identifier; enum sieve_command_type type; /* High-level command syntax */ int positional_args; int subtests; bool block_allowed; bool block_required; bool (*registered)(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); bool (*pre_validate)(struct sieve_validator *valdtr, struct sieve_command *cmd); bool (*validate)(struct sieve_validator *valdtr, struct sieve_command *cmd); bool (*validate_const)(struct sieve_validator *valdtr, struct sieve_command *cmd, int *const_current, int const_next); bool (*generate)(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); bool (*control_generate)(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_jumplist *jumps, bool jump_true); }; /* * Command instance */ struct sieve_command { const struct sieve_command_def *def; const struct sieve_extension *ext; /* The registration of this command in the validator (sieve-validator.h) */ struct sieve_command_registration *reg; /* The ast node of this command */ struct sieve_ast_node *ast_node; /* First positional argument, found during argument validation */ struct sieve_ast_argument *first_positional; /* The child ast node that unconditionally exits this command's block */ struct sieve_command *block_exit_command; /* Context data*/ void *data; }; #define sieve_command_is(cmd, definition) \ ((cmd)->def == &(definition)) #define sieve_command_identifier(cmd) \ ((cmd)->def->identifier) #define sieve_commands_equal(cmd1, cmd2) \ ((cmd1) != NULL && (cmd2) != NULL && (cmd1)->def == (cmd2)->def) /* Context API */ struct sieve_command * sieve_command_create(struct sieve_ast_node *cmd_node, const struct sieve_extension *ext, const struct sieve_command_def *cmd_def, struct sieve_command_registration *cmd_reg); const char * sieve_command_def_type_name(const struct sieve_command_def *cmd_def); const char *sieve_command_type_name(const struct sieve_command *cmd); struct sieve_command *sieve_command_prev(struct sieve_command *cmd); struct sieve_command *sieve_command_parent(struct sieve_command *cmd); struct sieve_ast_argument * sieve_command_add_dynamic_tag(struct sieve_command *cmd, const struct sieve_extension *ext, const struct sieve_argument_def *tag, int id_code); struct sieve_ast_argument * sieve_command_find_argument(struct sieve_command *cmd, const struct sieve_argument_def *argument); void sieve_command_exit_block_unconditionally(struct sieve_command *cmd); bool sieve_command_block_exits_unconditionally(struct sieve_command *cmd); /* Error handling */ #define sieve_command_validate_error(validator, context, ...) \ sieve_validator_error( \ validator, \ ((context) == NULL ? 0 : (context)->ast_node->source_line), \ __VA_ARGS__) #define sieve_command_validate_warning(validator, context, ...) \ sieve_validator_warning( \ validator, \ ((context) == NULL ? 0 : (context)->ast_node->source_line), \ __VA_ARGS__) #define sieve_command_generate_error(gentr, context, ...) \ sieve_generator_error( \ gentr, \ ((context) == NULL ? 0 : (context)->ast_node->source_line), \ __VA_ARGS__) #define sieve_command_generate_warning(gentr, context, ...) \ sieve_generator_warning( \ gentr, \ ((context) == NULL ? 0 : (context)->ast_node->source_line), \ __VA_ARGS__) /* Utility macros */ #define sieve_command_pool(context) \ sieve_ast_node_pool((context)->ast_node) #define sieve_command_source_line(context) \ (context)->ast_node->source_line #define sieve_command_first_argument(context) \ sieve_ast_argument_first((context)->ast_node) #define sieve_command_is_toplevel(context) \ (sieve_ast_node_type( \ sieve_ast_node_parent((context)->ast_node)) == SAT_ROOT) #define sieve_command_is_first(context) \ (sieve_ast_node_prev((context)->ast_node) == NULL) /* * Core commands */ extern const struct sieve_command_def cmd_require; extern const struct sieve_command_def cmd_stop; extern const struct sieve_command_def cmd_if; extern const struct sieve_command_def cmd_elsif; extern const struct sieve_command_def cmd_else; extern const struct sieve_command_def cmd_redirect; extern const struct sieve_command_def cmd_keep; extern const struct sieve_command_def cmd_discard; extern const struct sieve_command_def *sieve_core_commands[]; extern const unsigned int sieve_core_commands_count; /* * Core tests */ extern const struct sieve_command_def tst_true; extern const struct sieve_command_def tst_false; extern const struct sieve_command_def tst_not; extern const struct sieve_command_def tst_anyof; extern const struct sieve_command_def tst_allof; extern const struct sieve_command_def tst_address; extern const struct sieve_command_def tst_header; extern const struct sieve_command_def tst_exists; extern const struct sieve_command_def tst_size; extern const struct sieve_command_def *sieve_core_tests[]; extern const unsigned int sieve_core_tests_count; /* * Command utility functions */ bool sieve_command_verify_headers_argument(struct sieve_validator *valdtr, struct sieve_ast_argument *headers); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-address-source.h0000644000175100001700000000167215100335616025660 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_ADDRESS_SOURCE_H #define SIEVE_ADDRESS_SOURCE_H struct sieve_instance; struct sieve_script_env; struct sieve_message_context; enum sieve_execute_flags; enum sieve_address_source_type { SIEVE_ADDRESS_SOURCE_DEFAULT = 0, SIEVE_ADDRESS_SOURCE_SENDER, SIEVE_ADDRESS_SOURCE_RECIPIENT, SIEVE_ADDRESS_SOURCE_ORIG_RECIPIENT, SIEVE_ADDRESS_SOURCE_USER_EMAIL, SIEVE_ADDRESS_SOURCE_POSTMASTER, SIEVE_ADDRESS_SOURCE_EXPLICIT }; struct sieve_address_source { enum sieve_address_source_type type; const struct smtp_address *address; }; bool sieve_address_source_parse(pool_t pool, const char *value, struct sieve_address_source *asrc); int sieve_address_source_get_address(struct sieve_address_source *asrc, struct sieve_instance *svinst, const struct sieve_script_env *senv, struct sieve_message_context *msgctx, enum sieve_execute_flags flags, const struct smtp_address **addr_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/cmp-i-ascii-casemap.c0000644000175100001700000000356615100335616025325 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Comparator 'i;ascii-casemap': * */ #include "lib.h" #include "sieve-common.h" #include "sieve-comparators.h" #include #include #include /* * Forward declarations */ static int cmp_i_ascii_casemap_compare (const struct sieve_comparator *cmp, const char *val1, size_t val1_size, const char *val2, size_t val2_size); static bool cmp_i_ascii_casemap_char_match (const struct sieve_comparator *cmp, const char **val1, const char *val1_end, const char **val2, const char *val2_end); /* * Comparator object */ const struct sieve_comparator_def i_ascii_casemap_comparator = { SIEVE_OBJECT("i;ascii-casemap", &comparator_operand, SIEVE_COMPARATOR_I_ASCII_CASEMAP), .flags = SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY | SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH, .compare = cmp_i_ascii_casemap_compare, .char_match = cmp_i_ascii_casemap_char_match, .char_skip = sieve_comparator_octet_skip }; /* * Comparator implementation */ static int cmp_i_ascii_casemap_compare( const struct sieve_comparator *cmp ATTR_UNUSED, const char *val1, size_t val1_size, const char *val2, size_t val2_size) { size_t size = I_MIN(val1_size, val2_size); int ret = strncasecmp(val1, val2, size); return ret != 0 ? ret : (int)val1_size - (int)val2_size; } static bool cmp_i_ascii_casemap_char_match (const struct sieve_comparator *cmp ATTR_UNUSED, const char **val, const char *val_end, const char **key, const char *key_end) { const char *val_begin = *val; const char *key_begin = *key; while ( i_tolower(**val) == i_tolower(**key) && *val < val_end && *key < key_end ) { (*val)++; (*key)++; } if ( *key < key_end ) { /* Reset */ *val = val_begin; *key = key_begin; return FALSE; } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-execute.c0000644000175100001700000001031215100335616024361 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-execute.h" struct sieve_execute_state { void *dup_trans; }; struct event_category event_category_sieve_execute = { .parent = &event_category_sieve, .name = "sieve-execute", }; static struct sieve_execute_state * sieve_execute_state_create(struct sieve_execute_env *eenv) { return p_new(eenv->pool, struct sieve_execute_state, 1); } static void sieve_execute_state_free(struct sieve_execute_state **_estate, struct sieve_execute_env *eenv) { struct sieve_execute_state *estate = *_estate; const struct sieve_script_env *senv = eenv->scriptenv; *_estate = NULL; if (senv->duplicate_transaction_rollback != NULL) senv->duplicate_transaction_rollback(&estate->dup_trans); } void sieve_execute_init(struct sieve_execute_env *eenv, struct sieve_instance *svinst, pool_t pool, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, enum sieve_execute_flags flags) { i_assert(svinst->username != NULL); i_zero(eenv); eenv->svinst = svinst; eenv->pool = pool; eenv->flags = flags; eenv->msgdata = msgdata; eenv->scriptenv = senv; pool_ref(pool); eenv->event = event_create(svinst->event); event_add_category(eenv->event, &event_category_sieve_execute); event_add_str(eenv->event, "message_id", msgdata->id); if ((flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) { /* Make sure important envelope fields are available */ event_add_str(eenv->event, "mail_from", smtp_address_encode(msgdata->envelope.mail_from)); event_add_str(eenv->event, "rcpt_to", smtp_address_encode(msgdata->envelope.rcpt_to)); } eenv->state = sieve_execute_state_create(eenv); eenv->exec_status = senv->exec_status; if (eenv->exec_status == NULL) eenv->exec_status = p_new(pool, struct sieve_exec_status, 1); else i_zero(eenv->exec_status); } void sieve_execute_finish(struct sieve_execute_env *eenv, int status) { const struct sieve_script_env *senv = eenv->scriptenv; if (status == SIEVE_EXEC_OK) { if (senv->duplicate_transaction_commit != NULL) { senv->duplicate_transaction_commit( &eenv->state->dup_trans); } } else { if (senv->duplicate_transaction_rollback != NULL) { senv->duplicate_transaction_rollback( &eenv->state->dup_trans); } } } void sieve_execute_deinit(struct sieve_execute_env *eenv) { sieve_execute_state_free(&eenv->state, eenv); event_unref(&eenv->event); pool_unref(&eenv->pool); } /* * Checking for duplicates */ static void * sieve_execute_get_dup_transaction(const struct sieve_execute_env *eenv) { const struct sieve_script_env *senv = eenv->scriptenv; if (senv->duplicate_transaction_begin == NULL) return NULL; if (eenv->state->dup_trans == NULL) { eenv->state->dup_trans = senv->duplicate_transaction_begin(senv); } return eenv->state->dup_trans; } bool sieve_execute_duplicate_check_available( const struct sieve_execute_env *eenv) { const struct sieve_script_env *senv = eenv->scriptenv; return (senv->duplicate_transaction_begin != NULL); } int sieve_execute_duplicate_check(const struct sieve_execute_env *eenv, const void *id, size_t id_size, bool *duplicate_r) { const struct sieve_script_env *senv = eenv->scriptenv; void *dup_trans = sieve_execute_get_dup_transaction(eenv); int ret; *duplicate_r = FALSE; if (senv->duplicate_check == NULL) return SIEVE_EXEC_OK; e_debug(eenv->svinst->event, "Check duplicate ID"); ret = senv->duplicate_check(dup_trans, senv, id, id_size); switch (ret) { case SIEVE_DUPLICATE_CHECK_RESULT_EXISTS: *duplicate_r = TRUE; break; case SIEVE_DUPLICATE_CHECK_RESULT_NOT_FOUND: break; case SIEVE_DUPLICATE_CHECK_RESULT_FAILURE: return SIEVE_EXEC_FAILURE; case SIEVE_DUPLICATE_CHECK_RESULT_TEMP_FAILURE: return SIEVE_EXEC_TEMP_FAILURE; } return SIEVE_EXEC_OK; } void sieve_execute_duplicate_mark(const struct sieve_execute_env *eenv, const void *id, size_t id_size, time_t time) { const struct sieve_script_env *senv = eenv->scriptenv; void *dup_trans = sieve_execute_get_dup_transaction(eenv); if (senv->duplicate_mark == NULL) return; e_debug(eenv->svinst->event, "Mark ID as duplicate"); senv->duplicate_mark(dup_trans, senv, id, id_size, time); } dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-exists.c0000644000175100001700000001046615100335616023747 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-code-dumper.h" /* * Exists test * * Syntax: * exists */ static bool tst_exists_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_exists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst); const struct sieve_command_def tst_exists = { .identifier = "exists", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_exists_validate, .generate = tst_exists_generate }; /* * Exists operation */ static bool tst_exists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_exists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_exists_operation = { .mnemonic = "EXISTS", .code = SIEVE_OPERATION_EXISTS, .dump = tst_exists_operation_dump, .execute = tst_exists_operation_execute }; /* * Validation */ static bool tst_exists_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if (!sieve_validate_positional_argument(valdtr, tst, arg, "header names", 1, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; return sieve_command_verify_headers_argument(valdtr, arg); } /* * Code generation */ static bool tst_exists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { sieve_operation_emit(cgenv->sblock, NULL, &tst_exists_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_exists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "EXISTS"); sieve_code_descend(denv); /* Optional operands */ if (sieve_message_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return sieve_opr_stringlist_dump(denv, address, "header names"); } /* * Code execution */ static int tst_exists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_stringlist *hdr_list; ARRAY_TYPE(sieve_message_override) svmos; string_t *hdr_item; bool matched; int ret; /* * Read operands */ /* Optional operands */ i_zero(&svmos); if (sieve_message_opr_optional_read(renv, address, NULL, &ret, NULL, NULL, NULL, &svmos) < 0) return ret; /* Read header-list */ if ((ret = sieve_opr_stringlist_read(renv, address, "header-list", &hdr_list)) <= 0) return ret; /* * Perfrom test */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "exists test"); sieve_runtime_trace_descend(renv); /* Iterate through all requested headers to match (must find all specified) */ hdr_item = NULL; matched = TRUE; while (matched && (ret = sieve_stringlist_next_item(hdr_list, &hdr_item)) > 0) { struct sieve_stringlist *field_names, *value_list; string_t *dummy; /* Get header */ field_names = sieve_single_stringlist_create(renv, hdr_item, FALSE); ret = sieve_message_get_header_fields(renv, field_names, &svmos, FALSE, &value_list); if (ret <= 0) return ret; ret = sieve_stringlist_next_item(value_list, &dummy); if (ret < 0) return value_list->exec_status; if (ret == 0) matched = FALSE; sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "header '%s' %s", str_sanitize(str_c(hdr_item), 80), (matched ? "exists" : "is missing")); } if (matched) { sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "all headers exist"); } else { sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "headers are missing"); } /* Set test result for subsequent conditional jump */ if (ret >= 0) { sieve_interpreter_set_test_result(renv->interp, matched); return SIEVE_EXEC_OK; } sieve_runtime_trace_error(renv, "invalid header-list item"); return SIEVE_EXEC_BIN_CORRUPT; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve.h0000644000175100001700000002261315100335616022735 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_H #define SIEVE_H struct sieve_script; struct sieve_binary; #include "sieve-config.h" #include "sieve-types.h" #include "sieve-error.h" /* * Main Sieve library interface */ /* Initialize the sieve engine. Must be called before any sieve functionality is used. */ int sieve_init(const struct sieve_environment *env, const struct sieve_callbacks *callbacks, void *context, bool debug, struct sieve_instance **svinst_r); /* Free all memory allocated by the sieve engine. */ void sieve_deinit(struct sieve_instance **_svinst); /* Reload main engine settings */ int sieve_settings_reload(struct sieve_instance *svinst); /* Get capability string for a particular extension. */ const char * sieve_get_capabilities(struct sieve_instance *svinst, const char *name); /* Get top-level event for this Sieve instance. */ struct event *sieve_get_event(struct sieve_instance *svinst) ATTR_PURE; /* Set the supported extensions. The provided string is parsed into a list of extensions that are to be enabled/disabled. */ void sieve_set_extensions(struct sieve_instance *svinst, const char *extensions); /* * Script compilation */ /* Compile a Sieve script from a Sieve script object. Returns Sieve binary upon success and NULL upon failure. */ int sieve_compile_script(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); /* Compile a Sieve script from a Sieve script location string. Returns Sieve binary upon success and NULL upon failure. The provided script_name is used for the internally created Sieve script object. */ int sieve_compile(struct sieve_instance *svinst, const char *script_cause, const char *storage_name, const char *script_name, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); /* * Reading/writing Sieve binaries */ /* Loads the sieve binary indicated by the provided path. */ int sieve_load(struct sieve_instance *svinst, const char *bin_path, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); /* First tries to open the binary version of the specified script and if it does not exist or if it contains errors, the script is (re-)compiled. Note that errors in the bytecode are caught only at runtime. */ int sieve_open_script(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); /* First tries to open the binary version of the specified script and if it does not exist or if it contains errors, the script is (re-)compiled. Note that errors in the bytecode are caught only at runtime. */ int sieve_open(struct sieve_instance *svinst, const char *script_cause, const char *script_storage, const char *script_name, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); /* Record resource usage in the binary cumulatively. The binary is disabled when resource limits are exceeded within a configured timeout. Returns FALSE when resource limits are exceeded. */ bool ATTR_NOWARN_UNUSED_RESULT sieve_record_resource_usage(struct sieve_binary *sbin, const struct sieve_resource_usage *rusage) ATTR_NULL(1); /* Check whether Sieve binary is (still) executable. Returns 1 if all is OK, 0 when an error occurred, and -1 when the error is internal. Sets the Sieve error code in error_code_r and a user error message in client_error_r when the error is not internal. */ int sieve_check_executable(struct sieve_binary *sbin, enum sieve_error *error_code_r, const char **client_error_r); /* Saves the binary as the file indicated by the path parameter. This function will not write the binary to disk when the provided binary object was loaded earlier from the indicated bin_path, unless update is TRUE. */ int sieve_save_as(struct sieve_binary *sbin, const char *bin_path, bool update, mode_t save_mode, enum sieve_error *error_code_r); /* Saves the binary to the default location. This function will not overwrite the binary on disk when the provided binary object was loaded earlier from the default location, unless update is TRUE. */ int sieve_save(struct sieve_binary *sbin, bool update, enum sieve_error *error_code_r); /* Closes a compiled/opened sieve binary. */ void sieve_close(struct sieve_binary **_sbin); /* Obtains the path the binary was compiled or loaded from. */ const char *sieve_get_source(struct sieve_binary *sbin); /* Indicates whether the binary was loaded from a pre-compiled file. */ bool sieve_is_loaded(struct sieve_binary *sbin); /* * Debugging */ /* Dumps the byte code in human-readable form to the specified ostream. */ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream, bool verbose); /* Dumps the byte code in hexdump form to the specified ostream. */ void sieve_hexdump(struct sieve_binary *sbin, struct ostream *stream); /* Executes the bytecode, but only prints the result to the given stream. */ int sieve_test(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct sieve_error_handler *ehandler, struct ostream *stream, enum sieve_execute_flags flags); /* * Script execution */ /* Initializes the scirpt environment from the given mail_user. */ int sieve_script_env_init(struct sieve_script_env *senv, struct mail_user *user, const char **error_r); /* Executes the binary, including the result. */ int sieve_execute(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct sieve_error_handler *exec_ehandler, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags); /* * Multiscript support */ struct sieve_multiscript; struct sieve_multiscript * sieve_multiscript_start_execute(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv); struct sieve_multiscript * sieve_multiscript_start_test(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct ostream *stream); bool sieve_multiscript_run(struct sieve_multiscript *mscript, struct sieve_binary *sbin, struct sieve_error_handler *exec_ehandler, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags); bool sieve_multiscript_will_discard(struct sieve_multiscript *mscript); void sieve_multiscript_run_discard(struct sieve_multiscript *mscript, struct sieve_binary *sbin, struct sieve_error_handler *exec_ehandler, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags); int sieve_multiscript_status(struct sieve_multiscript *mscript); int sieve_multiscript_finish(struct sieve_multiscript **_mscript, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags, int status); /* * Configured limits */ unsigned int sieve_max_redirects(struct sieve_instance *svinst); unsigned int sieve_max_actions(struct sieve_instance *svinst); size_t sieve_max_script_size(struct sieve_instance *svinst); /* * User log */ const char *sieve_user_get_log_path(struct sieve_instance *svinst, struct sieve_script *user_script) ATTR_NULL(2); /* * Script trace log */ struct sieve_trace_log; int sieve_trace_log_create(struct sieve_instance *svinst, const char *path, struct sieve_trace_log **trace_log_r) ATTR_NULL(2); int sieve_trace_log_create_dir(struct sieve_instance *svinst, const char *dir, struct sieve_trace_log **trace_log_r) ATTR_NULL(3); int sieve_trace_log_open(struct sieve_instance *svinst, struct sieve_trace_log **trace_log_r) ATTR_NULL(2); void sieve_trace_log_printf(struct sieve_trace_log *trace_log, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_trace_log_free(struct sieve_trace_log **_trace_log); int sieve_trace_config_get(struct sieve_instance *svinst, struct sieve_trace_config *tr_config); /* * Execution exit codes */ const char *sieve_execution_exitcode_to_str(int code); /* * Resource usage */ /* Initialize the resource usage struct, clearing all usage statistics. */ void sieve_resource_usage_init(struct sieve_resource_usage *rusage_r); /* Calculate the sum of the provided resource usage statistics, writing the result to the first. */ void sieve_resource_usage_add(struct sieve_resource_usage *dst, const struct sieve_resource_usage *src); /* Returns TRUE if the resource usage is sufficiently high to warrant recording for checking cumulative resource limits (across several different script executions). */ bool sieve_resource_usage_is_high(struct sieve_instance *svinst, const struct sieve_resource_usage *rusage); /* Returns TRUE when the provided resource usage statistics exceed a configured policy limit. */ bool sieve_resource_usage_is_excessive( struct sieve_instance *svinst, const struct sieve_resource_usage *rusage); /* Returns a string containing a description of the resource usage (to be used log messages). */ const char * sieve_resource_usage_get_summary(const struct sieve_resource_usage *rusage); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary-debug.c0000644000175100001700000001477115100335616025304 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-code.h" #include "sieve-binary-private.h" /* Quick 'n dirty debug */ #if 0 #define debug_printf(...) printf ("lineinfo: " __VA_ARGS__) #else #define debug_printf(...) #endif /* * Opcodes */ enum { LINPROG_OP_COPY, LINPROG_OP_ADVANCE_PC, LINPROG_OP_ADVANCE_LINE, LINPROG_OP_SET_COLUMN, LINPROG_OP_SPECIAL_BASE }; #define LINPROG_LINE_BASE 0 #define LINPROG_LINE_RANGE 4 /* * Lineinfo writer */ struct sieve_binary_debug_writer { struct sieve_binary_block *sblock; sieve_size_t address; unsigned int line; unsigned int column; }; struct sieve_binary_debug_writer * sieve_binary_debug_writer_init(struct sieve_binary_block *sblock) { struct sieve_binary_debug_writer *dwriter; dwriter = i_new(struct sieve_binary_debug_writer, 1); dwriter->sblock = sblock; return dwriter; } void sieve_binary_debug_writer_deinit( struct sieve_binary_debug_writer **dwriter) { i_free(*dwriter); *dwriter = NULL; } void sieve_binary_debug_emit(struct sieve_binary_debug_writer *dwriter, sieve_size_t code_address, unsigned int code_line, unsigned int code_column) { i_assert(code_address >= dwriter->address); struct sieve_binary_block *sblock = dwriter->sblock; sieve_size_t address_inc = code_address - dwriter->address; int line_inc = (code_line > dwriter->line ? (int)(code_line - dwriter->line) : -(int)(dwriter->line - code_line)); unsigned int sp_opcode = 0; /* Check for applicability of special opcode */ if (line_inc > 0 && (LINPROG_LINE_BASE + LINPROG_LINE_RANGE - 1) >= line_inc) { sp_opcode = LINPROG_OP_SPECIAL_BASE + (line_inc - LINPROG_LINE_BASE) + (LINPROG_LINE_RANGE * address_inc); if (sp_opcode > 255) sp_opcode = 0; } /* Update line and address */ if (sp_opcode == 0) { if (line_inc != 0) { (void)sieve_binary_emit_byte(sblock, LINPROG_OP_ADVANCE_LINE); (void)sieve_binary_emit_unsigned( sblock, (unsigned int)line_inc); } if (address_inc > 0) { (void)sieve_binary_emit_byte(sblock, LINPROG_OP_ADVANCE_PC); (void)sieve_binary_emit_unsigned(sblock, address_inc); } } else { (void)sieve_binary_emit_byte(sblock, sp_opcode); } /* Set column */ if (dwriter->column != code_column) { (void)sieve_binary_emit_byte(sblock, LINPROG_OP_SET_COLUMN); (void)sieve_binary_emit_unsigned(sblock, code_column); } /* Generate matrix row */ (void)sieve_binary_emit_byte(sblock, LINPROG_OP_COPY); dwriter->address = code_address; dwriter->line = code_line; dwriter->column = code_column; } /* * Debug reader */ struct sieve_binary_debug_reader { struct sieve_binary_block *sblock; sieve_size_t address, last_address; unsigned int line, last_line; unsigned int column; sieve_size_t state; }; struct sieve_binary_debug_reader * sieve_binary_debug_reader_init(struct sieve_binary_block *sblock) { struct sieve_binary_debug_reader *dreader; dreader = i_new(struct sieve_binary_debug_reader, 1); dreader->sblock = sblock; return dreader; } void sieve_binary_debug_reader_deinit( struct sieve_binary_debug_reader **dreader) { i_free(*dreader); *dreader = NULL; } void sieve_binary_debug_reader_reset(struct sieve_binary_debug_reader *dreader) { dreader->address = 0; dreader->line = 0; dreader->column = 0; dreader->state = 0; } unsigned int sieve_binary_debug_read_line(struct sieve_binary_debug_reader *dreader, sieve_size_t code_address) { size_t linprog_size; sieve_size_t address; unsigned int line; if (code_address < dreader->last_address) sieve_binary_debug_reader_reset(dreader); if (code_address >= dreader->last_address && code_address < dreader->address) { debug_printf("%08llx: NOOP [%08llx]\n", (unsigned long long)dreader->state, (unsigned long long)code_address); return dreader->last_line; } address = dreader->address; line = dreader->line; debug_printf("%08llx: READ [%08llx]\n", (unsigned long long)dreader->state, (unsigned long long)code_address); linprog_size = sieve_binary_block_get_size(dreader->sblock); while (dreader->state < linprog_size) { unsigned int opcode; unsigned int value; int line_inc; if (sieve_binary_read_byte(dreader->sblock, &dreader->state, &opcode)) { switch (opcode) { case LINPROG_OP_COPY: debug_printf("%08llx: COPY ==> %08llx: %ld\n", (unsigned long long)dreader->state, (unsigned long long)address, line); dreader->last_address = dreader->address; dreader->last_line = dreader->line; dreader->address = address; dreader->line = line; if (code_address < address) return dreader->last_line; else if (code_address == address) return dreader->line; break; case LINPROG_OP_ADVANCE_PC: debug_printf("%08llx: ADV_PC\n", (unsigned long long)dreader->state); if (!sieve_binary_read_unsigned( dreader->sblock, &dreader->state, &value)) { sieve_binary_debug_reader_reset(dreader); return 0; } debug_printf(" : + %d\n", value); address += value; break; case LINPROG_OP_ADVANCE_LINE: debug_printf("%08llx: ADV_LINE\n", (unsigned long long)dreader->state); if (!sieve_binary_read_unsigned( dreader->sblock, &dreader->state, &value)) { sieve_binary_debug_reader_reset(dreader); return 0; } line_inc = (int)value; debug_printf(" : + %d\n", line_inc); line = (line_inc > 0 ? line + (unsigned int)line_inc : line - (unsigned int)-line_inc); break; case LINPROG_OP_SET_COLUMN: debug_printf("%08llx: SET_COL\n", (unsigned long long)dreader->state); if (!sieve_binary_read_unsigned( dreader->sblock, &dreader->state, &value)) { sieve_binary_debug_reader_reset(dreader); return 0; } debug_printf(" : = %d\n", value); dreader->column = value; break; default: opcode -= LINPROG_OP_SPECIAL_BASE; address += (opcode / LINPROG_LINE_RANGE); line += LINPROG_LINE_BASE + (opcode % LINPROG_LINE_RANGE); debug_printf("%08llx: SPECIAL\n", (unsigned long long)dreader->state); debug_printf(" : +A %d +L %d\n", (opcode / LINPROG_LINE_RANGE), LINPROG_LINE_BASE + (opcode % LINPROG_LINE_RANGE)); break; } } else { debug_printf("OPCODE READ FAILED\n"); sieve_binary_debug_reader_reset(dreader); return 0; } } return dreader->line; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-code.h0000644000175100001700000002412015100335616023640 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_CODE_H #define SIEVE_CODE_H #include "lib.h" #include "buffer.h" #include "mempool.h" #include "array.h" #include "sieve-common.h" #include "sieve-runtime.h" #include "sieve-runtime-trace.h" #include "sieve-dump.h" /* * Operand object */ struct sieve_operand_class { const char *name; }; struct sieve_operand_def { const char *name; const struct sieve_extension_def *ext_def; unsigned int code; const struct sieve_operand_class *class; const void *interface; }; struct sieve_operand { const struct sieve_operand_def *def; const struct sieve_extension *ext; sieve_size_t address; const char *field_name; }; #define sieve_operand_name(opr) \ ((opr)->def == NULL ? "(NULL)" : (opr)->def->name) #define sieve_operand_is(opr, definition) \ ((opr)->def == &(definition)) sieve_size_t sieve_operand_emit(struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_operand_def *oprnd); bool sieve_operand_read(struct sieve_binary_block *sblock, sieve_size_t *address, const char *field_name, struct sieve_operand *oprnd); static inline int sieve_operand_runtime_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_operand *operand) { if (!sieve_operand_read(renv->sblock, address, field_name, operand)) { sieve_runtime_trace_operand_error(renv, operand, "invalid operand"); return SIEVE_EXEC_BIN_CORRUPT; } return SIEVE_EXEC_OK; } /* * Optional operands */ int sieve_opr_optional_next(struct sieve_binary_block *sblock, sieve_size_t *address, signed int *opt_code); static inline int sieve_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code) { sieve_size_t pc = *address; int ret; if ((ret = sieve_opr_optional_next(denv->sblock, address, opt_code)) <= 0) return ret; sieve_code_mark_specific(denv, pc); return ret; } static inline int sieve_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code) { int ret; if ((ret = sieve_opr_optional_next(renv->sblock, address, opt_code)) < 0) { sieve_runtime_trace_error( renv, "invalid optional operand code"); } return ret; } /* * Core operands */ /* Operand codes */ enum sieve_core_operand { SIEVE_OPERAND_OPTIONAL = 0x00, SIEVE_OPERAND_NUMBER, SIEVE_OPERAND_STRING, SIEVE_OPERAND_STRING_LIST, SIEVE_OPERAND_COMPARATOR, SIEVE_OPERAND_MATCH_TYPE, SIEVE_OPERAND_ADDRESS_PART, SIEVE_OPERAND_CATENATED_STRING, SIEVE_OPERAND_CUSTOM }; /* Operand classes */ extern const struct sieve_operand_class number_class; extern const struct sieve_operand_class string_class; extern const struct sieve_operand_class stringlist_class; /* Operand objects */ extern const struct sieve_operand_def omitted_operand; extern const struct sieve_operand_def number_operand; extern const struct sieve_operand_def string_operand; extern const struct sieve_operand_def stringlist_operand; extern const struct sieve_operand_def catenated_string_operand; extern const struct sieve_operand_def *sieve_operands[]; extern const unsigned int sieve_operand_count; /* Operand object interfaces */ struct sieve_opr_number_interface { bool (*dump)(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); int (*read)(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, sieve_number_t *number_r); }; struct sieve_opr_string_interface { bool (*dump)(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); int (*read)(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); }; struct sieve_opr_stringlist_interface { bool (*dump)(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); int (*read)(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, struct sieve_stringlist **strlist_r); }; /* * Core operand functions */ /* Omitted */ void sieve_opr_omitted_emit(struct sieve_binary_block *sblock); static inline bool sieve_operand_is_omitted(const struct sieve_operand *operand) { return (operand != NULL && operand->def != NULL && operand->def == &omitted_operand); } /* Number */ void sieve_opr_number_emit(struct sieve_binary_block *sblock, sieve_number_t number); bool sieve_opr_number_dump_data(const struct sieve_dumptime_env *denv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name); bool sieve_opr_number_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); int sieve_opr_number_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, sieve_number_t *number_r); int sieve_opr_number_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, sieve_number_t *number_r); static inline bool sieve_operand_is_number(const struct sieve_operand *operand) { return (operand != NULL && operand->def != NULL && operand->def->class == &number_class); } /* String */ void sieve_opr_string_emit(struct sieve_binary_block *sblock, string_t *str); bool sieve_opr_string_dump_data(const struct sieve_dumptime_env *denv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name); bool sieve_opr_string_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); bool sieve_opr_string_dump_ex(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name, const char *omitted_value); int sieve_opr_string_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, string_t **str_r); int sieve_opr_string_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, string_t **str_r); int sieve_opr_string_read_ex(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, bool optional, string_t **str_r, bool *literal_r); static inline bool sieve_operand_is_string(const struct sieve_operand *operand) { return (operand != NULL && operand->def != NULL && operand->def->class == &string_class); } static inline bool sieve_operand_is_string_literal(const struct sieve_operand *operand) { return (operand != NULL && sieve_operand_is(operand, string_operand)); } /* String list */ void sieve_opr_stringlist_emit_start(struct sieve_binary_block *sblock, unsigned int listlen, void **context); void sieve_opr_stringlist_emit_item(struct sieve_binary_block *sblock, void *context ATTR_UNUSED, string_t *item); void sieve_opr_stringlist_emit_end(struct sieve_binary_block *sblock, void *context); bool sieve_opr_stringlist_dump_data(const struct sieve_dumptime_env *denv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name); bool sieve_opr_stringlist_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); bool sieve_opr_stringlist_dump_ex(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name, const char *omitted_value); int sieve_opr_stringlist_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, struct sieve_stringlist **strlist_r); int sieve_opr_stringlist_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_stringlist **strlist_r); int sieve_opr_stringlist_read_ex(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, bool optional, struct sieve_stringlist **strlist_r); static inline bool sieve_operand_is_stringlist(const struct sieve_operand *operand) { return (operand != NULL && operand->def != NULL && (operand->def->class == &stringlist_class || operand->def->class == &string_class)); } /* Catenated string */ void sieve_opr_catenated_string_emit(struct sieve_binary_block *sblock, unsigned int elements); /* * Operation object */ struct sieve_operation_def { const char *mnemonic; const struct sieve_extension_def *ext_def; unsigned int code; bool (*dump)(const struct sieve_dumptime_env *denv, sieve_size_t *address); int (*execute)(const struct sieve_runtime_env *renv, sieve_size_t *address); }; struct sieve_operation { const struct sieve_operation_def *def; const struct sieve_extension *ext; sieve_size_t address; }; #define sieve_operation_is(oprtn, definition) \ ((oprtn)->def == &(definition)) #define sieve_operation_mnemonic(oprtn) \ ((oprtn)->def == NULL ? "(NULL)" : (oprtn)->def->mnemonic) sieve_size_t sieve_operation_emit(struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_operation_def *op_def); bool sieve_operation_read(struct sieve_binary_block *sblock, sieve_size_t *address, struct sieve_operation *oprtn); const char * sieve_operation_read_string(struct sieve_binary_block *sblock, sieve_size_t *address); /* * Core operations */ /* Opcodes */ enum sieve_operation_code { SIEVE_OPERATION_INVALID, SIEVE_OPERATION_JMP, SIEVE_OPERATION_JMPTRUE, SIEVE_OPERATION_JMPFALSE, SIEVE_OPERATION_STOP, SIEVE_OPERATION_KEEP, SIEVE_OPERATION_DISCARD, SIEVE_OPERATION_REDIRECT, SIEVE_OPERATION_ADDRESS, SIEVE_OPERATION_HEADER, SIEVE_OPERATION_EXISTS, SIEVE_OPERATION_SIZE_OVER, SIEVE_OPERATION_SIZE_UNDER, SIEVE_OPERATION_CUSTOM }; /* Operation objects */ extern const struct sieve_operation_def sieve_jmp_operation; extern const struct sieve_operation_def sieve_jmptrue_operation; extern const struct sieve_operation_def sieve_jmpfalse_operation; extern const struct sieve_operation_def *sieve_operations[]; extern const unsigned int sieve_operations_count; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-anyof.c0000644000175100001700000000527415100335616023545 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-generator.h" #include "sieve-validator.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-binary.h" /* * Anyof test * * Syntax * anyof */ static bool tst_anyof_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true); static bool tst_anyof_validate_const (struct sieve_validator *valdtr, struct sieve_command *tst, int *const_current, int const_next); const struct sieve_command_def tst_anyof = { .identifier = "anyof", .type = SCT_TEST, .positional_args = 0, .subtests = 2, .block_allowed = FALSE, .block_required = FALSE, .validate_const = tst_anyof_validate_const, .control_generate = tst_anyof_generate }; /* * Code validation */ static bool tst_anyof_validate_const (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst ATTR_UNUSED, int *const_current, int const_next) { if ( const_next > 0 ) { *const_current = 1; return FALSE; } if ( *const_current != -1 ) *const_current = const_next; return TRUE; } /* * Code generation */ static bool tst_anyof_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true) { struct sieve_binary_block *sblock = cgenv->sblock; struct sieve_ast_node *test; struct sieve_jumplist true_jumps; if ( sieve_ast_test_count(ctx->ast_node) > 1 ) { if ( !jump_true ) { /* Prepare jumplist */ sieve_jumplist_init_temp(&true_jumps, sblock); } test = sieve_ast_test_first(ctx->ast_node); while ( test != NULL ) { bool result; /* If this test list must jump on true, all sub-tests can simply add their jumps * to the caller's jump list, otherwise this test redirects all true jumps to the * end of the currently generated code. This is just after a final jump to the false * case */ if ( !jump_true ) result = sieve_generate_test(cgenv, test, &true_jumps, TRUE); else result = sieve_generate_test(cgenv, test, jumps, TRUE); if ( !result ) return FALSE; test = sieve_ast_test_next(test); } if ( !jump_true ) { /* All tests failed, jump to case FALSE */ sieve_operation_emit(sblock, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(sblock, 0)); /* All true exits jump here */ sieve_jumplist_resolve(&true_jumps); } } else { /* Script author is being inefficient; we can optimize the allof test away */ test = sieve_ast_test_first(ctx->ast_node); sieve_generate_test(cgenv, test, jumps, jump_true); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-settings.c0000644000175100001700000000736415100335616024574 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "sieve-limits.h" #include "sieve-settings.h" #include static bool sieve_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \ "sieve_"#name, name, struct sieve_settings) static const struct setting_define sieve_setting_defines[] = { { .type = SET_FILTER_NAME, .key = "sieve_env_location_mda" }, { .type = SET_FILTER_NAME, .key = "sieve_env_location_mta" }, { .type = SET_FILTER_NAME, .key = "sieve_env_location_ms" }, DEF(BOOL, enabled), DEF(SIZE, max_script_size), DEF(UINT, max_actions), DEF(UINT, max_redirects), DEF(TIME, max_cpu_time), DEF(TIME, resource_usage_timeout), DEF(STR, redirect_envelope_from), DEF(UINT, redirect_duplicate_period), DEF(STR, user_email), DEF(STR, user_log_path), DEF(STR, trace_dir), DEF(ENUM, trace_level), DEF(BOOL, trace_debug), DEF(BOOL, trace_addresses), DEF(BOOLLIST, plugins), DEF(STR, plugin_dir), DEF(BOOLLIST, extensions), DEF(BOOLLIST, global_extensions), DEF(BOOLLIST, implicit_extensions), SETTING_DEFINE_LIST_END, }; const struct sieve_settings sieve_default_settings = { .enabled = TRUE, .max_script_size = (1 << 20), .max_actions = 32, .max_redirects = 4, .max_cpu_time = 0, .resource_usage_timeout = (60 * 60), .redirect_envelope_from = "", .redirect_duplicate_period = DEFAULT_REDIRECT_DUPLICATE_PERIOD, .user_email = "", .user_log_path = "", .trace_dir = "", .trace_level = "none:actions:commands:tests:matching", .trace_debug = FALSE, .trace_addresses = FALSE, .plugins = ARRAY_INIT, .plugin_dir = MODULEDIR"/sieve", .extensions = ARRAY_INIT, .global_extensions = ARRAY_INIT, .implicit_extensions = ARRAY_INIT, }; static const struct setting_keyvalue sieve_default_settings_keyvalue[] = { { "sieve_extensions", "fileinto reject envelope encoded-character vacation subaddress " "comparator-i;ascii-numeric relational regex imap4flags copy include " "body variables enotify environment mailbox date index ihave " "duplicate mime foreverypart extracttext" }, { "sieve_env_location_ms/sieve_max_cpu_time", "30s" }, { NULL, NULL } }; const struct setting_parser_info sieve_setting_parser_info = { .name = "sieve", .defines = sieve_setting_defines, .defaults = &sieve_default_settings, .default_settings = sieve_default_settings_keyvalue, .struct_size = sizeof(struct sieve_settings), .check_func = sieve_settings_check, .pool_offset1 = 1 + offsetof(struct sieve_settings, pool), }; /* */ static bool sieve_settings_check(void *_set, pool_t pool, const char **error_r) { struct sieve_settings *set = _set; struct smtp_address *address = NULL; const char *error; if (!sieve_address_source_parse( pool, set->redirect_envelope_from, &set->parsed.redirect_envelope_from)) { *error_r = t_strdup_printf("sieve_redirect_envelope_from: " "Invalid address source '%s'", set->redirect_envelope_from); return FALSE; } if (*set->user_email != '\0' && smtp_address_parse_path(pool, set->user_email, SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL, &address, &error) < 0) { *error_r = t_strdup_printf( "sieve_user_email: Invalid SMTP address '%s': %s", set->user_email, error); return FALSE; } set->parsed.user_email = address; #ifdef CONFIG_BINARY if (array_is_created(&set->plugins) && array_not_empty(&set->plugins) && faccessat(AT_FDCWD, set->plugin_dir, R_OK | X_OK, AT_EACCESS) < 0) { *error_r = t_strdup_printf( "sieve_plugin_dir: access(%s) failed: %m", set->plugin_dir); return FALSE; } #endif return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-match-types.c0000644000175100001700000003516115100335616025166 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "compat.h" #include "mempool.h" #include "hash.h" #include "array.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-comparators.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match-types.h" #include /* * Types */ struct sieve_match_values { pool_t pool; ARRAY(string_t *) values; unsigned count; }; /* * Default match types */ const struct sieve_match_type_def *sieve_core_match_types[] = { &is_match_type, &contains_match_type, &matches_match_type }; const unsigned int sieve_core_match_types_count = N_ELEMENTS(sieve_core_match_types); /* * Match-type 'extension' */ static bool mtch_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def match_type_extension = { .name = "@match-types", .validator_load = mtch_validator_load }; /* * Validator context: * name-based match-type registry. */ static struct sieve_validator_object_registry * _get_object_registry(struct sieve_validator *valdtr) { struct sieve_instance *svinst; const struct sieve_extension *mcht_ext; svinst = sieve_validator_svinst(valdtr); mcht_ext = sieve_get_match_type_extension(svinst); return sieve_validator_object_registry_get(valdtr, mcht_ext); } void sieve_match_type_register(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_match_type_def *mcht_def) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); sieve_validator_object_registry_add(regs, ext, &mcht_def->obj_def); } static bool sieve_match_type_exists(struct sieve_validator *valdtr, const char *identifier) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); return sieve_validator_object_registry_find(regs, identifier, NULL); } static const struct sieve_match_type * sieve_match_type_create_instance(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); struct sieve_object object; struct sieve_match_type *mcht; if (!sieve_validator_object_registry_find(regs, identifier, &object)) return NULL; mcht = p_new(sieve_command_pool(cmd), struct sieve_match_type, 1); mcht->object = object; mcht->def = (const struct sieve_match_type_def *)object.def; return mcht; } bool mtch_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct sieve_validator_object_registry *regs = sieve_validator_object_registry_init(valdtr, ext); unsigned int i; /* Register core match-types */ for (i = 0; i < sieve_core_match_types_count; i++) { sieve_validator_object_registry_add( regs, NULL, &(sieve_core_match_types[i]->obj_def)); } return TRUE; } /* * Interpreter context */ struct mtch_interpreter_context { struct sieve_match_values *match_values; bool match_values_enabled; }; static void mtch_interpreter_free(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_interpreter *interp ATTR_UNUSED, void *context) { struct mtch_interpreter_context *mctx = (struct mtch_interpreter_context *)context; if (mctx->match_values != NULL) pool_unref(&mctx->match_values->pool); } struct sieve_interpreter_extension mtch_interpreter_extension = { .ext_def = &match_type_extension, .free = mtch_interpreter_free }; static inline struct mtch_interpreter_context * get_interpreter_context(struct sieve_interpreter *interp, bool create) { struct sieve_instance *svinst; const struct sieve_extension *mcht_ext; struct mtch_interpreter_context *ctx; svinst = sieve_interpreter_svinst(interp); mcht_ext = sieve_get_match_type_extension(svinst); ctx = (struct mtch_interpreter_context *) sieve_interpreter_extension_get_context(interp, mcht_ext); if (ctx == NULL && create) { pool_t pool = sieve_interpreter_pool(interp); ctx = p_new(pool, struct mtch_interpreter_context, 1); sieve_interpreter_extension_register( interp, mcht_ext, &mtch_interpreter_extension, ctx); } return ctx; } /* * Match values */ bool sieve_match_values_set_enabled(const struct sieve_runtime_env *renv, bool enable) { struct mtch_interpreter_context *ctx = get_interpreter_context(renv->interp, enable); if (ctx != NULL) { bool previous = ctx->match_values_enabled; ctx->match_values_enabled = enable; return previous; } return FALSE; } bool sieve_match_values_are_enabled(const struct sieve_runtime_env *renv) { struct mtch_interpreter_context *ctx = get_interpreter_context(renv->interp, FALSE); return (ctx == NULL ? FALSE : ctx->match_values_enabled); } struct sieve_match_values * sieve_match_values_start(const struct sieve_runtime_env *renv) { struct mtch_interpreter_context *ctx = get_interpreter_context(renv->interp, FALSE); struct sieve_match_values *match_values; if (ctx == NULL || !ctx->match_values_enabled) return NULL; pool_t pool = pool_alloconly_create("sieve_match_values", 1024); match_values = p_new(pool, struct sieve_match_values, 1); match_values->pool = pool; match_values->count = 0; p_array_init(&match_values->values, pool, 4); return match_values; } static string_t * sieve_match_values_add_entry(struct sieve_match_values *mvalues) { string_t *entry; if (mvalues == NULL) return NULL; if (mvalues->count >= SIEVE_MAX_MATCH_VALUES) return NULL; if (mvalues->count >= array_count(&mvalues->values)) { entry = str_new(mvalues->pool, 64); array_append(&mvalues->values, &entry, 1); } else { string_t *const *ep = array_idx(&mvalues->values, mvalues->count); entry = *ep; str_truncate(entry, 0); } mvalues->count++; return entry; } void sieve_match_values_set(struct sieve_match_values *mvalues, unsigned int index, string_t *value) { if (mvalues != NULL && index < array_count(&mvalues->values)) { string_t *const *ep = array_idx(&mvalues->values, index); string_t *entry = *ep; if (entry != NULL && value != NULL) { str_truncate(entry, 0); str_append_str(entry, value); } } } void sieve_match_values_add(struct sieve_match_values *mvalues, string_t *value) { string_t *entry = sieve_match_values_add_entry(mvalues); if (entry != NULL && value != NULL) str_append_str(entry, value); } void sieve_match_values_add_cstr(struct sieve_match_values *mvalues, const char *value) { string_t *entry = sieve_match_values_add_entry(mvalues); if (entry != NULL && value != NULL) str_append(entry, value); } void sieve_match_values_add_char(struct sieve_match_values *mvalues, char c) { string_t *entry = sieve_match_values_add_entry(mvalues); if (entry != NULL) str_append_c(entry, c); } void sieve_match_values_skip(struct sieve_match_values *mvalues, int num) { int i; for (i = 0; i < num; i++) (void)sieve_match_values_add_entry(mvalues); } void sieve_match_values_commit(const struct sieve_runtime_env *renv, struct sieve_match_values **mvalues) { struct mtch_interpreter_context *ctx; if ((*mvalues) == NULL) return; ctx = get_interpreter_context(renv->interp, FALSE); if (ctx == NULL || !ctx->match_values_enabled) return; if (ctx->match_values != NULL) { pool_unref(&ctx->match_values->pool); ctx->match_values = NULL; } ctx->match_values = *mvalues; *mvalues = NULL; } void sieve_match_values_abort(struct sieve_match_values **mvalues) { if ((*mvalues) == NULL) return; pool_unref(&(*mvalues)->pool); *mvalues = NULL; } void sieve_match_values_get(const struct sieve_runtime_env *renv, unsigned int index, string_t **value_r) { struct mtch_interpreter_context *ctx = get_interpreter_context(renv->interp, FALSE); struct sieve_match_values *mvalues; if (ctx == NULL || ctx->match_values == NULL) { *value_r = NULL; return; } mvalues = ctx->match_values; if (index < array_count(&mvalues->values) && index < mvalues->count) { string_t *const *entry = array_idx(&mvalues->values, index); *value_r = *entry; return; } *value_r = NULL; } /* * Match-type tagged argument */ /* Forward declarations */ static bool tag_match_type_is_instance_of(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext, const char *identifier, void **data); static bool tag_match_type_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_match_type_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); /* Argument object */ const struct sieve_argument_def match_type_tag = { .identifier = "MATCH-TYPE", .is_instance_of = tag_match_type_is_instance_of, .validate = tag_match_type_validate, .generate = tag_match_type_generate }; /* Argument implementation */ static bool tag_match_type_is_instance_of(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext ATTR_UNUSED, const char *identifier, void **data) { const struct sieve_match_type *mcht; if (data == NULL) return sieve_match_type_exists(valdtr, identifier); if ((mcht = sieve_match_type_create_instance( valdtr, cmd, identifier)) == NULL) return FALSE; *data = (void *)mcht; return TRUE; } static bool tag_match_type_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd ATTR_UNUSED) { const struct sieve_match_type *mcht = (const struct sieve_match_type *)(*arg)->argument->data; struct sieve_match_type_context *mtctx; mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1); mtctx->match_type = mcht; mtctx->argument = *arg; mtctx->comparator = NULL; /* Can be filled in later */ (*arg)->argument->data = mtctx; /* Syntax: * ":is" / ":contains" / ":matches" (subject to extension) */ /* Skip tag */ *arg = sieve_ast_argument_next(*arg); /* Check whether this match type requires additional validation. Additional validation can override the match type recorded in the context for later code generation. */ if (mcht->def != NULL && mcht->def->validate != NULL) return mcht->def->validate(valdtr, arg, mtctx); return TRUE; } static bool tag_match_type_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { struct sieve_match_type_context *mtctx = (struct sieve_match_type_context *)arg->argument->data; (void)sieve_opr_match_type_emit(cgenv->sblock, mtctx->match_type); return TRUE; } void sieve_match_types_link_tags(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code) { struct sieve_instance *svinst; const struct sieve_extension *mcht_ext; svinst = sieve_validator_svinst(valdtr); mcht_ext = sieve_get_comparator_extension(svinst); sieve_validator_register_tag(valdtr, cmd_reg, mcht_ext, &match_type_tag, id_code); } /* * Validation */ bool sieve_match_type_validate(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *key_arg, const struct sieve_match_type *mcht_default, const struct sieve_comparator *cmp_default) { struct sieve_ast_argument *arg = sieve_command_first_argument(cmd); struct sieve_ast_argument *mt_arg = NULL; struct sieve_match_type_context *mtctx; const struct sieve_match_type *mcht = NULL; const struct sieve_comparator *cmp = NULL; /* Find match type and comparator among the arguments */ while (arg != NULL && arg != cmd->first_positional) { if (sieve_argument_is_comparator(arg)) { cmp = sieve_comparator_tag_get(arg); if (mt_arg != NULL) break; } if (sieve_argument_is_match_type(arg)) { mt_arg = arg; if (cmp != NULL) break; } arg = sieve_ast_argument_next(arg); } /* Verify the default match type if none is specified explicitly */ if (mt_arg == NULL || mt_arg->argument == NULL || mt_arg->argument->data == NULL) { mcht = sieve_match_type_copy(sieve_command_pool(cmd), mcht_default); mtctx = t_new(struct sieve_match_type_context, 1); mtctx->command = cmd; mtctx->match_type = mcht; } else { mtctx = (struct sieve_match_type_context *) mt_arg->argument->data; mcht = mtctx->match_type; } /* Verify using the default comparator if none is specified explicitly */ if (cmp != NULL ) mtctx->comparator_specified = TRUE; else cmp = sieve_comparator_copy(sieve_command_pool(cmd), cmp_default); mtctx->comparator = cmp; /* Check whether this match type requires additional validation. Additional validation can override the match type recorded in the context for later code generation. */ if (mcht != NULL && mcht->def != NULL && mcht->def->validate_context != NULL) { return mcht->def->validate_context(valdtr, mt_arg, mtctx, key_arg); } return TRUE; } void sieve_match_type_arguments_remove( struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct sieve_ast_argument *arg = sieve_command_first_argument(cmd); /* Remove any comparator and match type arguments */ while (arg != NULL && arg != cmd->first_positional) { if (sieve_argument_is_comparator(arg)) { arg = sieve_ast_arguments_detach(arg, 1); continue; } if (sieve_argument_is_match_type(arg)) { arg = sieve_ast_arguments_detach(arg, 1); continue; } arg = sieve_ast_argument_next(arg); } } /* * Match-type operand */ const struct sieve_operand_class sieve_match_type_operand_class = { "match type" }; static const struct sieve_extension_objects core_match_types = SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_match_types); const struct sieve_operand_def match_type_operand = { .name = "match-type", .code = SIEVE_OPERAND_MATCH_TYPE, .class = &sieve_match_type_operand_class, .interface = &core_match_types }; /* * Common validation implementation */ bool sieve_match_substring_validate_context( struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg ATTR_UNUSED) { const struct sieve_comparator *cmp = ctx->comparator; if (cmp == NULL || cmp->def == NULL) return TRUE; if ((cmp->def->flags & SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH) == 0) { sieve_argument_validate_error( valdtr, arg, "the specified %s comparator does not support " "sub-string matching as required by the :%s match type", cmp->object.def->identifier, ctx->match_type->object.def->identifier); return FALSE; } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-dump.h0000644000175100001700000000102515100335616023672 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_DUMP_H #define SIEVE_DUMP_H #include "sieve-common.h" #include "sieve-code-dumper.h" #include "sieve-binary-dumper.h" /* * Dumptime environment */ struct sieve_dumptime_env { /* Dumpers */ struct sieve_instance *svinst; struct sieve_binary_dumper *dumper; struct sieve_code_dumper *cdumper; /* Binary */ struct sieve_binary *sbin; struct sieve_binary_block *sblock; /* Code position */ const struct sieve_operation *oprtn; sieve_size_t offset; /* Output stream */ struct ostream *stream; }; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-storage-settings.h0000644000175100001700000000142715100335616026235 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_STORAGE_SETTINGS_H #define SIEVE_STORAGE_SETTINGS_H #define SIEVE_STORAGE_SETTINGS_FILTER "sieve_script" struct sieve_storage_settings { pool_t pool; const char *script_storage; unsigned int script_precedence; const char *script_type; ARRAY_TYPE(const_string) script_cause; const char *script_driver; const char *script_name; const char *script_bin_path; uoff_t quota_storage_size; unsigned int quota_script_count; ARRAY_TYPE(const_string) storages; }; extern const struct setting_parser_info sieve_storage_setting_parser_info; bool sieve_storage_settings_match_script_type( const struct sieve_storage_settings *set, const char *type); bool sieve_storage_settings_match_script_cause( const struct sieve_storage_settings *set, const char *cause); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-code-dumper.c0000644000175100001700000002045715100335616025136 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include #include #include "lib.h" #include "str.h" #include "mempool.h" #include "ostream.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-actions.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-result.h" #include "sieve-comparators.h" #include "sieve-dump.h" /* * Code dumper extension */ struct sieve_code_dumper_extension_reg { const struct sieve_code_dumper_extension *cdmpext; const struct sieve_extension *ext; void *context; }; struct sieve_code_dumper { pool_t pool; /* Dump status */ struct sieve_operation oprtn; sieve_size_t mark_address; unsigned int mark_line; unsigned int mark_last_line; unsigned int indent; /* Dump environment */ struct sieve_dumptime_env *dumpenv; struct sieve_binary_debug_reader *dreader; ARRAY(struct sieve_code_dumper_extension_reg) extensions; }; struct sieve_code_dumper *sieve_code_dumper_create (struct sieve_dumptime_env *denv) { pool_t pool; struct sieve_code_dumper *cdumper; pool = pool_alloconly_create("sieve_code_dumper", 4096); cdumper = p_new(pool, struct sieve_code_dumper, 1); cdumper->pool = pool; cdumper->dumpenv = denv; /* Setup storage for extension contexts */ p_array_init(&cdumper->extensions, pool, sieve_extensions_get_count(denv->svinst)); return cdumper; } void sieve_code_dumper_free(struct sieve_code_dumper **_cdumper) { struct sieve_code_dumper *cdumper = *_cdumper; const struct sieve_code_dumper_extension_reg *eregs; unsigned int count, i; sieve_binary_debug_reader_deinit(&cdumper->dreader); /* Signal registered extensions that the dumper is being destroyed */ eregs = array_get(&cdumper->extensions, &count); for ( i = 0; i < count; i++ ) { if ( eregs[i].cdmpext != NULL && eregs[i].cdmpext->free != NULL ) eregs[i].cdmpext->free(cdumper, eregs[i].context); } pool_unref(&cdumper->pool); *_cdumper = NULL; } pool_t sieve_code_dumper_pool(struct sieve_code_dumper *cdumper) { return cdumper->pool; } /* EXtension support */ void sieve_dump_extension_register (struct sieve_code_dumper *cdumper, const struct sieve_extension *ext, const struct sieve_code_dumper_extension *cdmpext, void *context) { struct sieve_code_dumper_extension_reg *reg; if ( ext->id < 0 ) return; reg = array_idx_get_space(&cdumper->extensions, (unsigned int) ext->id); reg->cdmpext = cdmpext; reg->ext = ext; reg->context = context; } void sieve_dump_extension_set_context (struct sieve_code_dumper *cdumper, const struct sieve_extension *ext, void *context) { struct sieve_code_dumper_extension_reg *reg; if ( ext->id < 0 ) return; reg = array_idx_get_space(&cdumper->extensions, (unsigned int) ext->id); reg->context = context; } void *sieve_dump_extension_get_context (struct sieve_code_dumper *cdumper, const struct sieve_extension *ext) { const struct sieve_code_dumper_extension_reg *reg; if ( ext->id < 0 || ext->id >= (int) array_count(&cdumper->extensions) ) return NULL; reg = array_idx(&cdumper->extensions, (unsigned int) ext->id); return reg->context; } /* Dump functions */ void sieve_code_dumpf (const struct sieve_dumptime_env *denv, const char *fmt, ...) { struct sieve_code_dumper *cdumper = denv->cdumper; unsigned tab = cdumper->indent; string_t *outbuf = t_str_new(128); va_list args; va_start(args, fmt); str_printfa(outbuf, "%08llx: ", (unsigned long long) cdumper->mark_address); if ( cdumper->mark_line > 0 && (cdumper->indent == 0 || cdumper->mark_line != cdumper->mark_last_line) ) { str_printfa(outbuf, "%4u: ", cdumper->mark_line); cdumper->mark_last_line = cdumper->mark_line; } else { str_append(outbuf, " "); } while ( tab > 0 ) { str_append(outbuf, " "); tab--; } str_vprintfa(outbuf, fmt, args); str_append_c(outbuf, '\n'); va_end(args); o_stream_nsend(denv->stream, str_data(outbuf), str_len(outbuf)); } static inline void sieve_code_line_mark (const struct sieve_dumptime_env *denv, sieve_size_t location) { if ( denv->cdumper->dreader != NULL ) { denv->cdumper->mark_line = sieve_binary_debug_read_line (denv->cdumper->dreader, location); } } void sieve_code_mark(const struct sieve_dumptime_env *denv) { denv->cdumper->mark_address = denv->offset; sieve_code_line_mark(denv, denv->offset); } void sieve_code_mark_specific (const struct sieve_dumptime_env *denv, sieve_size_t location) { denv->cdumper->mark_address = location; sieve_code_line_mark(denv, location); } void sieve_code_descend(const struct sieve_dumptime_env *denv) { denv->cdumper->indent++; } void sieve_code_ascend(const struct sieve_dumptime_env *denv) { if ( denv->cdumper->indent > 0 ) denv->cdumper->indent--; } /* Code Dump */ static bool sieve_code_dumper_print_operation (struct sieve_code_dumper *cdumper) { struct sieve_dumptime_env *denv = cdumper->dumpenv; struct sieve_operation *oprtn = &(cdumper->oprtn); sieve_size_t *address = &(denv->offset); /* Mark start address of operation */ cdumper->indent = 0; cdumper->mark_address = *address; sieve_code_line_mark(denv, *address); /* Read operation */ if ( sieve_operation_read(denv->sblock, address, oprtn) ) { const struct sieve_operation_def *opdef = oprtn->def; if ( opdef->dump != NULL ) return opdef->dump(denv, address); else if ( opdef->mnemonic != NULL ) sieve_code_dumpf(denv, "%s", opdef->mnemonic); else return FALSE; return TRUE; } sieve_code_dumpf(denv, "Failed to read opcode."); return FALSE; } static bool sieve_code_dumper_print_extension (struct sieve_code_dumper *cdumper) { struct sieve_dumptime_env *denv = cdumper->dumpenv; sieve_size_t *address = &(denv->offset); struct sieve_binary_block *sblock = denv->sblock; unsigned int code = 0, deferred; const struct sieve_extension *ext; sieve_code_mark(denv); if ( !sieve_binary_read_extension (sblock, address, &code, &ext) || !sieve_binary_read_byte (sblock, address, &deferred) ) { return FALSE; } if ( ext->def == NULL) { sieve_code_dumpf(denv, "[undefined]"); } else { sieve_code_dumpf(denv, "%s%s", sieve_extension_name(ext), (deferred > 0 ? " (deferred)" : "")); if (ext->def->code_dump != NULL ) { sieve_code_descend(denv); if ( !ext->def->code_dump(ext, denv, address) ) return FALSE; sieve_code_ascend(denv); } } return TRUE; } void sieve_code_dumper_run(struct sieve_code_dumper *cdumper) { struct sieve_dumptime_env *denv = cdumper->dumpenv; struct sieve_binary *sbin = denv->sbin; struct sieve_binary_block *sblock = denv->sblock; unsigned int debug_block_id, ext_count; bool success; sieve_size_t *address; denv->offset = 0; denv->oprtn = &(cdumper->oprtn); address = &(denv->offset); /* Heading */ o_stream_nsend_str(denv->stream, "Address Line Code\n"); /* Load debug block */ sieve_code_mark(denv); if ( sieve_binary_read_unsigned(sblock, address, &debug_block_id) ) { struct sieve_binary_block *debug_block = sieve_binary_block_get(sbin, debug_block_id); if ( debug_block == NULL ) { sieve_code_dumpf(denv, "Invalid id %d for debug block.", debug_block_id); return; } else { /* Initialize debug reader */ cdumper->dreader = sieve_binary_debug_reader_init(debug_block); /* Dump block id */ sieve_code_dumpf(denv, "DEBUG BLOCK: %d", debug_block_id); } } else { sieve_code_dumpf(denv, "Binary code header is corrupt."); return; } /* Load and dump extensions listed in code */ sieve_code_mark(denv); success = TRUE; if ( sieve_binary_read_unsigned(sblock, address, &ext_count) ) { unsigned int i; sieve_code_dumpf(denv, "EXTENSIONS [%d]:", ext_count); sieve_code_descend(denv); for ( i = 0; success && (i < ext_count); i++ ) { T_BEGIN { success = success && sieve_code_dumper_print_extension(cdumper); } T_END; } sieve_code_ascend(denv); } else success = FALSE; if ( !success ) { sieve_code_dumpf(denv, "Binary code header is corrupt."); return; } while ( *address < sieve_binary_block_get_size(sblock) ) { T_BEGIN { success = sieve_code_dumper_print_operation(cdumper); } T_END; if ( !success ) { sieve_code_dumpf(denv, "Binary is corrupt."); return; } } /* Mark end of the binary */ cdumper->indent = 0; cdumper->mark_address = sieve_binary_block_get_size(sblock); sieve_code_dumpf(denv, "[End of code]"); } dovecot-pigeonhole-2.4.2/src/lib-sieve/cmd-redirect.c0000644000175100001700000004516515100335616024166 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "ioloop.h" #include "str-sanitize.h" #include "strfuncs.h" #include "istream.h" #include "istream-header-filter.h" #include "ostream.h" #include "mail-storage.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-address.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-code-dumper.h" #include "sieve-result.h" #include "sieve-smtp.h" #include "sieve-message.h" #include /* * Redirect command * * Syntax * redirect */ static bool cmd_redirect_validate(struct sieve_validator *validator, struct sieve_command *cmd); static bool cmd_redirect_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def cmd_redirect = { .identifier = "redirect", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_redirect_validate, .generate = cmd_redirect_generate }; /* * Redirect operation */ static bool cmd_redirect_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_redirect_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def cmd_redirect_operation = { .mnemonic = "REDIRECT", .code = SIEVE_OPERATION_REDIRECT, .dump = cmd_redirect_operation_dump, .execute = cmd_redirect_operation_execute }; /* * Redirect action */ static bool act_redirect_equals(const struct sieve_script_env *senv, const struct sieve_action *act1, const struct sieve_action *act2); static int act_redirect_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_redirect_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_redirect_start(const struct sieve_action_exec_env *aenv, void **tr_context); static int act_redirect_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); static int act_redirect_commit(const struct sieve_action_exec_env *aenv, void *tr_context); const struct sieve_action_def act_redirect = { .name = "redirect", .flags = SIEVE_ACTFLAG_TRIES_DELIVER, .equals = act_redirect_equals, .check_duplicate = act_redirect_check_duplicate, .print = act_redirect_print, .start = act_redirect_start, .execute = act_redirect_execute, .commit = act_redirect_commit, }; /* * Validation */ static bool cmd_redirect_validate(struct sieve_validator *validator, struct sieve_command *cmd) { struct sieve_instance *svinst = sieve_validator_svinst(validator); struct sieve_ast_argument *arg = cmd->first_positional; /* Check and activate address argument */ if (!sieve_validate_positional_argument(validator, cmd, arg, "address", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(validator, cmd, arg, FALSE)) return FALSE; /* We can only assess the validity of the outgoing address when it is * a string literal. For runtime-generated strings this needs to be * done at runtime. */ if (sieve_argument_is_string_literal(arg)) { string_t *raw_address = sieve_ast_argument_str(arg); const char *error; bool result; T_BEGIN { /* Parse the address */ result = sieve_address_validate_str(raw_address, &error); if (!result) { sieve_argument_validate_error( validator, arg, "specified redirect address '%s' is invalid: %s", str_sanitize(str_c(raw_address),128), error); } } T_END; return result; } if (svinst->set->max_redirects == 0) { sieve_command_validate_error(validator, cmd, "local policy prohibits the use of a redirect action"); return FALSE; } return TRUE; } /* * Code generation */ static bool cmd_redirect_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, NULL, &cmd_redirect_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_redirect_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "REDIRECT"); sieve_code_descend(denv); if (sieve_action_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return sieve_opr_string_dump(denv, address, "address"); } /* * Code execution */ static int cmd_redirect_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_execute_env *eenv = renv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct sieve_side_effects_list *slist = NULL; string_t *redirect; const struct smtp_address *to_address; const char *error; int ret; /* * Read data */ /* Optional operands (side effects only) */ if (sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0) return ret; /* Read the address */ if ((ret = sieve_opr_string_read(renv, address, "address", &redirect)) <= 0) return ret; /* * Perform operation */ /* Parse the address */ to_address = sieve_address_parse_str(redirect, &error); if (to_address == NULL) { sieve_runtime_error(renv, NULL, "specified redirect address '%s' is invalid: %s", str_sanitize(str_c(redirect),128), error); return SIEVE_EXEC_FAILURE; } if (svinst->set->max_redirects == 0) { sieve_runtime_error(renv, NULL, "local policy prohibits the use of a redirect action"); return SIEVE_EXEC_FAILURE; } if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS)) { sieve_runtime_trace(renv, 0, "redirect action"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, "forward message to address %s", smtp_address_encode_path(to_address)); } /* Add redirect action to the result */ return sieve_act_redirect_add_to_result(renv, "redirect", slist, to_address); } /* * Action implementation */ struct act_redirect_transaction { const char *msg_id, *new_msg_id; const char *dupeid; bool skip_redirect:1; }; static bool act_redirect_equals(const struct sieve_script_env *senv ATTR_UNUSED, const struct sieve_action *act1, const struct sieve_action *act2) { struct act_redirect_context *rd_ctx1 = (struct act_redirect_context *)act1->context; struct act_redirect_context *rd_ctx2 = (struct act_redirect_context *)act2->context; /* Address is already normalized */ return (smtp_address_equals(rd_ctx1->to_address, rd_ctx2->to_address)); } static int act_redirect_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other) { const struct sieve_execute_env *eenv = renv->exec_env; return (act_redirect_equals(eenv->scriptenv, act, act_other) ? 1 : 0); } static void act_redirect_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep) { struct act_redirect_context *ctx = (struct act_redirect_context *)action->context; sieve_result_action_printf(rpenv, "redirect message to: %s", smtp_address_encode_path(ctx->to_address)); *keep = FALSE; } static int act_redirect_send(const struct sieve_action_exec_env *aenv, struct mail *mail, struct act_redirect_context *ctx, const char *new_msg_id) ATTR_NULL(4) { static const char *hide_headers[] = { "Return-Path" }; const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct sieve_message_context *msgctx = aenv->msgctx; const struct sieve_script_env *senv = eenv->scriptenv; struct sieve_address_source env_from = svinst->set->parsed.redirect_envelope_from; struct istream *input; struct ostream *output; const struct smtp_address *sender; const char *error; struct sieve_smtp_context *sctx; int ret; /* Just to be sure */ if (!sieve_smtp_available(senv)) { sieve_result_global_warning(aenv, "no means to send mail"); return SIEVE_EXEC_FAILURE; } if (mail_get_stream(mail, NULL, NULL, &input) < 0) { return sieve_result_mail_error(aenv, mail, "failed to read input message"); } /* Determine which sender to use From RFC 5228, Section 4.2: The envelope sender address on the outgoing message is chosen by the sieve implementation. It MAY be copied from the message being processed. However, if the message being processed has an empty envelope sender address the outgoing message MUST also have an empty envelope sender address. This last requirement is imposed to prevent loops in the case where a message is redirected to an invalid address when then returns a delivery status notification that also ends up being redirected to the same invalid address. */ if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) { /* Envelope available */ sender = sieve_message_get_sender(msgctx); if (sender != NULL && sieve_address_source_get_address(&env_from, svinst, senv, msgctx, eenv->flags, &sender) < 0) sender = NULL; } else { /* No envelope available */ ret = sieve_address_source_get_address(&env_from, svinst, senv, msgctx, eenv->flags, &sender); if (ret < 0) sender = NULL; else if (ret == 0) sender = svinst->set->parsed.user_email; } /* Open SMTP transport */ sctx = sieve_smtp_start_single(senv, ctx->to_address, sender, &output); /* Remove unwanted headers */ input = i_stream_create_header_filter( input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hide_headers, N_ELEMENTS(hide_headers), *null_header_filter_callback, NULL); T_BEGIN { string_t *hdr = t_str_new(256); const struct smtp_address *user_email; /* Prepend sieve headers (should not affect signatures) */ rfc2822_header_append(hdr, "X-Sieve", SIEVE_IMPLEMENTATION, FALSE, NULL); if (svinst->set->parsed.user_email == NULL && (eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) user_email = sieve_message_get_final_recipient(msgctx); else user_email = sieve_get_user_email(svinst); if (user_email != NULL) { rfc2822_header_append(hdr, "X-Sieve-Redirected-From", smtp_address_encode(user_email), FALSE, NULL); } /* Add new Message-ID if message doesn't have one */ if (new_msg_id != NULL) rfc2822_header_write(hdr, "Message-ID", new_msg_id); o_stream_nsend(output, str_data(hdr), str_len(hdr)); } T_END; o_stream_nsend_istream(output, input); if (input->stream_errno != 0) { sieve_result_critical(aenv, "failed to read input message", "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); i_stream_unref(&input); sieve_smtp_abort(sctx); return SIEVE_EXEC_TEMP_FAILURE; } i_stream_unref(&input); /* Close SMTP transport */ if ((ret = sieve_smtp_finish(sctx, &error)) <= 0) { if (ret < 0) { sieve_result_global_error( aenv, "failed to redirect message to <%s>: %s " "(temporary failure)", smtp_address_encode(ctx->to_address), str_sanitize(error, 512)); return SIEVE_EXEC_TEMP_FAILURE; } sieve_result_global_log_error( aenv, "failed to redirect message to <%s>: %s " "(permanent failure)", smtp_address_encode(ctx->to_address), str_sanitize(error, 512)); return SIEVE_EXEC_FAILURE; } return SIEVE_EXEC_OK; } static int act_redirect_get_duplicate_id(struct act_redirect_context *ctx, const struct sieve_action_exec_env *aenv, const char *msg_id, const char **dupeid_r) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_message_context *msgctx = aenv->msgctx; const struct sieve_message_data *msgdata = eenv->msgdata; struct mail *mail = msgdata->mail; const struct smtp_address *recipient; const char *resent_id = NULL, *list_id = NULL; /* Read identifying headers */ if (mail_get_first_header(mail, "resent-message-id", &resent_id) < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field 'resent-message-id'"); } if (resent_id == NULL && mail_get_first_header(mail, "resent-from", &resent_id) < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field 'resent-from'"); } if (mail_get_first_header(mail, "list-id", &list_id) < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field 'list-id'"); } if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) recipient = sieve_message_get_orig_recipient(msgctx); else recipient = sieve_get_user_email(eenv->svinst); pool_t pool = sieve_result_pool(aenv->result); /* Base the duplicate ID on: - the message id - the recipient running this Sieve script - redirect target address - if this message is resent: the message-id or from-address of the original message - if the message came through a mailing list: the mailinglist ID */ *dupeid_r = p_strdup_printf( pool, "%s-%s-%s-%s-%s", msg_id, (recipient != NULL ? smtp_address_encode(recipient) : ""), smtp_address_encode(ctx->to_address), (resent_id != NULL ? resent_id : ""), (list_id != NULL ? list_id : "")); return SIEVE_EXEC_OK; } static int act_redirect_check_loop_header(const struct sieve_action_exec_env *aenv, struct mail *mail, bool *loop_detected_r) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_message_context *msgctx = aenv->msgctx; const char *const *headers; const char *recipient, *user_email; const struct smtp_address *addr; int ret; *loop_detected_r = FALSE; ret = mail_get_headers(mail, "x-sieve-redirected-from", &headers); if (ret < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field " "'x-sieve-redirected-from'"); } if (ret == 0) return SIEVE_EXEC_OK; recipient = user_email = NULL; if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) { addr = sieve_message_get_final_recipient(msgctx); if (addr != NULL) recipient = smtp_address_encode(addr); } addr = sieve_get_user_email(eenv->svinst); if (addr != NULL) user_email = smtp_address_encode(addr); while (*headers != NULL) { const char *header = t_str_trim(*headers, " \t\r\n"); if (recipient != NULL && strcmp(header, recipient) == 0) { *loop_detected_r = TRUE; break; } if (user_email != NULL && strcmp(header, user_email) == 0) { *loop_detected_r = TRUE; break; } headers++; } return SIEVE_EXEC_OK; } static int act_redirect_start(const struct sieve_action_exec_env *aenv, void **tr_context) { struct act_redirect_transaction *trans; pool_t pool = sieve_result_pool(aenv->result); /* Create transaction context */ trans = p_new(pool, struct act_redirect_transaction, 1); *tr_context = trans; return SIEVE_EXEC_OK; } static int act_redirect_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep) { const struct sieve_action *action = aenv->action; const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct act_redirect_context *ctx = (struct act_redirect_context *)action->context; struct act_redirect_transaction *trans = tr_context; struct sieve_message_context *msgctx = aenv->msgctx; struct mail *mail = (action->mail != NULL ? action->mail : sieve_message_get_mail(msgctx)); const struct sieve_message_data *msgdata = eenv->msgdata; bool duplicate, loop_detected = FALSE; int ret; /* * Prevent mail loops */ /* Create Message-ID for the message if it has none */ trans->msg_id = msgdata->id; if (trans->msg_id == NULL) { pool_t pool = sieve_result_pool(aenv->result); const char *msg_id; if (mail_get_message_id_no_validation(msgdata->mail, &msg_id) > 0) trans->msg_id = p_strdup(pool, msg_id); else { msg_id = sieve_message_get_new_id(svinst); trans->msg_id = trans->new_msg_id = p_strdup(pool, msg_id); } } /* Create ID for duplicate database lookup */ ret = act_redirect_get_duplicate_id(ctx, aenv, trans->msg_id, &trans->dupeid); if (ret != SIEVE_EXEC_OK) return ret; i_assert(trans->dupeid != NULL); /* Check whether we've seen this message before */ ret = sieve_action_duplicate_check(aenv, trans->dupeid, strlen(trans->dupeid), &duplicate); if (ret < SIEVE_EXEC_OK) { sieve_result_critical( aenv, "failed to check for duplicate forward", "failed to check for duplicate forward to <%s>%s", smtp_address_encode(ctx->to_address), (ret == SIEVE_EXEC_TEMP_FAILURE ? " (temporaty failure)" : "")); return ret; } if (duplicate) { sieve_result_global_log( aenv, "discarded duplicate forward to <%s>", smtp_address_encode(ctx->to_address)); trans->skip_redirect = TRUE; return SIEVE_EXEC_OK; } /* Check whether we've seen this message before based on added headers */ ret = act_redirect_check_loop_header(aenv, mail, &loop_detected); if (ret != SIEVE_EXEC_OK) return ret; if (loop_detected) { sieve_result_global_log( aenv, "not forwarding message to <%s>: " "the 'x-sieve-redirected-from' header indicates a mail loop", smtp_address_encode(ctx->to_address)); trans->skip_redirect = TRUE; return SIEVE_EXEC_OK; } /* Cancel implicit keep */ *keep = FALSE; return SIEVE_EXEC_OK; } static int act_redirect_commit(const struct sieve_action_exec_env *aenv, void *tr_context) { const struct sieve_action *action = aenv->action; const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct act_redirect_context *ctx = (struct act_redirect_context *)action->context; struct sieve_message_context *msgctx = aenv->msgctx; struct mail *mail = (action->mail != NULL ? action->mail : sieve_message_get_mail(msgctx)); struct act_redirect_transaction *trans = tr_context; int ret; if (trans->skip_redirect) return SIEVE_EXEC_OK; /* * Try to forward the message */ ret = act_redirect_send(aenv, mail, ctx, trans->new_msg_id); if (ret == SIEVE_EXEC_OK) { /* Mark this message id as forwarded to the specified destination */ sieve_action_duplicate_mark( aenv, trans->dupeid, strlen(trans->dupeid), ioloop_time + svinst->set->redirect_duplicate_period); eenv->exec_status->significant_action_executed = TRUE; struct event_passthrough *e = sieve_action_create_finish_event(aenv)-> add_str("redirect_target", smtp_address_encode(ctx->to_address)); sieve_result_event_log(aenv, e->event(), "forwarded to <%s>", smtp_address_encode(ctx->to_address)); /* Indicate that message was successfully forwarded */ eenv->exec_status->message_forwarded = TRUE; return SIEVE_EXEC_OK; } return ret; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-address.h0000644000175100001700000000306015100335616024353 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_ADDRESS_H #define SIEVE_ADDRESS_H #include "lib.h" #include "strfuncs.h" #include "smtp-address.h" #include "sieve-common.h" #include "sieve-stringlist.h" /* * Address list API */ struct sieve_address_list { struct sieve_stringlist strlist; int (*next_item)(struct sieve_address_list *_addrlist, struct smtp_address *addr_r, string_t **unparsed_r); }; static inline int sieve_address_list_next_item(struct sieve_address_list *addrlist, struct smtp_address *addr_r, string_t **unparsed_r) { return addrlist->next_item(addrlist, addr_r, unparsed_r); } static inline void sieve_address_list_reset(struct sieve_address_list *addrlist) { sieve_stringlist_reset(&addrlist->strlist); } static inline int sieve_address_list_get_length(struct sieve_address_list *addrlist) { return sieve_stringlist_get_length(&addrlist->strlist); } static inline void sieve_address_list_set_trace(struct sieve_address_list *addrlist, bool trace) { sieve_stringlist_set_trace(&addrlist->strlist, trace); } /* * Header address list */ struct sieve_address_list * sieve_header_address_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_values); /* * Sieve address parsing/validatin */ const struct smtp_address * sieve_address_parse(const char *address, const char **error_r); const struct smtp_address * sieve_address_parse_str(string_t *address, const char **error_r); bool sieve_address_validate(const char *address, const char **error_r); bool sieve_address_validate_str(string_t *address, const char **error_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-validator.h0000644000175100001700000001434715100335616024725 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_VALIDATOR_H #define SIEVE_VALIDATOR_H #include "lib.h" #include "sieve-common.h" /* * Types */ enum sieve_argument_type { SAT_NUMBER, SAT_CONST_STRING, SAT_VAR_STRING, SAT_STRING_LIST, SAT_COUNT }; struct sieve_command_registration; /* * Validator */ struct sieve_validator; struct sieve_validator * sieve_validator_create(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags); void sieve_validator_free(struct sieve_validator **valdtr); pool_t sieve_validator_pool(struct sieve_validator *valdtr); bool sieve_validator_run(struct sieve_validator *valdtr); /* * Accessors */ struct sieve_error_handler * sieve_validator_error_handler(struct sieve_validator *valdtr); struct sieve_ast *sieve_validator_ast(struct sieve_validator *valdtr); struct sieve_script *sieve_validator_script(struct sieve_validator *valdtr); const char *sieve_validator_script_cause(struct sieve_validator *valdtr); struct sieve_instance *sieve_validator_svinst(struct sieve_validator *valdtr); enum sieve_compile_flags sieve_validator_compile_flags(struct sieve_validator *valdtr); /* * Command/Test registry */ void sieve_validator_register_command(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_command_def *command); /* * Per-command tagged argument registry */ void sieve_validator_register_tag(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, int id_code); void sieve_validator_register_external_tag( struct sieve_validator *valdtr, const char *command, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, int id_code); void sieve_validator_register_persistent_tag( struct sieve_validator *valdtr, const char *command, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def); /* * Overriding the default literal arguments */ void sieve_validator_argument_override( struct sieve_validator *valdtr, enum sieve_argument_type type, const struct sieve_extension *ext, const struct sieve_argument_def *arg_def); bool sieve_validator_argument_activate_super( struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant); /* * Argument validation API */ bool sieve_validate_positional_argument(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos, enum sieve_ast_argument_type req_type); bool sieve_validator_argument_activate(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant); bool sieve_validate_tag_parameter(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *tag, struct sieve_ast_argument *param, const char *arg_name, unsigned int arg_pos, enum sieve_ast_argument_type req_type, bool constant); /* * Extension support */ struct sieve_validator_extension { const struct sieve_extension_def *ext; bool (*check_conflict)(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, const struct sieve_extension *ext_other, bool required); bool (*validate)(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, bool required); void (*free)(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context); }; bool sieve_validator_extension_load(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext, bool required) ATTR_NULL(2, 3); const struct sieve_extension * sieve_validator_extension_load_by_name(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, const char *ext_name); const struct sieve_extension * sieve_validator_extension_load_implicit(struct sieve_validator *valdtr, const char *ext_name); void sieve_validator_extension_register( struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_validator_extension *valext, void *context); bool sieve_validator_extension_loaded(struct sieve_validator *valdtr, const struct sieve_extension *ext); void sieve_validator_extension_set_context(struct sieve_validator *valdtr, const struct sieve_extension *ext, void *context); void *sieve_validator_extension_get_context(struct sieve_validator *valdtr, const struct sieve_extension *ext); /* * Validator object registry */ struct sieve_validator_object_registry; struct sieve_validator_object_registry * sieve_validator_object_registry_get(struct sieve_validator *valdtr, const struct sieve_extension *ext); void sieve_validator_object_registry_add( struct sieve_validator_object_registry *regs, const struct sieve_extension *ext, const struct sieve_object_def *obj_def); bool sieve_validator_object_registry_find( struct sieve_validator_object_registry *regs, const char *identifier, struct sieve_object *obj); struct sieve_validator_object_registry * sieve_validator_object_registry_create(struct sieve_validator *valdtr); struct sieve_validator_object_registry * sieve_validator_object_registry_init(struct sieve_validator *valdtr, const struct sieve_extension *ext); /* * Error handling */ void sieve_validator_error(struct sieve_validator *valdtr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_validator_error(valdtr, ...) \ sieve_validator_error(valdtr, __FILE__, __LINE__, __VA_ARGS__) void sieve_validator_warning(struct sieve_validator *valdtr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_validator_warning(valdtr, ...) \ sieve_validator_warning(valdtr, __FILE__, __LINE__, __VA_ARGS__) #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-comparators.c0000644000175100001700000001456615100335616025270 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "hash.h" #include "array.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-comparators.h" #include #include /* * Core comparators */ const struct sieve_comparator_def *sieve_core_comparators[] = { &i_octet_comparator, &i_ascii_casemap_comparator, &i_unicode_casemap_comparator }; const unsigned int sieve_core_comparators_count = N_ELEMENTS(sieve_core_comparators); /* * Comparator 'extension' */ static bool cmp_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def comparator_extension = { .name = "@comparators", .validator_load = cmp_validator_load }; /* * Validator context: * name-based comparator registry. */ static struct sieve_validator_object_registry * _get_object_registry(struct sieve_validator *valdtr) { struct sieve_instance *svinst; const struct sieve_extension *mcht_ext; svinst = sieve_validator_svinst(valdtr); mcht_ext = sieve_get_comparator_extension(svinst); return sieve_validator_object_registry_get(valdtr, mcht_ext); } void sieve_comparator_register(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_comparator_def *cmp) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); sieve_validator_object_registry_add(regs, ext, &cmp->obj_def); } static struct sieve_comparator * sieve_comparator_create(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); struct sieve_object object; struct sieve_comparator *cmp; if (!sieve_validator_object_registry_find(regs, identifier, &object)) return NULL; cmp = p_new(sieve_command_pool(cmd), struct sieve_comparator, 1); cmp->object = object; cmp->def = (const struct sieve_comparator_def *) object.def; return cmp; } bool cmp_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct sieve_validator_object_registry *regs = sieve_validator_object_registry_init(valdtr, ext); unsigned int i; /* Register core comparators */ for (i = 0; i < sieve_core_comparators_count; i++) { sieve_validator_object_registry_add( regs, NULL, &(sieve_core_comparators[i]->obj_def)); } return TRUE; } /* * Comparator tagged argument */ /* Forward declarations */ static bool tag_comparator_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_comparator_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); /* Argument object */ const struct sieve_argument_def comparator_tag = { .identifier = "comparator", .validate = tag_comparator_validate, .generate = tag_comparator_generate }; /* Argument implementation */ static bool tag_comparator_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; const struct sieve_comparator *cmp; /* Skip tag */ *arg = sieve_ast_argument_next(*arg); /* Check syntax: * ":comparator" */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE) ) { return FALSE; } /* FIXME: We can currently only handle string literal argument, so * variables are not allowed. */ if (!sieve_argument_is_string_literal(*arg)) { sieve_argument_validate_error( valdtr, *arg, "this Sieve implementation currently only supports " "a literal string argument for the :comparator tag"); return FALSE; } /* Get comparator from registry */ cmp = sieve_comparator_create(valdtr, cmd, sieve_ast_argument_strc(*arg)); if (cmp == NULL) { sieve_argument_validate_error( valdtr, *arg, "unknown comparator '%s'", str_sanitize(sieve_ast_argument_strc(*arg),80)); return FALSE; } /* String argument not needed during code generation, so detach it from * argument list */ *arg = sieve_ast_arguments_detach(*arg, 1); /* Store comparator in context */ tag->argument->data = (void *)cmp; return TRUE; } static bool tag_comparator_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { const struct sieve_comparator *cmp = (const struct sieve_comparator *)arg->argument->data; sieve_opr_comparator_emit(cgenv->sblock, cmp); return TRUE; } /* Functions to enable and evaluate comparator tag for commands */ void sieve_comparators_link_tag(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code) { struct sieve_instance *svinst; const struct sieve_extension *mcht_ext; svinst = sieve_validator_svinst(valdtr); mcht_ext = sieve_get_comparator_extension(svinst); sieve_validator_register_tag(valdtr, cmd_reg, mcht_ext, &comparator_tag, id_code); } bool sieve_comparator_tag_is(struct sieve_ast_argument *tag, const struct sieve_comparator_def *cmp_def) { const struct sieve_comparator *cmp; if (!sieve_argument_is(tag, comparator_tag)) return FALSE; cmp = (const struct sieve_comparator *)tag->argument->data; return (cmp->def == cmp_def); } const struct sieve_comparator * sieve_comparator_tag_get(struct sieve_ast_argument *tag) { if (!sieve_argument_is(tag, comparator_tag)) return NULL; return (const struct sieve_comparator *)tag->argument->data; } /* * Comparator coding */ const struct sieve_operand_class sieve_comparator_operand_class = { "comparator" }; static const struct sieve_extension_objects core_comparators = SIEVE_EXT_DEFINE_COMPARATORS(sieve_core_comparators); const struct sieve_operand_def comparator_operand = { .name = "comparator", .code = SIEVE_OPERAND_COMPARATOR, .class = &sieve_comparator_operand_class, .interface = &core_comparators }; /* * Trivial/Common comparator method implementations */ bool sieve_comparator_octet_skip(const struct sieve_comparator *cmp ATTR_UNUSED, const char **val, const char *val_end) { if (*val < val_end) { (*val)++; return TRUE; } return FALSE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/cmd-if.c0000644000175100001700000001527115100335616022756 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-code.h" #include "sieve-binary.h" /* * Commands */ static bool cmd_if_validate (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_elsif_validate (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_if_validate_const (struct sieve_validator *valdtr, struct sieve_command *cmd, int *const_current, int const_next); static bool cmd_if_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); static bool cmd_else_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); /* If command * * Syntax: * if */ const struct sieve_command_def cmd_if = { .identifier = "if", .type = SCT_COMMAND, .positional_args = 0, .subtests = 1, .block_allowed = TRUE, .block_required = TRUE, .validate = cmd_if_validate, .validate_const = cmd_if_validate_const, .generate = cmd_if_generate }; /* ElsIf command * * Santax: * elsif */ const struct sieve_command_def cmd_elsif = { .identifier = "elsif", .type = SCT_COMMAND, .positional_args = 0, .subtests = 1, .block_allowed = TRUE, .block_required = TRUE, .validate = cmd_elsif_validate, .validate_const = cmd_if_validate_const, .generate = cmd_if_generate }; /* Else command * * Syntax: * else */ const struct sieve_command_def cmd_else = { .identifier = "else", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = TRUE, .block_required = TRUE, .validate = cmd_elsif_validate, .validate_const = cmd_if_validate_const, .generate = cmd_else_generate }; /* * Context management */ struct cmd_if_context_data { struct cmd_if_context_data *previous; struct cmd_if_context_data *next; int const_condition; bool jump_generated; sieve_size_t exit_jump; }; static void cmd_if_initialize_context_data (struct sieve_command *cmd, struct cmd_if_context_data *previous) { struct cmd_if_context_data *cmd_data; /* Assign context */ cmd_data = p_new(sieve_command_pool(cmd), struct cmd_if_context_data, 1); cmd_data->exit_jump = 0; cmd_data->jump_generated = FALSE; /* Update linked list of contexts */ cmd_data->previous = previous; cmd_data->next = NULL; if ( previous != NULL ) previous->next = cmd_data; /* Check const status */ cmd_data->const_condition = -1; while ( previous != NULL ) { if ( previous->const_condition > 0 ) { cmd_data->const_condition = 0; break; } previous = previous->previous; } /* Assign to command context */ cmd->data = cmd_data; } /* * Validation */ static bool cmd_if_validate (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { /* Start if-command structure */ cmd_if_initialize_context_data(cmd, NULL); return TRUE; } static bool cmd_elsif_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_command *prev; i_assert(cmd != NULL); prev = sieve_command_prev(cmd); /* Check valid command placement */ if ( prev == NULL || ( !sieve_command_is(prev, cmd_if) && !sieve_command_is(prev, cmd_elsif) ) ) { sieve_command_validate_error(valdtr, cmd, "the %s command must follow an if or elseif command", sieve_command_identifier(cmd)); return FALSE; } /* Previous command in this block is 'if' or 'elsif', so we can safely refer * to its context data */ cmd_if_initialize_context_data(cmd, prev->data); return TRUE; } static bool cmd_if_validate_const (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd, int *const_current, int const_next) { struct cmd_if_context_data *cmd_data = (struct cmd_if_context_data *) cmd->data; if ( cmd_data != NULL ) { if ( cmd_data->const_condition == 0 ) { *const_current = cmd_data->const_condition; return FALSE; } cmd_data->const_condition = const_next; } *const_current = const_next; return ( const_next < 0 ); } /* * Code generation */ /* The if command does not generate specific IF-ELSIF-ELSE opcodes, but only uses * JMP instructions. This is why the implementation of the if command does not * include an opcode implementation. */ static void cmd_if_resolve_exit_jumps (struct sieve_binary_block *sblock, struct cmd_if_context_data *cmd_data) { struct cmd_if_context_data *if_ctx = cmd_data->previous; /* Iterate backwards through all if-command contexts and resolve the * exit jumps to the current code position. */ while ( if_ctx != NULL ) { if ( if_ctx->jump_generated ) sieve_binary_resolve_offset(sblock, if_ctx->exit_jump); if_ctx = if_ctx->previous; } } static bool cmd_if_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct sieve_binary_block *sblock = cgenv->sblock; struct cmd_if_context_data *cmd_data = (struct cmd_if_context_data *) cmd->data; struct sieve_ast_node *test; struct sieve_jumplist jmplist; /* Generate test condition */ if ( cmd_data->const_condition < 0 ) { /* Prepare jumplist */ sieve_jumplist_init_temp(&jmplist, sblock); test = sieve_ast_test_first(cmd->ast_node); if ( !sieve_generate_test(cgenv, test, &jmplist, FALSE) ) return FALSE; } /* Case true { */ if ( cmd_data->const_condition != 0 ) { if ( !sieve_generate_block(cgenv, cmd->ast_node) ) return FALSE; } /* Are we the final command in this if-elsif-else structure? */ if ( cmd_data->next == NULL || cmd_data->const_condition == 1 ) { /* Yes, Resolve previous exit jumps to this point */ cmd_if_resolve_exit_jumps(sblock, cmd_data); } else if ( cmd_data->const_condition < 0 ) { /* No, generate jump to end of if-elsif-else structure (resolved later) * This of course is not necessary if the {} block contains a command * like stop at top level that unconditionally exits the block already * anyway. */ if ( !sieve_command_block_exits_unconditionally(cmd) ) { sieve_operation_emit(sblock, NULL, &sieve_jmp_operation); cmd_data->exit_jump = sieve_binary_emit_offset(sblock, 0); cmd_data->jump_generated = TRUE; } } if ( cmd_data->const_condition < 0 ) { /* Case false ... (subsequent elsif/else commands might generate more) */ sieve_jumplist_resolve(&jmplist); } return TRUE; } static bool cmd_else_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_if_context_data *cmd_data = (struct cmd_if_context_data *) cmd->data; /* Else { */ if ( cmd_data->const_condition != 0 ) { if ( !sieve_generate_block(cgenv, cmd->ast_node) ) return FALSE; /* } End: resolve all exit blocks */ cmd_if_resolve_exit_jumps(cgenv->sblock, cmd_data); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-truefalse.c0000644000175100001700000000500615100335616024414 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-ast.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-interpreter.h" /* * True/False test command */ static bool tst_false_validate_const (struct sieve_validator *valdtr, struct sieve_command *tst, int *const_current, int const_next); static bool tst_false_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_jumplist *jumps, bool jump_true); const struct sieve_command_def tst_false = { .identifier = "false", .type = SCT_TEST, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate_const = tst_false_validate_const, .control_generate = tst_false_generate }; static bool tst_true_validate_const (struct sieve_validator *valdtr, struct sieve_command *tst, int *const_current, int const_next); static bool tst_true_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_jumplist *jumps, bool jump_true); const struct sieve_command_def tst_true = { .identifier = "true", .type = SCT_TEST, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate_const = tst_true_validate_const, .control_generate = tst_true_generate }; /* * Code validation */ static bool tst_false_validate_const (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst ATTR_UNUSED, int *const_current, int const_next ATTR_UNUSED) { *const_current = 0; return TRUE; } static bool tst_true_validate_const (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst ATTR_UNUSED, int *const_current, int const_next ATTR_UNUSED) { *const_current = 1; return TRUE; } /* * Code generation */ static bool tst_false_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd ATTR_UNUSED, struct sieve_jumplist *jumps, bool jump_true) { if ( !jump_true ) { sieve_operation_emit(cgenv->sblock, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sblock, 0)); } return TRUE; } static bool tst_true_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd ATTR_UNUSED, struct sieve_jumplist *jumps, bool jump_true) { if ( jump_true ) { sieve_operation_emit(cgenv->sblock, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sblock, 0)); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-plugins.c0000644000175100001700000001043315100335616024404 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "settings-parser.h" #include "module-dir.h" #include "master-service.h" #include "sieve-extensions.h" #include "sieve-common.h" #include "sieve-plugins.h" /* * Types */ typedef int (*sieve_plugin_load_func_t)(struct sieve_instance *svinst, void **context); typedef void (*sieve_plugin_unload_func_t)(struct sieve_instance *svinst, void *context); struct sieve_plugin { struct module *module; void *context; struct sieve_plugin *next; }; /* * Plugin support */ static struct module *sieve_modules = NULL; static int sieve_modules_refcount = 0; static struct module *sieve_plugin_module_find(const char *name) { struct module *module; module = sieve_modules; while (module != NULL) { const char *mod_name; /* Strip module names */ mod_name = module_get_plugin_name(module); if (strcmp(mod_name, name) == 0) return module; module = module->next; } return NULL; } int sieve_plugins_load(struct sieve_instance *svinst, const char *path, const char *plugins) { struct module *module; struct module_dir_load_settings mod_set; const char *const *module_names; unsigned int i; /* Determine what to load */ if (path == NULL && plugins == NULL) { /* From settings */ module_names = settings_boollist_get(&svinst->set->plugins); path = svinst->set->plugin_dir; } else { /* From function parameters */ const char **module_names_mod; if (plugins == NULL || *plugins == '\0') return 0; module_names_mod = t_strsplit_spaces(plugins, ", "); if (path == NULL || *path == '\0') path = sieve_default_settings.plugin_dir; for (i = 0; module_names_mod[i] != NULL; i++) { /* Allow giving the module names also in non-base form. */ module_names_mod[i] = module_file_get_name(module_names_mod[i]); } module_names = module_names_mod; } if (module_names == NULL || *module_names == NULL) return 0; i_zero(&mod_set); mod_set.abi_version = PIGEONHOLE_ABI_VERSION; mod_set.binary_name = master_service_get_name(master_service); mod_set.setting_name = "sieve_plugins"; mod_set.require_init_funcs = TRUE; mod_set.debug = svinst->debug; /* Load missing plugin modules */ sieve_modules = module_dir_load_missing(sieve_modules, path, module_names, &mod_set); /* Call plugin load functions for this Sieve instance */ if (svinst->plugins == NULL) sieve_modules_refcount++; for (i = 0; module_names[i] != NULL; i++) { struct sieve_plugin *plugin; const char *name = module_names[i]; sieve_plugin_load_func_t load_func; /* Find the module */ module = sieve_plugin_module_find(name); i_assert(module != NULL); /* Check whether the plugin is already loaded in this instance */ plugin = svinst->plugins; while (plugin != NULL) { if (plugin->module == module) break; plugin = plugin->next; } /* Skip it if it is loaded already */ if (plugin != NULL) continue; /* Create plugin list item */ plugin = p_new(svinst->pool, struct sieve_plugin, 1); plugin->module = module; /* Call load function */ load_func = (sieve_plugin_load_func_t) module_get_symbol(module, t_strdup_printf("%s_load", module->name)); if (load_func != NULL && load_func(svinst, &plugin->context) < 0) return -1; /* Add plugin to the instance */ if (svinst->plugins == NULL) svinst->plugins = plugin; else { struct sieve_plugin *plugin_last; plugin_last = svinst->plugins; while ( plugin_last->next != NULL ) plugin_last = plugin_last->next; plugin_last->next = plugin; } } return 0; } void sieve_plugins_unload(struct sieve_instance *svinst) { struct sieve_plugin *plugin; if (svinst->plugins == NULL) return; /* Call plugin unload functions for this instance */ plugin = svinst->plugins; while (plugin != NULL) { struct module *module = plugin->module; sieve_plugin_unload_func_t unload_func; unload_func = (sieve_plugin_unload_func_t) module_get_symbol( module, t_strdup_printf("%s_unload", module->name)); if (unload_func != NULL) unload_func(svinst, plugin->context); plugin = plugin->next; } /* Physically unload modules */ i_assert(sieve_modules_refcount > 0); if (--sieve_modules_refcount != 0) return; module_dir_unload(&sieve_modules); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-generator.h0000644000175100001700000000714115100335616024720 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_GENERATOR_H #define SIEVE_GENERATOR_H #include "sieve-common.h" /* * Code generator */ struct sieve_generator; struct sieve_codegen_env { struct sieve_generator *gentr; struct sieve_instance *svinst; enum sieve_compile_flags flags; struct sieve_script *script; struct sieve_ast *ast; struct sieve_binary *sbin; struct sieve_binary_block *sblock; }; struct sieve_generator * sieve_generator_create(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags); void sieve_generator_free(struct sieve_generator **generator); /* * Accessors */ struct sieve_error_handler * sieve_generator_error_handler(struct sieve_generator *gentr); pool_t sieve_generator_pool(struct sieve_generator *gentr); struct sieve_script *sieve_generator_script(struct sieve_generator *gentr); struct sieve_binary *sieve_generator_get_binary(struct sieve_generator *gentr); struct sieve_binary_block * sieve_generator_get_block(struct sieve_generator *gentr); /* * Extension support */ void sieve_generator_extension_set_context(struct sieve_generator *gentr, const struct sieve_extension *ext, void *context); const void * sieve_generator_extension_get_context(struct sieve_generator *gentr, const struct sieve_extension *ext); /* * Jump list */ struct sieve_jumplist { pool_t pool; struct sieve_binary_block *block; ARRAY(sieve_size_t) jumps; }; struct sieve_jumplist * sieve_jumplist_create(pool_t pool, struct sieve_binary_block *sblock); void sieve_jumplist_init_temp(struct sieve_jumplist *jlist, struct sieve_binary_block *sblock); void sieve_jumplist_reset(struct sieve_jumplist *jlist); void sieve_jumplist_add(struct sieve_jumplist *jlist, sieve_size_t jump); void sieve_jumplist_resolve(struct sieve_jumplist *jlist); /* * Code generation API */ bool sieve_generate_argument(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); bool sieve_generate_arguments(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_ast_argument **last_arg_r); bool sieve_generate_argument_parameters(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_ast_argument *arg); bool sieve_generate_block(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *block); bool sieve_generate_test(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *tst_node, struct sieve_jumplist *jlist, bool jump_true); struct sieve_binary * sieve_generator_run(struct sieve_generator *gentr, struct sieve_binary_block **sblock_r); /* * Error handling */ void sieve_generator_error(struct sieve_generator *gentr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_generator_error(gentr, ...) \ sieve_generator_error(gentr, __FILE__, __LINE__, __VA_ARGS__) void sieve_generator_warning(struct sieve_generator *gentr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_generator_warning(gentr, ...) \ sieve_generator_warning(gentr, __FILE__, __LINE__, __VA_ARGS__) void sieve_generator_critical(struct sieve_generator *gentr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_generator_critical(gentr, ...) \ sieve_generator_critical(gentr, __FILE__, __LINE__, __VA_ARGS__) #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-runtime-trace.c0000644000175100001700000000745715100335616025516 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "ostream.h" #include "sieve-common.h" #include "sieve-script.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-interpreter.h" #include "sieve-runtime.h" #include "sieve-runtime-trace.h" static inline string_t *_trace_line_new (const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line) { string_t *trline; unsigned int i; trline = t_str_new(128); if ( (renv->trace->config.flags & SIEVE_TRFLG_ADDRESSES) > 0 ) str_printfa(trline, "%08llx: ", (unsigned long long) address); if ( cmd_line > 0 ) str_printfa(trline, "%4d: ", cmd_line); else str_append(trline, " "); for ( i = 0; i < renv->trace->indent; i++ ) str_append(trline, " "); return trline; } static inline void _trace_line_print (string_t *trline, const struct sieve_runtime_env *renv) { sieve_trace_log_write_line(renv->trace->log, trline); } static inline void _trace_line_print_empty (const struct sieve_runtime_env *renv) { sieve_trace_log_write_line(renv->trace->log, NULL); } /* * Trace errors */ void _sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, va_list args) { string_t *trline = _trace_line_new(renv, renv->pc, 0); str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn)); str_vprintfa(trline, fmt, args); _trace_line_print(trline, renv); } void _sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, const char *fmt, va_list args) { string_t *trline = _trace_line_new(renv, oprnd->address, sieve_runtime_get_source_location(renv, oprnd->address)); str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn)); if ( oprnd->field_name != NULL ) str_printfa(trline, "%s: ", oprnd->field_name); str_vprintfa(trline, fmt, args); _trace_line_print(trline, renv); } /* * Trace info */ static inline void ATTR_FORMAT(4, 0) _sieve_runtime_trace_vprintf (const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line, const char *fmt, va_list args) { string_t *trline = _trace_line_new(renv, address, cmd_line); str_vprintfa(trline, fmt, args); _trace_line_print(trline, renv); } static inline void ATTR_FORMAT(4, 5) _sieve_runtime_trace_printf (const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line, const char *fmt, ...) { va_list args; va_start(args, fmt); _sieve_runtime_trace_vprintf(renv, address, cmd_line, fmt, args); va_end(args); } void ATTR_FORMAT(2, 0) _sieve_runtime_trace (const struct sieve_runtime_env *renv, const char *fmt, va_list args) { _sieve_runtime_trace_vprintf (renv, renv->oprtn->address, sieve_runtime_get_command_location(renv), fmt, args); } void _sieve_runtime_trace_address (const struct sieve_runtime_env *renv, sieve_size_t address, const char *fmt, va_list args) { _sieve_runtime_trace_vprintf (renv, address, sieve_runtime_get_source_location(renv, address), fmt, args); } /* * Trace boundaries */ void _sieve_runtime_trace_begin(const struct sieve_runtime_env *renv) { const char *script_name = ( renv->script != NULL ? sieve_script_name(renv->script) : sieve_binary_path(renv->sbin) ); _trace_line_print_empty(renv); _sieve_runtime_trace_printf(renv, renv->pc, 0, "## Started executing script '%s'", script_name); } void _sieve_runtime_trace_end(const struct sieve_runtime_env *renv) { const char *script_name = ( renv->script != NULL ? sieve_script_name(renv->script) : sieve_binary_path(renv->sbin) ); _sieve_runtime_trace_printf(renv, renv->pc, 0, "## Finished executing script '%s'", script_name); _trace_line_print_empty(renv); } void _sieve_runtime_trace_sep(const struct sieve_runtime_env *renv) { _trace_line_print_empty(renv); } dovecot-pigeonhole-2.4.2/src/lib-sieve/mcht-contains.c0000644000175100001700000000275215100335616024366 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Match-type ':contains' */ #include "lib.h" #include "sieve-match-types.h" #include "sieve-comparators.h" #include "sieve-match.h" #include #include /* * Forward declarations */ static int mcht_contains_match_key (struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size); /* * Match-type object */ const struct sieve_match_type_def contains_match_type = { SIEVE_OBJECT("contains", &match_type_operand, SIEVE_MATCH_TYPE_CONTAINS), .validate_context = sieve_match_substring_validate_context, .match_key = mcht_contains_match_key }; /* * Match-type implementation */ /* FIXME: Naive substring match implementation. Should switch to more * efficient algorithm if large values need to be searched (e.g. message body). */ static int mcht_contains_match_key (struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size) { const struct sieve_comparator *cmp = mctx->comparator; const char *vend = (const char *) val + val_size; const char *kend = (const char *) key + key_size; const char *vp = val; const char *kp = key; if ( val_size == 0 ) return ( key_size == 0 ? 1 : 0 ); if ( cmp->def == NULL || cmp->def->char_match == NULL ) return 0; while ( (vp < vend) && (kp < kend) ) { if ( !cmp->def->char_match(cmp, &vp, vend, &kp, kend) ) vp++; } return ( kp == kend ? 1 : 0 ); } dovecot-pigeonhole-2.4.2/src/lib-sieve/cmp-i-unicode-casemap.c0000644000175100001700000000443415100335616025656 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ /* Comparator 'i;unicode-casemap': * */ #include "lib.h" #include "unichar.h" #include "sieve-common.h" #include "sieve-comparators.h" /* * Comparator implementation */ static int cmp_i_unicode_casemap_compare(const struct sieve_comparator *cmp ATTR_UNUSED, const char *val1, size_t val1_size, const char *val2, size_t val2_size) { string_t *value_a = t_str_new(val1_size); string_t *value_b = t_str_new(val2_size); uni_utf8_to_decomposed_titlecase(val1, val1_size, value_a); uni_utf8_to_decomposed_titlecase(val2, val2_size, value_b); val1 = str_c(value_a); val2 = str_c(value_b); return strcmp(val1, val2); } static bool cmp_i_unicode_casemap_char_match(const struct sieve_comparator *cmp ATTR_UNUSED, const char **val, const char *val_end, const char **key, const char *key_end) { const char *val_begin = *val; const char *key_begin = *key; while (*val < val_end && *key < key_end) { unsigned int val_len = uni_utf8_char_bytes((unsigned char)**val); unsigned int key_len = uni_utf8_char_bytes((unsigned char)**key); unichar_t val_chr, key_chr; uni_utf8_get_char(*val, &val_chr); uni_utf8_get_char(*key, &key_chr); /* normalize */ val_chr = uni_ucs4_to_titlecase(val_chr); key_chr = uni_ucs4_to_titlecase(key_chr); if (val_chr != key_chr) break; (*val) += val_len; (*key) += key_len; } i_assert(*val <= val_end); i_assert(*key <= key_end); if (*key < key_end) { /* Reset */ *val = val_begin; *key = key_begin; return FALSE; } return TRUE; } static bool cmp_i_unicode_casemap_char_skip(const struct sieve_comparator *cmp ATTR_UNUSED, const char **val, const char *val_end) { if (*val >= val_end) return FALSE; unsigned int len = uni_utf8_char_bytes(**val); (*val) += len; return TRUE; } /* * Comparator object */ const struct sieve_comparator_def i_unicode_casemap_comparator = { SIEVE_OBJECT("i;unicode-casemap", &comparator_operand, SIEVE_COMPARATOR_I_UNICODE_CASEMAP), .flags = SIEVE_COMPARATOR_FLAG_EQUALITY | SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH, .compare = cmp_i_unicode_casemap_compare, .char_match = cmp_i_unicode_casemap_char_match, .char_skip = cmp_i_unicode_casemap_char_skip, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-parser.h0000644000175100001700000000062615100335616024227 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_PARSER_H #define SIEVE_PARSER_H #include "lib.h" #include "sieve-common.h" struct sieve_parser; struct sieve_parser * sieve_parser_create(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r); void sieve_parser_free(struct sieve_parser **parser); bool sieve_parser_run(struct sieve_parser *parser, struct sieve_ast **ast); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/ext-reject.c0000644000175100001700000003630015100335616023665 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension reject * ---------------- * * Authors: Stephan Bosch * Specification: RFC 5429 * Implementation: full * Status: testing * */ #include "lib.h" #include "ioloop.h" #include "hostpid.h" #include "str-sanitize.h" #include "message-date.h" #include "message-size.h" #include "istream.h" #include "istream-header-filter.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-result.h" #include "sieve-message.h" #include "sieve-smtp.h" /* * Forward declarations */ static const struct sieve_command_def reject_command; static const struct sieve_operation_def reject_operation; static const struct sieve_command_def ereject_command; static const struct sieve_operation_def ereject_operation; /* * Extensions */ static bool ext_reject_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, bool required); static int ext_reject_interpreter_run(const struct sieve_extension *this_ext, const struct sieve_runtime_env *renv, void *context, bool deferred); /* Reject */ static bool ext_reject_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_reject_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_extension_def reject_extension = { .name = "reject", .validator_load = ext_reject_validator_load, .interpreter_load = ext_reject_interpreter_load, SIEVE_EXT_DEFINE_OPERATION(reject_operation) }; const struct sieve_validator_extension reject_validator_extension = { .ext = &reject_extension, .validate = ext_reject_validator_validate }; const struct sieve_interpreter_extension reject_interpreter_extension = { .ext_def = &reject_extension, .run = ext_reject_interpreter_run }; static bool ext_reject_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ sieve_validator_register_command(valdtr, ext, &reject_command); sieve_validator_extension_register(valdtr, ext, &reject_validator_extension, NULL); return TRUE; } static bool ext_reject_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_interpreter_extension_register(renv->interp, ext, &reject_interpreter_extension, NULL); return TRUE; } /* EReject */ static bool ext_ereject_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_ereject_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_extension_def ereject_extension = { .name = "ereject", .validator_load = ext_ereject_validator_load, .interpreter_load = ext_ereject_interpreter_load, SIEVE_EXT_DEFINE_OPERATION(ereject_operation) }; const struct sieve_validator_extension ereject_validator_extension = { .ext = &ereject_extension, .validate = ext_reject_validator_validate }; const struct sieve_interpreter_extension ereject_interpreter_extension = { .ext_def = &ereject_extension, .run = ext_reject_interpreter_run }; static bool ext_ereject_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ sieve_validator_register_command(valdtr, ext, &ereject_command); sieve_validator_extension_register(valdtr, ext, &ereject_validator_extension, NULL); return TRUE; } static bool ext_ereject_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_interpreter_extension_register(renv->interp, ext, &ereject_interpreter_extension, NULL); return TRUE; } /* Environment checking */ static bool ext_reject_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg, bool required) { if (required) { enum sieve_compile_flags flags = sieve_validator_compile_flags(valdtr); if ((flags & SIEVE_COMPILE_FLAG_NO_ENVELOPE) != 0) { sieve_argument_validate_error( valdtr, require_arg, "the %s extension cannot be used in this context " "(needs access to message envelope)", sieve_extension_name(ext)); return FALSE; } } return TRUE; } static int ext_reject_interpreter_run(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, void *context ATTR_UNUSED, bool deferred) { const struct sieve_execute_env *eenv = renv->exec_env; if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0) { if (!deferred) { sieve_runtime_error( renv, NULL, "the %s extension cannot be used in this context " "(needs access to message envelope)", sieve_extension_name(ext)); } return SIEVE_EXEC_FAILURE; } return SIEVE_EXEC_OK; } /* * Commands */ /* Forward declarations */ static bool cmd_reject_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_reject_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); /* Reject command * * Syntax: * reject */ static const struct sieve_command_def reject_command = { .identifier = "reject", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_reject_validate, .generate = cmd_reject_generate }; /* EReject command * * Syntax: * ereject */ static const struct sieve_command_def ereject_command = { .identifier = "ereject", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_reject_validate, .generate = cmd_reject_generate, }; /* * Operations */ /* Forward declarations */ static bool ext_reject_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_reject_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); /* Reject operation */ static const struct sieve_operation_def reject_operation = { .mnemonic = "REJECT", .ext_def = &reject_extension, .dump = ext_reject_operation_dump, .execute = ext_reject_operation_execute }; /* EReject operation */ static const struct sieve_operation_def ereject_operation = { .mnemonic = "EREJECT", .ext_def = &ereject_extension, .dump = ext_reject_operation_dump, .execute = ext_reject_operation_execute }; /* * Reject action */ static int act_reject_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); int act_reject_check_conflict(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_reject_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_reject_start(const struct sieve_action_exec_env *aenv, void **tr_context); static int act_reject_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); static int act_reject_commit(const struct sieve_action_exec_env *aenv, void *tr_context); const struct sieve_action_def act_reject = { .name = "reject", .flags = SIEVE_ACTFLAG_SENDS_RESPONSE, .check_duplicate = act_reject_check_duplicate, .check_conflict = act_reject_check_conflict, .print = act_reject_print, .start = act_reject_start, .execute = act_reject_execute, .commit = act_reject_commit, }; struct act_reject_context { const char *reason; bool ereject; }; /* * Validation */ static bool cmd_reject_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; if (!sieve_validate_positional_argument(valdtr, cmd, arg, "reason", 1, SAAT_STRING)) return FALSE; return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } /* * Code generation */ static bool cmd_reject_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { if (sieve_command_is(cmd, reject_command)) { sieve_operation_emit(cgenv->sblock, cmd->ext, &reject_operation); } else { sieve_operation_emit(cgenv->sblock, cmd->ext, &ereject_operation); } /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool ext_reject_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(denv->oprtn)); sieve_code_descend(denv); if (sieve_action_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return sieve_opr_string_dump(denv, address, "reason"); } /* * Interpretation */ static int ext_reject_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *oprtn = renv->oprtn; const struct sieve_extension *this_ext = oprtn->ext; struct sieve_side_effects_list *slist = NULL; struct act_reject_context *act; string_t *reason; pool_t pool; int ret; /* * Read data */ /* Optional operands (side effects only) */ if (sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0) return ret; /* Read rejection reason */ if ((ret = sieve_opr_string_read(renv, address, "reason", &reason)) <= 0) return ret; /* * Perform operation */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS)) { if (sieve_operation_is(oprtn, ereject_operation)) sieve_runtime_trace(renv, 0, "ereject action"); else sieve_runtime_trace(renv, 0, "reject action"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, "reject message with reason '%s'", str_sanitize(str_c(reason), 64)); } /* Add reject action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_reject_context, 1); act->reason = p_strdup(pool, str_c(reason)); act->ereject = sieve_operation_is(oprtn, ereject_operation); if (sieve_result_add_action(renv, this_ext, (act->ereject ? "ereject" : "reject"), &act_reject, slist, act, 0, FALSE) < 0) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } /* * Action implementation */ struct act_reject_transaction { bool ignore_reject:1; }; static int act_reject_check_duplicate(const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *act, const struct sieve_action *act_other) { if (!sieve_action_is_executed(act_other, renv->result)) { sieve_runtime_error( renv, act->location, "duplicate reject/ereject action not allowed " "(previously triggered one was here: %s)", act_other->location); return -1; } return 1; } int act_reject_check_conflict(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other) { if ((act_other->def->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0) { if (!sieve_action_is_executed(act_other, renv->result)) { sieve_runtime_error( renv, act->location, "reject/ereject action conflicts with other action: " "the %s action (%s) tries to deliver the message", act_other->def->name, act_other->location); return -1; } } if ((act_other->def->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0) { struct act_reject_context *rj_ctx; if (!sieve_action_is_executed(act_other, renv->result)) { sieve_runtime_error( renv, act->location, "reject/ereject action conflicts with other action: " "the %s action (%s) also sends a response to the sender", act_other->def->name, act_other->location); return -1; } /* Conflicting action was already executed, transform reject * into discard equivalent. */ rj_ctx = (struct act_reject_context *)act->context; rj_ctx->reason = NULL; } return 0; } static void act_reject_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep) { struct act_reject_context *rj_ctx = (struct act_reject_context *)action->context; if (rj_ctx->reason != NULL) { sieve_result_action_printf( rpenv, "reject message with reason: %s", str_sanitize(rj_ctx->reason, 128)); } else { sieve_result_action_printf( rpenv, "reject message without sending a response (discard)"); } *keep = FALSE; } static int act_reject_start(const struct sieve_action_exec_env *aenv, void **tr_context) { struct act_reject_transaction *trans; pool_t pool = sieve_result_pool(aenv->result); /* Create transaction context */ trans = p_new(pool, struct act_reject_transaction, 1); *tr_context = trans; return SIEVE_EXEC_OK; } static int act_reject_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep) { const struct sieve_execute_env *eenv = aenv->exec_env; struct act_reject_context *rj_ctx = (struct act_reject_context *)aenv->action->context; struct act_reject_transaction *trans = tr_context; const struct smtp_address *sender, *recipient; sender = sieve_message_get_sender(aenv->msgctx); recipient = sieve_message_get_orig_recipient(aenv->msgctx); if ((eenv->flags & SIEVE_EXECUTE_FLAG_SKIP_RESPONSES) != 0) { sieve_result_global_log( aenv, "not sending reject message (skipped)"); trans->ignore_reject = TRUE; return SIEVE_EXEC_OK; } if (smtp_address_isnull(recipient)) { sieve_result_global_warning( aenv, "reject action aborted: envelope recipient is <>"); trans->ignore_reject = TRUE; return SIEVE_EXEC_OK; } if (rj_ctx->reason == NULL) { sieve_result_global_log( aenv, "not sending reject message " "(would cause second response to sender)"); trans->ignore_reject = TRUE; *keep = FALSE; return SIEVE_EXEC_OK; } if (smtp_address_isnull(sender)) { sieve_result_global_log( aenv, "not sending reject message to <>"); trans->ignore_reject = TRUE; *keep = FALSE; return SIEVE_EXEC_OK; } *keep = FALSE; return SIEVE_EXEC_OK; } static int act_reject_commit(const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED) { const struct sieve_execute_env *eenv = aenv->exec_env; struct act_reject_context *rj_ctx = (struct act_reject_context *)aenv->action->context; struct act_reject_transaction *trans = tr_context; const struct smtp_address *sender, *recipient; int ret; sender = sieve_message_get_sender(aenv->msgctx); recipient = sieve_message_get_orig_recipient(aenv->msgctx); if (trans->ignore_reject) return SIEVE_EXEC_OK; if ((ret = sieve_action_reject_mail(aenv, recipient, rj_ctx->reason)) <= 0) return ret; eenv->exec_status->significant_action_executed = TRUE; struct event_passthrough *e = sieve_action_create_finish_event(aenv); sieve_result_event_log(aenv, e->event(), "rejected message from <%s> (%s)", smtp_address_encode(sender), (rj_ctx->ereject ? "ereject" : "reject")); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-actions.c0000644000175100001700000007172415100335616024375 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "strfuncs.h" #include "ioloop.h" #include "hostpid.h" #include "str-sanitize.h" #include "unichar.h" #include "istream.h" #include "istream-header-filter.h" #include "ostream.h" #include "smtp-params.h" #include "mail-storage.h" #include "message-date.h" #include "message-size.h" #include "rfc2822.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-result.h" #include "sieve-actions.h" #include "sieve-message.h" #include "sieve-smtp.h" /* * Action execution environment */ struct event_passthrough * sieve_action_create_finish_event(const struct sieve_action_exec_env *aenv) { struct event_passthrough *e = event_create_passthrough(aenv->event)-> set_name("sieve_action_finished"); return e; } /* * Action instance */ bool sieve_action_is_executed(const struct sieve_action *act, struct sieve_result *result) { unsigned int cur_exec_seq = sieve_result_get_exec_seq(result); i_assert(act->exec_seq <= cur_exec_seq); return (act->exec_seq < cur_exec_seq); } /* * Side-effect operand */ const struct sieve_operand_class sieve_side_effect_operand_class = { "SIDE-EFFECT" }; bool sieve_opr_side_effect_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct sieve_side_effect seffect; const struct sieve_side_effect_def *sdef; if (!sieve_opr_object_dump(denv, &sieve_side_effect_operand_class, address, &seffect.object)) return FALSE; sdef = seffect.def = (const struct sieve_side_effect_def *)seffect.object.def; if (sdef->dump_context != NULL) { sieve_code_descend(denv); if (!sdef->dump_context(&seffect, denv, address)) return FALSE; sieve_code_ascend(denv); } return TRUE; } int sieve_opr_side_effect_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_side_effect *seffect) { const struct sieve_side_effect_def *sdef; int ret; seffect->context = NULL; if (!sieve_opr_object_read(renv, &sieve_side_effect_operand_class, address, &seffect->object)) return SIEVE_EXEC_BIN_CORRUPT; sdef = seffect->def = (const struct sieve_side_effect_def *)seffect->object.def; if (sdef->read_context != NULL && (ret = sdef->read_context(seffect, renv, address, &seffect->context)) <= 0) return ret; return SIEVE_EXEC_OK; } /* * Optional operands */ int sieve_action_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code) { signed int _opt_code = 0; bool final = FALSE, opok = TRUE; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } while (opok) { int opt; opt = sieve_opr_optional_dump(denv, address, opt_code); if (opt <= 0) return opt; if (*opt_code == SIEVE_OPT_SIDE_EFFECT) opok = sieve_opr_side_effect_dump(denv, address); else return (final ? -1 : 1); } return -1; } int sieve_action_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code, int *exec_status, struct sieve_side_effects_list **list) { signed int _opt_code = 0; bool final = FALSE; int ret; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } if (exec_status != NULL) *exec_status = SIEVE_EXEC_OK; for (;;) { int opt; opt = sieve_opr_optional_read(renv, address, opt_code); if (opt <= 0) { if (opt < 0 && exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return opt; } if (*opt_code == SIEVE_OPT_SIDE_EFFECT) { struct sieve_side_effect seffect; i_assert(list != NULL); ret = sieve_opr_side_effect_read(renv, address, &seffect); if (ret <= 0) { if (exec_status != NULL) *exec_status = ret; return -1; } if (*list == NULL) { *list = sieve_side_effects_list_create( renv->result); } sieve_side_effects_list_add(*list, &seffect); } else { if (final) { sieve_runtime_trace_error( renv, "invalid optional operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } return 1; } } i_unreached(); } /* * Store action */ /* Forward declarations */ static bool act_store_equals(const struct sieve_script_env *senv, const struct sieve_action *act1, const struct sieve_action *act2); static int act_store_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_store_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_store_start(const struct sieve_action_exec_env *aenv, void **tr_context); static int act_store_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); static int act_store_commit(const struct sieve_action_exec_env *aenv, void *tr_context); static void act_store_rollback(const struct sieve_action_exec_env *aenv, void *tr_context, bool success); /* Action object */ const struct sieve_action_def act_store = { .name = "store", .flags = SIEVE_ACTFLAG_TRIES_DELIVER | SIEVE_ACTFLAG_MAIL_STORAGE, .equals = act_store_equals, .check_duplicate = act_store_check_duplicate, .print = act_store_print, .start = act_store_start, .execute = act_store_execute, .commit = act_store_commit, .rollback = act_store_rollback, }; /* API */ int sieve_act_store_add_to_result(const struct sieve_runtime_env *renv, const char *name, struct sieve_side_effects_list *seffects, const char *mailbox) { pool_t pool; struct act_store_context *act; /* Add redirect action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_store_context, 1); act->mailbox = p_strdup(pool, mailbox); return sieve_result_add_action(renv, NULL, name, &act_store, seffects, act, 0, TRUE); } void sieve_act_store_add_flags(const struct sieve_action_exec_env *aenv, void *tr_context, const char *const *keywords, enum mail_flags flags) { struct act_store_transaction *trans = (struct act_store_transaction *)tr_context; i_assert(trans != NULL); /* Assign mail keywords for subsequent mailbox_copy() */ if (*keywords != NULL) { const char *const *kw; if (!array_is_created(&trans->keywords)) { pool_t pool = sieve_result_pool(aenv->result); p_array_init(&trans->keywords, pool, 2); } kw = keywords; while (*kw != NULL) { array_append(&trans->keywords, kw, 1); kw++; } } /* Assign mail flags for subsequent mailbox_copy() */ trans->flags |= flags; trans->flags_altered = TRUE; } /* Equality */ static bool act_store_equals(const struct sieve_script_env *senv, const struct sieve_action *act1, const struct sieve_action *act2) { struct act_store_context *st_ctx1 = (act1 == NULL ? NULL : (struct act_store_context *)act1->context); struct act_store_context *st_ctx2 = (act2 == NULL ? NULL : (struct act_store_context *)act2->context); const char *mailbox1, *mailbox2; /* FIXME: consider namespace aliases */ if (st_ctx1 == NULL && st_ctx2 == NULL) return TRUE; mailbox1 = (st_ctx1 == NULL ? SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) : st_ctx1->mailbox); mailbox2 = (st_ctx2 == NULL ? SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) : st_ctx2->mailbox); if (strcmp(mailbox1, mailbox2) == 0) return TRUE; return (strcasecmp(mailbox1, "INBOX") == 0 && strcasecmp(mailbox2, "INBOX") == 0); } /* Result verification */ static int act_store_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other) { const struct sieve_execute_env *eenv = renv->exec_env; return (act_store_equals(eenv->scriptenv, act, act_other) ? 1 : 0); } /* Result printing */ static void act_store_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep) { struct act_store_context *ctx = (struct act_store_context *)action->context; const char *mailbox; mailbox = (ctx == NULL ? SIEVE_SCRIPT_DEFAULT_MAILBOX(rpenv->scriptenv) : ctx->mailbox); sieve_result_action_printf(rpenv, "store message in folder: %s", str_sanitize(mailbox, 128)); *keep = FALSE; } /* Action implementation */ void sieve_act_store_get_storage_error(const struct sieve_action_exec_env *aenv, struct act_store_transaction *trans) { pool_t pool = sieve_result_pool(aenv->result); trans->error = p_strdup(pool, mailbox_get_last_internal_error(trans->box, &trans->error_code)); } static bool act_store_mailbox_alloc(const struct sieve_action_exec_env *aenv, const char *mailbox, struct mailbox **box_r, enum mail_error *error_code_r, const char **error_r) { const struct sieve_execute_env *eenv = aenv->exec_env; struct mailbox *box; struct mail_storage **storage = &(eenv->exec_status->last_storage); enum mailbox_flags flags = MAILBOX_FLAG_POST_SESSION; *box_r = NULL; *error_code_r = MAIL_ERROR_NONE; *error_r = NULL; if (!uni_utf8_str_is_valid(mailbox)) { /* Just a precaution; already (supposed to be) checked at compiletime/runtime. */ *error_r = t_strdup_printf("mailbox name not utf-8: %s", mailbox); *error_code_r = MAIL_ERROR_PARAMS; return FALSE; } if (eenv->scriptenv->mailbox_autocreate) flags |= MAILBOX_FLAG_AUTO_CREATE; if (eenv->scriptenv->mailbox_autosubscribe) flags |= MAILBOX_FLAG_AUTO_SUBSCRIBE; *box_r = box = mailbox_alloc_for_user(eenv->scriptenv->user, mailbox, flags); *storage = mailbox_get_storage(box); return TRUE; } static int act_store_start(const struct sieve_action_exec_env *aenv, void **tr_context) { const struct sieve_action *action = aenv->action; struct act_store_context *ctx = (struct act_store_context *)action->context; const struct sieve_execute_env *eenv = aenv->exec_env; const struct sieve_script_env *senv = eenv->scriptenv; struct act_store_transaction *trans; struct mailbox *box = NULL; pool_t pool = sieve_result_pool(aenv->result); const char *error = NULL; enum mail_error error_code = MAIL_ERROR_NONE; bool disabled = FALSE, alloc_failed = FALSE; /* If context is NULL, the store action is the result of (implicit) keep. */ if (ctx == NULL) { ctx = p_new(pool, struct act_store_context, 1); ctx->mailbox = p_strdup(pool, SIEVE_SCRIPT_DEFAULT_MAILBOX(senv)); } e_debug(aenv->event, "Start storing into mailbox %s", ctx->mailbox); /* Open the requested mailbox */ /* NOTE: The caller of the sieve library is allowed to leave user set to NULL. This implementation will then skip actually storing the message. */ if (senv->user != NULL) { if (!act_store_mailbox_alloc(aenv, ctx->mailbox, &box, &error_code, &error)) alloc_failed = TRUE; } else { disabled = TRUE; } /* Create transaction context */ trans = p_new(pool, struct act_store_transaction, 1); trans->context = ctx; trans->box = box; trans->flags = 0; trans->mailbox_name = ctx->mailbox; trans->mailbox_identifier = p_strdup_printf(pool, "'%s'", str_sanitize(ctx->mailbox, 256)); trans->disabled = disabled; if (alloc_failed) { trans->error = p_strdup(pool, error); trans->error_code = error_code; e_debug(aenv->event, "Failed to open mailbox %s: %s", trans->mailbox_identifier, trans->error); } else { trans->error_code = MAIL_ERROR_NONE; } *tr_context = trans; switch (trans->error_code) { case MAIL_ERROR_NONE: case MAIL_ERROR_NOTFOUND: return SIEVE_EXEC_OK; case MAIL_ERROR_TEMP: return SIEVE_EXEC_TEMP_FAILURE; default: break; } return SIEVE_EXEC_FAILURE; } static struct mail_keywords * act_store_keywords_create(const struct sieve_action_exec_env *aenv, ARRAY_TYPE(const_string) *keywords, struct mailbox *box, bool create_empty) { struct mail_keywords *box_keywords = NULL; const char *const *kwds = NULL; if (!array_is_created(keywords) || array_count(keywords) == 0) { if (!create_empty) return NULL; } else { ARRAY_TYPE(const_string) valid_keywords; const char *error; unsigned int count, i; kwds = array_get(keywords, &count); t_array_init(&valid_keywords, count); for (i = 0; i < count; i++) { if (mailbox_keyword_is_valid(box, kwds[i], &error)) { array_append(&valid_keywords, &kwds[i], 1); continue; } sieve_result_warning(aenv, "specified IMAP keyword '%s' is invalid " "(ignored): %s", str_sanitize(kwds[i], 64), sieve_error_from_external(error)); } array_append_zero(keywords); kwds = array_idx(keywords, 0); } if (mailbox_keywords_create(box, kwds, &box_keywords) < 0) { sieve_result_error( aenv, "invalid keywords set for stored message"); return NULL; } return box_keywords; } static bool have_equal_keywords(struct mail *mail, struct mail_keywords *new_kw) { const ARRAY_TYPE(keyword_indexes) *old_kw_arr = mail_get_keyword_indexes(mail); const unsigned int *old_kw; unsigned int i, j; if (array_count(old_kw_arr) != new_kw->count) return FALSE; if (new_kw->count == 0) return TRUE; old_kw = array_front(old_kw_arr); for (i = 0; i < new_kw->count; i++) { /* new_kw->count equals old_kw's count and it's easier to use */ for (j = 0; j < new_kw->count; j++) { if (old_kw[j] == new_kw->idx[i]) break; } if (j == new_kw->count) return FALSE; } return TRUE; } static int act_store_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep) { const struct sieve_action *action = aenv->action; const struct sieve_execute_env *eenv = aenv->exec_env; struct act_store_transaction *trans = (struct act_store_transaction *)tr_context; struct mail *mail = (action->mail != NULL ? action->mail : eenv->msgdata->mail); struct mail_save_context *save_ctx; struct mail_keywords *keywords = NULL; struct mailbox *box; bool backends_equal = FALSE; int status = SIEVE_EXEC_OK; /* Verify transaction */ if (trans == NULL) return SIEVE_EXEC_FAILURE; box = trans->box; /* Check whether we need to do anything */ if (trans->disabled) { e_debug(aenv->event, "Skip storing into mailbox %s", trans->mailbox_identifier); *keep = FALSE; return SIEVE_EXEC_OK; } /* Exit early if mailbox is not available */ if (box == NULL) return SIEVE_EXEC_FAILURE; e_debug(aenv->event, "Execute storing into mailbox %s", trans->mailbox_identifier); /* Mark attempt to use storage. Can only get here when all previous actions succeeded. */ eenv->exec_status->last_storage = mailbox_get_storage(box); /* Open the mailbox (may already be open) */ if (trans->error_code == MAIL_ERROR_NONE) { if (mailbox_open(box) < 0) { sieve_act_store_get_storage_error(aenv, trans); e_debug(aenv->event, "Failed to open mailbox %s: %s", trans->mailbox_identifier, trans->error); } } /* Exit early if transaction already failed */ switch (trans->error_code) { case MAIL_ERROR_NONE: break; case MAIL_ERROR_TEMP: return SIEVE_EXEC_TEMP_FAILURE; default: return SIEVE_EXEC_FAILURE; } /* If the message originates from the target mailbox, only update the flags and keywords (if not read-only) */ if (mailbox_backends_equal(box, mail->box)) { backends_equal = TRUE; } else { struct mail *real_mail; if (mail_get_backend_mail(mail, &real_mail) < 0) return SIEVE_EXEC_FAILURE; if (real_mail != mail && mailbox_backends_equal(box, real_mail->box)) backends_equal = TRUE; } if (backends_equal) { trans->redundant = TRUE; if (trans->flags_altered && !mailbox_is_readonly(mail->box)) { keywords = act_store_keywords_create( aenv, &trans->keywords, mail->box, TRUE); if (keywords != NULL) { if (!have_equal_keywords(mail, keywords)) { eenv->exec_status->significant_action_executed = TRUE; mail_update_keywords(mail, MODIFY_REPLACE, keywords); } mailbox_keywords_unref(&keywords); } if ((mail_get_flags(mail) & MAIL_FLAGS_NONRECENT) != trans->flags) { eenv->exec_status->significant_action_executed = TRUE; mail_update_flags(mail, MODIFY_REPLACE, trans->flags); } } e_debug(aenv->event, "Updated existing mail in mailbox %s", trans->mailbox_identifier); return SIEVE_EXEC_OK; /* If the message is modified, only store it in the source mailbox when it is not opened read-only. Mail structs of modified messages have their own mailbox, unrelated to the orignal mail, so this case needs to be handled separately. */ } else if (mail != eenv->msgdata->mail && mailbox_is_readonly(eenv->msgdata->mail->box) && (mailbox_backends_equal(box, eenv->msgdata->mail->box))) { e_debug(aenv->event, "Not modifying exsiting mail in read-only mailbox %s", trans->mailbox_identifier); trans->redundant = TRUE; return SIEVE_EXEC_OK; } /* Mark attempt to store in default mailbox */ if (strcmp(trans->context->mailbox, SIEVE_SCRIPT_DEFAULT_MAILBOX(eenv->scriptenv)) == 0) eenv->exec_status->tried_default_save = TRUE; /* Start mail transaction */ trans->mail_trans = mailbox_transaction_begin( box, MAILBOX_TRANSACTION_FLAG_EXTERNAL, __func__); /* Store the message */ save_ctx = mailbox_save_alloc(trans->mail_trans); /* Apply keywords and flags that side-effects may have added */ if (trans->flags_altered) { keywords = act_store_keywords_create(aenv, &trans->keywords, box, FALSE); if (trans->flags != 0 || keywords != NULL) { eenv->exec_status->significant_action_executed = TRUE; mailbox_save_set_flags(save_ctx, trans->flags, keywords); } } else { mailbox_save_copy_flags(save_ctx, mail); } if (mailbox_save_using_mail(&save_ctx, mail) < 0) { sieve_act_store_get_storage_error(aenv, trans); e_debug(aenv->event, "Failed to save to mailbox %s: %s", trans->mailbox_identifier, trans->error); status = (trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } else { e_debug(aenv->event, "Saving to mailbox %s successful so far", trans->mailbox_identifier); eenv->exec_status->significant_action_executed = TRUE; } /* Deallocate keywords */ if (keywords != NULL) mailbox_keywords_unref(&keywords); /* Cancel implicit keep if all went well so far */ *keep = (status < SIEVE_EXEC_OK); return status; } static void act_store_log_status(struct act_store_transaction *trans, const struct sieve_action_exec_env *aenv, bool rolled_back, bool status) { const char *mailbox_name = trans->mailbox_name; const char *mailbox_identifier = trans->mailbox_identifier; if (trans->box != NULL) { const char *mailbox_vname = str_sanitize(mailbox_get_vname(trans->box), 128); if (strcmp(trans->mailbox_name, mailbox_vname) != 0) { mailbox_identifier = t_strdup_printf( "%s (%s)", mailbox_identifier, str_sanitize(mailbox_vname, 256)); } } /* Store disabled? */ if (trans->disabled) { sieve_result_global_log(aenv, "store into mailbox %s skipped", mailbox_identifier); /* Store redundant? */ } else if (trans->redundant) { sieve_result_global_log(aenv, "left message in mailbox %s", mailbox_identifier); /* Store failed? */ } else if (!status) { const char *errstr; enum mail_error error_code; if (trans->error == NULL) sieve_act_store_get_storage_error(aenv, trans); errstr = trans->error; error_code = trans->error_code; if (error_code == MAIL_ERROR_NOQUOTA) { /* Never log quota problems as error in global log */ sieve_result_global_log_error( aenv, "failed to store into mailbox %s: %s", mailbox_identifier, errstr); } else if (error_code == MAIL_ERROR_NOTFOUND || error_code == MAIL_ERROR_PARAMS || error_code == MAIL_ERROR_PERM) { sieve_result_error( aenv, "failed to store into mailbox %s: %s", mailbox_identifier, errstr); } else { sieve_result_global_error( aenv, "failed to store into mailbox %s: %s", mailbox_identifier, errstr); } /* Store aborted? */ } else if (rolled_back) { if (!aenv->action->keep) { sieve_result_global_log( aenv, "store into mailbox %s aborted", mailbox_identifier); } else { e_debug(aenv->event, "Store into mailbox %s aborted", mailbox_identifier); } /* Succeeded */ } else { struct event_passthrough *e = sieve_action_create_finish_event(aenv)-> add_str("fileinto_mailbox_name", mailbox_name)-> add_str("fileinto_mailbox", mailbox_identifier); sieve_result_event_log(aenv, e->event(), "stored mail into mailbox %s", mailbox_identifier); } } static void act_store_cleanup(struct act_store_transaction *trans) { if (trans->mail_trans != NULL) mailbox_transaction_rollback(&trans->mail_trans); if (trans->box != NULL) mailbox_free(&trans->box); } static int act_store_commit(const struct sieve_action_exec_env *aenv, void *tr_context) { const struct sieve_execute_env *eenv = aenv->exec_env; struct act_store_transaction *trans = (struct act_store_transaction *)tr_context; bool bail_out = FALSE, status = TRUE; int ret = SIEVE_EXEC_OK; /* Verify transaction */ if (trans == NULL) return SIEVE_EXEC_FAILURE; e_debug(aenv->event, "Commit storing into mailbox %s", trans->mailbox_identifier); /* Check whether we can commit this transaction */ if (trans->error_code != MAIL_ERROR_NONE) { /* Transaction already failed */ bail_out = TRUE; status = FALSE; if (trans->error_code == MAIL_ERROR_TEMP) ret = SIEVE_EXEC_TEMP_FAILURE; else ret = SIEVE_EXEC_FAILURE; /* Check whether we need to do anything */ } else if (trans->disabled) { /* Nothing to do */ bail_out = TRUE; } else if (trans->redundant) { /* This transaction is redundant */ bail_out = TRUE; eenv->exec_status->keep_original = TRUE; eenv->exec_status->message_saved = TRUE; } if (bail_out) { act_store_log_status(trans, aenv, FALSE, status); act_store_cleanup(trans); return ret; } i_assert(trans->box != NULL); i_assert(trans->mail_trans != NULL); /* Mark attempt to use storage. Can only get here when all previous actions succeeded. */ eenv->exec_status->last_storage = mailbox_get_storage(trans->box); /* Commit mailbox transaction */ status = (mailbox_transaction_commit(&trans->mail_trans) == 0); /* Note the fact that the message was stored at least once */ if (status) eenv->exec_status->message_saved = TRUE; else eenv->exec_status->store_failed = TRUE; /* Log our status */ act_store_log_status(trans, aenv, FALSE, status); /* Clean up */ act_store_cleanup(trans); if (status) return SIEVE_EXEC_OK; return (trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } static void act_store_rollback(const struct sieve_action_exec_env *aenv, void *tr_context, bool success) { const struct sieve_execute_env *eenv = aenv->exec_env; struct act_store_transaction *trans = (struct act_store_transaction *)tr_context; if (trans == NULL) return; e_debug(aenv->event, "Roll back storing into mailbox %s", trans->mailbox_identifier); i_assert(trans->box != NULL); if (!success) { eenv->exec_status->last_storage = mailbox_get_storage(trans->box); eenv->exec_status->store_failed = TRUE; } /* Log status */ act_store_log_status(trans, aenv, TRUE, success); /* Rollback mailbox transaction and clean up */ act_store_cleanup(trans); } /* * Redirect action */ int sieve_act_redirect_add_to_result(const struct sieve_runtime_env *renv, const char *name, struct sieve_side_effects_list *seffects, const struct smtp_address *to_address) { const struct sieve_execute_env *eenv = renv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct act_redirect_context *act; pool_t pool; pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_redirect_context, 1); act->to_address = smtp_address_clone(pool, to_address); if (sieve_result_add_action(renv, NULL, name, &act_redirect, seffects, act, svinst->set->max_redirects, TRUE) < 0) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } /* * Action utility functions */ /* Rejecting the mail */ static int sieve_action_do_reject_mail(const struct sieve_action_exec_env *aenv, const struct smtp_address *recipient, const char *reason) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_instance *svinst = eenv->svinst; const struct sieve_script_env *senv = eenv->scriptenv; const struct sieve_message_data *msgdata = eenv->msgdata; const struct smtp_address *sender, *orig_recipient; struct istream *input; struct ostream *output; struct sieve_smtp_context *sctx; const char *new_msgid, *boundary, *error; string_t *hdr; int ret; sender = sieve_message_get_sender(aenv->msgctx); orig_recipient = msgdata->envelope.rcpt_params->orcpt.addr; sctx = sieve_smtp_start_single(senv, sender, NULL, &output); /* Just to be sure */ if (sctx == NULL) { sieve_result_global_warning( aenv, "reject action has no means to send mail"); return SIEVE_EXEC_OK; } new_msgid = sieve_message_get_new_id(svinst); boundary = t_strdup_printf("%s/%s", my_pid, svinst->hostname); hdr = t_str_new(512); rfc2822_header_write(hdr, "X-Sieve", SIEVE_IMPLEMENTATION); rfc2822_header_write(hdr, "Message-ID", new_msgid); rfc2822_header_write(hdr, "Date", message_date_create(ioloop_time)); rfc2822_header_write(hdr, "From", sieve_get_postmaster_address(senv)); rfc2822_header_printf(hdr, "To", "<%s>", smtp_address_encode(sender)); rfc2822_header_write(hdr, "Subject", "Automatically rejected mail"); rfc2822_header_write(hdr, "Auto-Submitted", "auto-replied (rejected)"); rfc2822_header_write(hdr, "Precedence", "bulk"); rfc2822_header_write(hdr, "MIME-Version", "1.0"); rfc2822_header_printf(hdr, "Content-Type", "multipart/report; " "report-type=disposition-notification;\r\n" "boundary=\"%s\"", boundary); str_append(hdr, "\r\nThis is a MIME-encapsulated message\r\n\r\n"); /* Human readable status report */ str_printfa(hdr, "--%s\r\n", boundary); rfc2822_header_write(hdr, "Content-Type", "text/plain; charset=utf-8"); rfc2822_header_write(hdr, "Content-Disposition", "inline"); rfc2822_header_write(hdr, "Content-Transfer-Encoding", "8bit"); str_printfa(hdr, "\r\nYour message to <%s> was automatically rejected:\r\n" "%s\r\n", smtp_address_encode(recipient), reason); /* MDN status report */ str_printfa(hdr, "--%s\r\n", boundary); rfc2822_header_write(hdr, "Content-Type", "message/disposition-notification"); str_append(hdr, "\r\n"); rfc2822_header_write(hdr, "Reporting-UA: %s; Dovecot Mail Delivery Agent", svinst->hostname); if (orig_recipient != NULL) { rfc2822_header_printf(hdr, "Original-Recipient", "rfc822; %s", smtp_address_encode(orig_recipient)); } rfc2822_header_printf(hdr, "Final-Recipient", "rfc822; %s", smtp_address_encode(recipient)); if (msgdata->id != NULL) rfc2822_header_write(hdr, "Original-Message-ID", msgdata->id); rfc2822_header_write(hdr, "Disposition", "automatic-action/MDN-sent-automatically; deleted"); str_append(hdr, "\r\n"); /* original message's headers */ str_printfa(hdr, "--%s\r\n", boundary); rfc2822_header_write(hdr, "Content-Type", "message/rfc822"); str_append(hdr, "\r\n"); o_stream_nsend(output, str_data(hdr), str_len(hdr)); if (mail_get_hdr_stream(msgdata->mail, NULL, &input) == 0) { /* NOTE: If you add more headers, they need to be sorted. We'll drop Content-Type because we're not including the message body, and having a multipart Content-Type may confuse some MIME parsers when they don't see the message boundaries. */ static const char *const exclude_headers[] = { "Content-Type" }; input = i_stream_create_header_filter( input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, exclude_headers, N_ELEMENTS(exclude_headers), *null_header_filter_callback, NULL); o_stream_nsend_istream(output, input); i_stream_unref(&input); } str_truncate(hdr, 0); str_printfa(hdr, "\r\n\r\n--%s--\r\n", boundary); o_stream_nsend(output, str_data(hdr), str_len(hdr)); if ((ret = sieve_smtp_finish(sctx, &error)) <= 0) { if (ret < 0) { sieve_result_global_error(aenv, "failed to send rejection message to <%s>: %s " "(temporary failure)", smtp_address_encode(sender), str_sanitize(error, 512)); } else { sieve_result_global_log_error(aenv, "failed to send rejection message to <%s>: %s " "(permanent failure)", smtp_address_encode(sender), str_sanitize(error, 512)); } return SIEVE_EXEC_FAILURE; } return SIEVE_EXEC_OK; } int sieve_action_reject_mail(const struct sieve_action_exec_env *aenv, const struct smtp_address *recipient, const char *reason) { const struct sieve_execute_env *eenv = aenv->exec_env; const struct sieve_script_env *senv = eenv->scriptenv; int result; T_BEGIN { if (senv->reject_mail != NULL) { result = (senv->reject_mail(senv, recipient, reason) >= 0 ? SIEVE_EXEC_OK : SIEVE_EXEC_FAILURE); } else { result = sieve_action_do_reject_mail(aenv, recipient, reason); } } T_END; return result; } /* * Mailbox */ bool sieve_mailbox_check_name(const char *mailbox, const char **error_r) { if (!uni_utf8_str_is_valid(mailbox)) { *error_r = "invalid utf-8"; return FALSE; } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/ext-encoded-character.c0000644000175100001700000001340615100335616025746 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension encoded-character * --------------------------- * * Authors: Stephan Bosch * Specification: RFC 5228 * Implementation: full * Status: testing * */ #include "lib.h" #include "unichar.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include /* * Extension */ static bool ext_encoded_character_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def encoded_character_extension = { .name = "encoded-character", .validator_load = ext_encoded_character_validator_load, }; /* * Encoded string argument */ bool arg_encoded_string_validate (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *context); const struct sieve_argument_def encoded_string_argument = { .identifier = "@encoded-string", .validate = arg_encoded_string_validate }; /* Parsing */ static bool _skip_whitespace (const char **in, const char *inend) { while ( *in < inend ) { if ( **in == '\r' ) { (*in)++; if ( **in != '\n' ) return FALSE; continue; } /* (Loose LF is non-standard) */ if ( **in != ' ' && **in != '\n' && **in != '\t' ) break; (*in)++; } return TRUE; } static bool _parse_hexint (const char **in, const char *inend, int max_digits, unsigned int *result) { int digit = 0; *result = 0; while ( *in < inend && (max_digits == 0 || digit < max_digits) ) { if ( (**in) >= '0' && (**in) <= '9' ) *result = ((*result) << 4) + (**in) - ((unsigned int) '0'); else if ( (**in) >= 'a' && (**in) <= 'f' ) *result = ((*result) << 4) + (**in) - ((unsigned int) 'a') + 0x0a; else if ( (**in) >= 'A' && (**in) <= 'F' ) *result = ((*result) << 4) + (**in) - ((unsigned int) 'A') + 0x0a; else return ( digit > 0 ); (*in)++; digit++; } if ( digit == max_digits ) { /* Hex digit _MUST_ end here */ if ( (**in >= '0' && **in <= '9') || (**in >= 'a' && **in <= 'f') || (**in >= 'A' && **in <= 'F') ) return FALSE; return TRUE; } return ( digit > 0 ); } static bool _decode_hex (const char **in, const char *inend, string_t *result) { int values = 0; while ( *in < inend ) { unsigned int hexpair; if ( !_skip_whitespace(in, inend) ) return FALSE; if ( !_parse_hexint(in, inend, 2, &hexpair) ) break; str_append_c(result, (unsigned char) hexpair); values++; } return ( values > 0 ); } static bool _decode_unicode (const char **in, const char *inend, string_t *result, unsigned int *error_hex) { int values = 0; bool valid = TRUE; while ( *in < inend ) { unsigned int unicode_hex; if ( !_skip_whitespace(in, inend) ) return FALSE; if ( !_parse_hexint(in, inend, 0, &unicode_hex) ) break; if ( uni_is_valid_ucs4((unichar_t) unicode_hex) ) uni_ucs4_to_utf8_c((unichar_t) unicode_hex, result); else { if ( valid ) *error_hex = unicode_hex; valid = FALSE; } values++; } return ( values > 0 ); } bool arg_encoded_string_validate (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { bool result = TRUE; enum { ST_NONE, ST_OPEN, ST_TYPE, ST_CLOSE } state = ST_NONE; string_t *str = sieve_ast_argument_str(*arg); string_t *tmpstr, *newstr = NULL; const char *p, *mark, *strstart, *substart = NULL; const char *strval = (const char *) str_data(str); const char *strend = strval + str_len(str); unsigned int error_hex = 0; T_BEGIN { tmpstr = t_str_new(32); p = strval; strstart = p; while ( result && p < strend ) { switch ( state ) { /* Normal string */ case ST_NONE: if ( *p == '$' ) { substart = p; state = ST_OPEN; } p++; break; /* Parsed '$' */ case ST_OPEN: if ( *p == '{' ) { state = ST_TYPE; p++; } else state = ST_NONE; break; /* Parsed '${' */ case ST_TYPE: mark = p; /* Scan for 'hex' or 'unicode' */ while ( p < strend && i_isalpha(*p) ) p++; if ( *p != ':' ) { state = ST_NONE; break; } state = ST_CLOSE; str_truncate(tmpstr, 0); if ( strncasecmp(mark, "hex", p - mark) == 0 ) { /* Hexadecimal */ p++; if ( !_decode_hex(&p, strend, tmpstr) ) state = ST_NONE; } else if ( strncasecmp(mark, "unicode", p - mark) == 0 ) { /* Unicode */ p++; if ( !_decode_unicode(&p, strend, tmpstr, &error_hex) ) state = ST_NONE; } else { /* Invalid encoding */ p++; state = ST_NONE; } break; case ST_CLOSE: if ( *p == '}' ) { /* We now know that the substitution is valid */ if ( error_hex != 0 ) { sieve_argument_validate_error(valdtr, *arg, "invalid unicode character 0x%08x in encoded character substitution", error_hex); result = FALSE; break; } if ( newstr == NULL ) { newstr = str_new(sieve_ast_pool((*arg)->ast), str_len(str)*2); } str_append_data(newstr, strstart, substart-strstart); str_append_str(newstr, tmpstr); strstart = p + 1; substart = strstart; p++; } state = ST_NONE; } } } T_END; if ( !result ) return FALSE; if ( newstr != NULL ) { if ( strstart != strend ) str_append_data(newstr, strstart, strend-strstart); sieve_ast_argument_string_set(*arg, newstr); } /* Pass the processed string to a (possible) next layer of processing */ return sieve_validator_argument_activate_super (valdtr, cmd, *arg, TRUE); } /* * Extension implementation */ static bool ext_encoded_character_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Override the constant string argument with our own */ sieve_validator_argument_override (valdtr, SAT_CONST_STRING, ext, &encoded_string_argument); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-address.c0000644000175100001700000003327515100335616024361 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "rfc822-parser.h" #include "message-address.h" #include "sieve-common.h" #include "sieve-runtime-trace.h" #include "sieve-address.h" #include /* * Header address list */ /* Forward declarations */ static int sieve_header_address_list_next_string_item(struct sieve_stringlist *_strlist, string_t **str_r); static int sieve_header_address_list_next_item(struct sieve_address_list *_addrlist, struct smtp_address *addr_r, string_t **unparsed_r); static void sieve_header_address_list_reset(struct sieve_stringlist *_strlist); static void sieve_header_address_list_set_trace(struct sieve_stringlist *_strlist, bool trace); /* Stringlist object */ struct sieve_header_address_list { struct sieve_address_list addrlist; struct sieve_stringlist *field_values; const struct message_address *cur_address; }; struct sieve_address_list * sieve_header_address_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_values) { struct sieve_header_address_list *addrlist; addrlist = t_new(struct sieve_header_address_list, 1); addrlist->addrlist.strlist.runenv = renv; addrlist->addrlist.strlist.exec_status = SIEVE_EXEC_OK; addrlist->addrlist.strlist.next_item = sieve_header_address_list_next_string_item; addrlist->addrlist.strlist.reset = sieve_header_address_list_reset; addrlist->addrlist.strlist.set_trace = sieve_header_address_list_set_trace; addrlist->addrlist.next_item = sieve_header_address_list_next_item; addrlist->field_values = field_values; return &addrlist->addrlist; } static int sieve_header_address_list_next_address( struct sieve_header_address_list *addrlist, struct smtp_address *addr_r) { struct smtp_address adummy; int ret = 0; if (addr_r == NULL) addr_r = &adummy; while (addrlist->cur_address != NULL) { const struct message_address *aitem = addrlist->cur_address; addrlist->cur_address = addrlist->cur_address->next; if (!aitem->invalid_syntax && aitem->domain != NULL && smtp_address_init_from_msg(addr_r, aitem) >= 0) return 1; ret = -1; } return ret; } static int sieve_header_address_list_next_item(struct sieve_address_list *_addrlist, struct smtp_address *addr_r, string_t **unparsed_r) { struct sieve_header_address_list *addrlist = (struct sieve_header_address_list *)_addrlist; const struct sieve_runtime_env *runenv = _addrlist->strlist.runenv; string_t *value_item = NULL; bool trace = _addrlist->strlist.trace; if (addr_r != NULL) smtp_address_init(addr_r, NULL, NULL); if (unparsed_r != NULL) *unparsed_r = NULL; for (;;) { int ret; if ((ret = sieve_header_address_list_next_address( addrlist, addr_r)) < 0 && value_item != NULL) { /* completely invalid address list is returned as-is */ if (trace) { sieve_runtime_trace( runenv, 0, "invalid address value '%s'", str_sanitize(str_c(value_item), 80)); } if (unparsed_r != NULL) *unparsed_r = value_item; return 1; } if (ret > 0) { if (trace) { sieve_runtime_trace( runenv, 0, "address value '%s'", str_sanitize(smtp_address_encode(addr_r), 80)); } return 1; } /* Read next header value from source list */ if ((ret = sieve_stringlist_next_item(addrlist->field_values, &value_item)) <= 0) return ret; if (str_len(value_item) == 0) { /* empty header value is returned as-is */ if (trace) { sieve_runtime_trace(runenv, 0, "empty address value"); } addrlist->cur_address = NULL; if (unparsed_r != NULL) *unparsed_r = value_item; return 1; } if (trace) { sieve_runtime_trace( runenv, 0, "parsing address header value '%s'", str_sanitize(str_c(value_item), 80)); } addrlist->cur_address = message_address_parse( pool_datastack_create(), (const unsigned char *)str_data(value_item), str_len(value_item), 256, 0); } i_unreached(); } static int sieve_header_address_list_next_string_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct sieve_address_list *addrlist = (struct sieve_address_list *)_strlist; struct smtp_address addr; int ret; if ((ret = sieve_header_address_list_next_item( addrlist, &addr, str_r)) <= 0) return ret; if (addr.localpart != NULL) { const char *addr_str = smtp_address_encode(&addr); if (str_r != NULL) *str_r = t_str_new_const(addr_str, strlen(addr_str)); } return 1; } static void sieve_header_address_list_reset(struct sieve_stringlist *_strlist) { struct sieve_header_address_list *addrlist = (struct sieve_header_address_list *)_strlist; sieve_stringlist_reset(addrlist->field_values); addrlist->cur_address = NULL; } static void sieve_header_address_list_set_trace(struct sieve_stringlist *_strlist, bool trace) { struct sieve_header_address_list *addrlist = (struct sieve_header_address_list *)_strlist; sieve_stringlist_set_trace(addrlist->field_values, trace); } /* * RFC 2822 addresses */ /* Mail message address according to RFC 2822 and implemented in the Dovecot message address parser: address = mailbox / group mailbox = name-addr / addr-spec name-addr = [display-name] angle-addr angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr group = display-name ":" [mailbox-list / CFWS] ";" [CFWS] display-name = phrase addr-spec = local-part "@" domain local-part = dot-atom / quoted-string / obs-local-part domain = dot-atom / domain-literal / obs-domain domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS] dcontent = dtext / quoted-pair dtext = NO-WS-CTL / ; Non white space controls %d33-90 / ; The rest of the US-ASCII %d94-126 ; characters not including "[", ; "]", or "\" atext = ALPHA / DIGIT / ; Any character except controls, "!" / "#" / ; SP, and specials. "$" / "%" / ; Used for atoms "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" atom = [CFWS] 1*atext [CFWS] dot-atom = [CFWS] dot-atom-text [CFWS] dot-atom-text = 1*atext *("." 1*atext) word = atom / quoted-string phrase = 1*word / obs-phrase Message address specification as allowed bij the RFC 5228 SIEVE specification: sieve-address = addr-spec ; simple address / phrase "<" addr-spec ">" ; name & addr-spec\ Which concisely is about equal to: sieve-address = mailbox */ /* * Address parse context */ struct sieve_message_address_parser { struct rfc822_parser_context parser; string_t *str; string_t *local_part; string_t *domain; string_t *error; }; /* * Error handling */ static inline void ATTR_FORMAT(2, 3) sieve_address_error(struct sieve_message_address_parser *ctx, const char *fmt, ...) { va_list args; if (str_len(ctx->error) == 0) { va_start(args, fmt); str_vprintfa(ctx->error, fmt, args); va_end(args); } } /* Partial RFC 2822 address parser FIXME: lots of overlap with dovecot/src/lib-mail/message-parser.c --> this implementation adds textual error reporting MERGE! */ static int check_local_part(struct sieve_message_address_parser *ctx) { const unsigned char *p, *pend; p = str_data(ctx->local_part); pend = p + str_len(ctx->local_part); while (p < pend) { if (*p < 0x20 || *p > 0x7e) return -1; p++; } return 0; } static int parse_local_part(struct sieve_message_address_parser *ctx) { int ret; /* local-part = dot-atom / quoted-string / obs-local-part obs-local-part = word *("." word) */ if (ctx->parser.data == ctx->parser.end) { sieve_address_error(ctx, "empty local part"); return -1; } str_truncate(ctx->local_part, 0); if (*ctx->parser.data == '"') { ret = rfc822_parse_quoted_string(&ctx->parser, ctx->local_part); } else { ret = -1; /* NOTE: this deviates from dot-atom syntax to allow some Japanese mail addresses with dots at non-standard places to be accepted. */ do { while (*ctx->parser.data == '.') { str_append_c(ctx->local_part, '.'); ctx->parser.data++; if (ctx->parser.data == ctx->parser.end) { /* @domain is missing, but local-part parsing was successful */ return 0; } ret = 1; } if (*ctx->parser.data == '@') break; ret = rfc822_parse_atom(&ctx->parser, ctx->local_part); } while (ret > 0 && *ctx->parser.data == '.'); } if (ret < 0 || check_local_part(ctx) < 0) { sieve_address_error(ctx, "invalid local part"); return -1; } return ret; } static int parse_domain(struct sieve_message_address_parser *ctx) { int ret; str_truncate(ctx->domain, 0); if ((ret = rfc822_parse_domain(&ctx->parser, ctx->domain)) < 0) { sieve_address_error(ctx, "invalid or missing domain"); return -1; } return ret; } static int parse_addr_spec(struct sieve_message_address_parser *ctx) { /* addr-spec = local-part "@" domain */ int ret; if ((ret = parse_local_part(ctx)) < 0) return ret; if (ret > 0 && *ctx->parser.data == '@') { return parse_domain(ctx); } sieve_address_error( ctx, "invalid or lonely local part '%s' (expecting '@')", str_sanitize(str_c(ctx->local_part), 80)); return -1; } static int parse_mailbox(struct sieve_message_address_parser *ctx) { int ret; const unsigned char *start; /* sieve-address = addr-spec ; simple address / phrase "<" addr-spec ">" ; name & addr-spec */ /* Record parser state in case we fail at our first attempt */ start = ctx->parser.data; /* First try: phrase "<" addr-spec ">" ; name & addr-spec */ str_truncate(ctx->str, 0); if (rfc822_parse_phrase(&ctx->parser, ctx->str) <= 0 || *ctx->parser.data != '<') { /* Failed; try just bare addr-spec */ ctx->parser.data = start; return parse_addr_spec(ctx); } /* "<" addr-spec ">" */ ctx->parser.data++; if ((ret = rfc822_skip_lwsp(&ctx->parser)) <= 0) { if (ret < 0) sieve_address_error(ctx, "invalid characters after <"); return ret; } if (parse_addr_spec(ctx) < 0) return -1; if (*ctx->parser.data != '>') { sieve_address_error(ctx, "missing '>'"); return -1; } ctx->parser.data++; if ((ret = rfc822_skip_lwsp(&ctx->parser)) < 0) { sieve_address_error( ctx, "address ends with invalid characters"); } return ret; } static bool parse_mailbox_address(struct sieve_message_address_parser *ctx, const unsigned char *address, unsigned int addr_size) { /* Initialize parser */ rfc822_parser_init(&ctx->parser, address, addr_size, NULL); /* Parse */ rfc822_skip_lwsp(&ctx->parser); if (ctx->parser.data == ctx->parser.end) { sieve_address_error(ctx, "empty address"); return FALSE; } if (parse_mailbox(ctx) < 0) return FALSE; if (ctx->parser.data != ctx->parser.end) { if (*ctx->parser.data == ',') { sieve_address_error( ctx, "not a single address (found ',')"); } else { sieve_address_error( ctx, "address ends in invalid characters"); } return FALSE; } if (str_len(ctx->domain) == 0) { /* Not gonna happen */ sieve_address_error(ctx, "missing domain"); return FALSE; } if (str_len(ctx->local_part) == 0) { sieve_address_error(ctx, "missing local part"); return FALSE; } return TRUE; } static bool sieve_address_do_validate(const unsigned char *address, size_t size, const char **error_r) { struct sieve_message_address_parser ctx; *error_r = NULL; if (address == NULL) { *error_r = "null address"; return FALSE; } i_zero(&ctx); ctx.local_part = t_str_new(128); ctx.domain = t_str_new(128); ctx.str = t_str_new(128); ctx.error = t_str_new(128); if (!parse_mailbox_address(&ctx, address, size)) { *error_r = str_c(ctx.error); return FALSE; } return TRUE; } static const struct smtp_address * sieve_address_do_parse(const unsigned char *address, size_t size, const char **error_r) { struct sieve_message_address_parser ctx; *error_r = NULL; if (address == NULL) return NULL; i_zero(&ctx); ctx.local_part = t_str_new(128); ctx.domain = t_str_new(128); ctx.str = t_str_new(128); ctx.error = t_str_new(128); if (!parse_mailbox_address(&ctx, address, size)) { *error_r = str_c(ctx.error); return NULL; } (void)str_lcase(str_c_modifiable(ctx.domain)); return smtp_address_create_temp(str_c(ctx.local_part), str_c(ctx.domain)); } /* * Sieve address */ const struct smtp_address * sieve_address_parse(const char *address, const char **error_r) { return sieve_address_do_parse((const unsigned char *)address, strlen(address), error_r); } const struct smtp_address * sieve_address_parse_str(string_t *address, const char **error_r) { return sieve_address_do_parse(str_data(address), str_len(address), error_r); } bool sieve_address_validate(const char *address, const char **error_r) { return sieve_address_do_validate((const unsigned char *)address, strlen(address), error_r); } bool sieve_address_validate_str(string_t *address, const char **error_r) { return sieve_address_do_validate(str_data(address), str_len(address), error_r); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-error.c0000644000175100001700000006027215100335616024062 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "array.h" #include "ostream.h" #include "var-expand.h" #include "eacces-error.h" #include "sieve-common.h" #include "sieve-script.h" #include "sieve-error-private.h" #include #include #include #include #include #include /* * Definitions */ #define CRITICAL_MSG \ "internal error occurred: refer to server log for more information." #define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]" /* Logfile error handler will rotate log when it exceeds 10k bytes */ #define LOGFILE_MAX_SIZE (10 * 1024) /* * Utility */ const char * sieve_error_script_location(const struct sieve_script *script, unsigned int source_line) { const char *sname; sname = (script == NULL ? NULL : sieve_script_name(script)); if (sname == NULL || *sname == '\0') { if (source_line == 0) return NULL; return t_strdup_printf("line %d", source_line); } if (source_line == 0) return sname; return t_strdup_printf("%s: line %d", sname, source_line); } const char *sieve_error_from_external(const char *msg) { char *new_msg; if (msg == NULL || *msg == '\0') return msg; new_msg = t_strdup_noconst(msg); new_msg[0] = i_tolower(new_msg[0]); return new_msg; } /* * Initialization */ void sieve_errors_init(struct sieve_instance *svinst ATTR_UNUSED) { /* nothing */ } void sieve_errors_deinit(struct sieve_instance *svinst ATTR_UNUSED) { /* nothing */ } /* * Direct handler calls */ static void sieve_direct_master_log(struct sieve_instance *svinst, const struct sieve_error_params *params, const char *message) { struct event_log_params event_params = { .log_type = params->log_type, .source_filename = params->csrc.filename, .source_linenum = params->csrc.linenum, .base_event = svinst->event, }; struct event *event = (params->event != NULL ? params->event : svinst->event); if (params->location != NULL && *params->location != '\0') { event_params.base_send_prefix = t_strconcat(params->location, ": ", NULL); } event_log(event, &event_params, "%s", message); } void sieve_direct_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags, const char *fmt, va_list args) { struct event_log_params event_params = { .log_type = params->log_type, .source_filename = params->csrc.filename, .source_linenum = params->csrc.linenum, .base_event = svinst->event, .base_str_out = NULL, .no_send = TRUE, }; struct event *event = (params->event != NULL ? params->event : svinst->event); bool event_log = FALSE, ehandler_log = FALSE; if (ehandler != NULL) { switch (params->log_type) { case LOG_TYPE_ERROR: ehandler_log = sieve_errors_more_allowed(ehandler); break; case LOG_TYPE_WARNING: ehandler_log = TRUE; break; case LOG_TYPE_INFO: ehandler_log = ehandler->log_info; break; case LOG_TYPE_DEBUG: ehandler_log = ehandler->log_debug; break; case LOG_TYPE_FATAL: case LOG_TYPE_PANIC: case LOG_TYPE_COUNT: case LOG_TYPE_OPTION: i_unreached(); } } if (ehandler != NULL && ehandler->master_log) { event_log = ehandler_log; ehandler_log = FALSE; } if ((flags & SIEVE_ERROR_FLAG_GLOBAL) != 0) { event_log = TRUE; if ((flags & SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO) != 0 && params->log_type > LOG_TYPE_INFO) event_params.log_type = LOG_TYPE_INFO; } if (event_log) { event_params.no_send = FALSE; if (params->location != NULL && *params->location != '\0') { event_params.base_send_prefix = t_strconcat(params->location, ": ", NULL); } } if (ehandler_log) { if (ehandler->log == NULL) ehandler_log = FALSE; else event_params.base_str_out = t_str_new(128); } if (event_log || ehandler_log) event_logv(event, &event_params, fmt, args); if (ehandler_log) { ehandler->log(ehandler, params, flags, str_c(event_params.base_str_out)); } if (ehandler != NULL && ehandler->pool != NULL) { switch (params->log_type) { case LOG_TYPE_ERROR: ehandler->errors++; break; case LOG_TYPE_WARNING: ehandler->warnings++; break; default: break; } } } /* * User errors */ void sieve_global_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *fmt, va_list args) { sieve_direct_logv(svinst, ehandler, params, SIEVE_ERROR_FLAG_GLOBAL, fmt, args); } void sieve_global_info_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *fmt, va_list args) { sieve_direct_logv(svinst, ehandler, params, (SIEVE_ERROR_FLAG_GLOBAL | SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO), fmt, args); } #undef sieve_global_error void sieve_global_error(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_global_logv(svinst, ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_global_warning void sieve_global_warning(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_global_logv(svinst, ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_global_info void sieve_global_info(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_INFO, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_global_logv(svinst, ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_global_info_error void sieve_global_info_error(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_global_info_logv(svinst, ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_global_info_warning void sieve_global_info_warning(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_global_info_logv(svinst, ehandler, ¶ms, fmt, args); } T_END; va_end(args); } /* * Default (user) error functions */ void sieve_internal_error_params(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *user_prefix) { char str[256]; const char *msg; struct tm *tm; if (ehandler == NULL || ehandler->master_log) return; tm = localtime(&ioloop_time); msg = (strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ? str : CRITICAL_MSG); if (user_prefix == NULL || *user_prefix == '\0') { sieve_direct_log(ehandler->svinst, ehandler, params, 0, "%s", msg); } else { sieve_direct_log(ehandler->svinst, ehandler, params, 0, "%s: %s", user_prefix, msg); } } #undef sieve_internal_error void sieve_internal_error(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *user_prefix) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; sieve_internal_error_params(ehandler, ¶ms, user_prefix); } void sieve_logv(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *fmt, va_list args) { if (ehandler == NULL) return; sieve_direct_logv(ehandler->svinst, ehandler, params, 0, fmt, args); } void sieve_event_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, struct event *event, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *location, enum sieve_error_flags flags, const char *fmt, va_list args) { struct sieve_error_params params = { .log_type = log_type, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .event = event, .location = location, }; T_BEGIN { sieve_direct_logv(svinst, ehandler, ¶ms, flags, fmt, args); } T_END; } #undef sieve_event_log void sieve_event_log(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, struct event *event, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *location, enum sieve_error_flags flags, const char *fmt, ...) { va_list args; va_start(args, fmt); sieve_event_logv(svinst, ehandler, event, log_type, csrc_filename, csrc_linenum, location, flags, fmt, args); va_end(args); } void sieve_criticalv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *user_prefix, const char *fmt, va_list args) { struct sieve_error_params new_params = *params; new_params.log_type = LOG_TYPE_ERROR; sieve_direct_master_log(svinst, &new_params, t_strdup_vprintf(fmt, args)); sieve_internal_error_params(ehandler, &new_params, user_prefix); } #undef sieve_error void sieve_error(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_logv(ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_warning void sieve_warning(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_logv(ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_info void sieve_info(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_INFO, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_logv(ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_debug void sieve_debug(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_DEBUG, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_logv(ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #undef sieve_critical void sieve_critical(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *user_prefix, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_criticalv(svinst, ehandler, ¶ms, user_prefix, fmt, args); } T_END; va_end(args); } /* * Error statistics */ unsigned int sieve_get_errors(struct sieve_error_handler *ehandler) { if (ehandler == NULL || ehandler->pool == NULL) return 0; return ehandler->errors; } unsigned int sieve_get_warnings(struct sieve_error_handler *ehandler) { if (ehandler == NULL || ehandler->pool == NULL) return 0; return ehandler->warnings; } bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler) { if (ehandler == NULL || ehandler->pool == NULL) return TRUE; return (ehandler->max_errors == 0 || ehandler->errors < ehandler->max_errors); } /* * Error handler configuration */ void sieve_error_handler_accept_infolog(struct sieve_error_handler *ehandler, bool enable) { ehandler->log_info = enable; } void sieve_error_handler_accept_debuglog(struct sieve_error_handler *ehandler, bool enable) { ehandler->log_debug = enable; } /* * Error handler init */ void sieve_error_handler_init(struct sieve_error_handler *ehandler, struct sieve_instance *svinst, pool_t pool, unsigned int max_errors) { ehandler->pool = pool; ehandler->svinst = svinst; ehandler->refcount = 1; ehandler->max_errors = max_errors; ehandler->errors = 0; ehandler->warnings = 0; } void sieve_error_handler_ref(struct sieve_error_handler *ehandler) { if (ehandler == NULL || ehandler->pool == NULL) return; ehandler->refcount++; } void sieve_error_handler_unref(struct sieve_error_handler **ehandler) { if (*ehandler == NULL || (*ehandler)->pool == NULL) return; i_assert((*ehandler)->refcount > 0); if (--(*ehandler)->refcount != 0) return; if ((*ehandler)->free != NULL) (*ehandler)->free(*ehandler); pool_unref(&((*ehandler)->pool)); *ehandler = NULL; } void sieve_error_handler_reset(struct sieve_error_handler *ehandler) { if (ehandler == NULL || ehandler->pool == NULL) return; ehandler->errors = 0; ehandler->warnings = 0; } /* * Error params utility */ static void sieve_error_params_add_prefix(struct sieve_error_handler *ehandler ATTR_UNUSED, const struct sieve_error_params *params, string_t *prefix) { if (params->location != NULL && *params->location != '\0') { str_append(prefix, params->location); str_append(prefix, ": "); } switch (params->log_type) { case LOG_TYPE_ERROR: str_append(prefix, "error: "); break; case LOG_TYPE_WARNING: str_append(prefix, "warning: "); break; case LOG_TYPE_INFO: str_append(prefix, "info: "); break; case LOG_TYPE_DEBUG: str_append(prefix, "debug: "); break; default: i_unreached(); } } /* * Master/System error handler * * - Output errors directly to Dovecot master log */ struct sieve_error_handler * sieve_master_ehandler_create(struct sieve_instance *svinst, unsigned int max_errors) { struct sieve_error_handler *ehandler; pool_t pool; pool = pool_alloconly_create("master_error_handler", 256); ehandler = p_new(pool, struct sieve_error_handler, 1); sieve_error_handler_init(ehandler, svinst, pool, max_errors); ehandler->master_log = TRUE; ehandler->log_debug = svinst->debug; return ehandler; } /* * STDERR error handler * * - Output errors directly to stderror */ static void sieve_stderr_log(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags ATTR_UNUSED, const char *message) { string_t *prefix = t_str_new(64); sieve_error_params_add_prefix(ehandler, params, prefix); fprintf(stderr, "%s%s.\n", str_c(prefix), message); } struct sieve_error_handler * sieve_stderr_ehandler_create(struct sieve_instance *svinst, unsigned int max_errors) { pool_t pool; struct sieve_error_handler *ehandler; /* Pool is not strictly necessary, but other handler types will need * a pool, so this one will have one too. */ pool = pool_alloconly_create("stderr_error_handler", sizeof(struct sieve_error_handler)); ehandler = p_new(pool, struct sieve_error_handler, 1); sieve_error_handler_init(ehandler, svinst, pool, max_errors); ehandler->log = sieve_stderr_log; return ehandler; } /* String buffer error handler * * - Output errors to a string buffer */ struct sieve_strbuf_ehandler { struct sieve_error_handler handler; string_t *errors; bool crlf; }; static void sieve_strbuf_log(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags ATTR_UNUSED, const char *message) { struct sieve_strbuf_ehandler *handler = (struct sieve_strbuf_ehandler *) ehandler; sieve_error_params_add_prefix(ehandler, params, handler->errors); str_append(handler->errors, message); if (!handler->crlf) str_append(handler->errors, ".\n"); else str_append(handler->errors, ".\r\n"); } struct sieve_error_handler * sieve_strbuf_ehandler_create(struct sieve_instance *svinst, string_t *strbuf, bool crlf, unsigned int max_errors) { pool_t pool; struct sieve_strbuf_ehandler *ehandler; pool = pool_alloconly_create("strbuf_error_handler", 256); ehandler = p_new(pool, struct sieve_strbuf_ehandler, 1); ehandler->errors = strbuf; sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors); ehandler->handler.log = sieve_strbuf_log; ehandler->crlf = crlf; return &(ehandler->handler); } /* * Logfile error handler * * - Output errors to a log file */ struct sieve_logfile_ehandler { struct sieve_error_handler handler; const char *logfile; bool started; int fd; struct ostream *stream; }; static void sieve_logfile_write(struct sieve_logfile_ehandler *ehandler, const struct sieve_error_params *params, const char *message) { string_t *outbuf; ssize_t ret = 0, remain; const char *data; if (ehandler->stream == NULL) return; T_BEGIN { outbuf = t_str_new(256); sieve_error_params_add_prefix(&ehandler->handler, params, outbuf); str_append(outbuf, message); str_append(outbuf, ".\n"); remain = str_len(outbuf); data = (const char *) str_data(outbuf); while (remain > 0) { if ((ret = o_stream_send(ehandler->stream, data, remain)) < 0) break; remain -= ret; data += ret; } } T_END; if (ret < 0) { e_error(ehandler->handler.svinst->event, "o_stream_send() failed on logfile %s: %m", ehandler->logfile); } } inline static void ATTR_FORMAT(5, 6) sieve_logfile_printf(struct sieve_logfile_ehandler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_INFO, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); sieve_logfile_write(ehandler, ¶ms, t_strdup_vprintf(fmt, args)); va_end(args); } static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) { struct sieve_instance *svinst = ehandler->handler.svinst; struct ostream *ostream = NULL; struct stat st; struct tm *tm; char buf[256]; time_t now; int fd; /* Open the logfile */ fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY, 0600); if (fd == -1) { if (errno == EACCES) { e_error(svinst->event, "failed to open logfile " "(LOGGING TO STDERR): %s", eacces_error_get_creating("open", ehandler->logfile)); } else { e_error(svinst->event, "failed to open logfile " "(LOGGING TO STDERR): " "open(%s) failed: %m", ehandler->logfile); } fd = STDERR_FILENO; } else { /* fd_close_on_exec(fd, TRUE); Necessary? */ /* Stat the log file to obtain size information */ if (fstat(fd, &st) != 0) { e_error(svinst->event, "failed to stat logfile " "(logging to STDERR): " "fstat(fd=%s) failed: %m", ehandler->logfile); if (close(fd) < 0) { e_error(svinst->event, "failed to close logfile after error: " "close(fd=%s) failed: %m", ehandler->logfile); } fd = STDERR_FILENO; } /* Rotate log when it has grown too large */ if (st.st_size >= LOGFILE_MAX_SIZE) { const char *rotated; /* Close open file */ if (close(fd) < 0) { e_error(svinst->event, "failed to close logfile: " "close(fd=%s) failed: %m", ehandler->logfile); } /* Rotate logfile */ rotated = t_strconcat(ehandler->logfile, ".0", NULL); if (rename(ehandler->logfile, rotated) < 0 && errno != ENOENT) { if (errno == EACCES) { const char *target = t_strconcat(ehandler->logfile, ", ", rotated, NULL); e_error(svinst->event, "failed to rotate logfile: %s", eacces_error_get_creating( "rename", target)); } else { e_error(svinst->event, "failed to rotate logfile: " "rename(%s, %s) failed: %m", ehandler->logfile, rotated); } } /* Open clean logfile (overwrites existing if rename() failed earlier) */ fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY | O_TRUNC, 0600); if (fd == -1) { if (errno == EACCES) { e_error(svinst->event, "failed to open logfile " "(LOGGING TO STDERR): %s", eacces_error_get_creating( "open", ehandler->logfile)); } else { e_error(svinst->event, "failed to open logfile " "(LOGGING TO STDERR): " "open(%s) failed: %m", ehandler->logfile); } fd = STDERR_FILENO; } } } ostream = o_stream_create_fd(fd, 0); if (ostream == NULL) { /* Can't we do anything else in this most awkward situation? */ e_error(svinst->event, "failed to open log stream on open file: " "o_stream_create_fd(fd=%s) failed " "(non-critical messages are not logged!)", ehandler->logfile); } ehandler->fd = fd; ehandler->stream = ostream; ehandler->started = TRUE; if (ostream != NULL) { now = time(NULL); tm = localtime(&now); if (strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", tm) > 0) { sieve_logfile_printf(ehandler, __FILE__, __LINE__, "sieve", "started log at %s", buf); } } } static void sieve_logfile_log(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags ATTR_UNUSED, const char *message) { struct sieve_logfile_ehandler *handler = (struct sieve_logfile_ehandler *) ehandler; if (!handler->started) sieve_logfile_start(handler); sieve_logfile_write(handler, params, message); } static void sieve_logfile_free(struct sieve_error_handler *ehandler) { struct sieve_logfile_ehandler *handler = (struct sieve_logfile_ehandler *) ehandler; if (handler->stream != NULL) { o_stream_destroy(&(handler->stream)); if (handler->fd != STDERR_FILENO) { if (close(handler->fd) < 0) { e_error(ehandler->svinst->event, "failed to close logfile: " "close(fd=%s) failed: %m", handler->logfile); } } } } struct sieve_error_handler * sieve_logfile_ehandler_create(struct sieve_instance *svinst, const char *logfile, unsigned int max_errors) { pool_t pool; struct sieve_logfile_ehandler *ehandler; pool = pool_alloconly_create("logfile_error_handler", 512); ehandler = p_new(pool, struct sieve_logfile_ehandler, 1); sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors); ehandler->handler.log = sieve_logfile_log; ehandler->handler.free = sieve_logfile_free; /* Don't open logfile until something is actually logged. * Let's not pullute the sieve directory with useless logfiles. */ ehandler->logfile = p_strdup(pool, logfile); ehandler->started = FALSE; ehandler->stream = NULL; ehandler->fd = -1; return &(ehandler->handler); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary-private.h0000644000175100001700000001311015100335616025657 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_BINARY_PRIVATE_H #define SIEVE_BINARY_PRIVATE_H #include "sieve-common.h" #include "sieve-binary.h" #include "sieve-extensions.h" #include #define SIEVE_BINARY_FILE_LOCK_TIMEOUT 10 /* * Binary file */ enum SIEVE_BINARY_FLAGS { SIEVE_BINARY_FLAG_RESOURCE_LIMIT = BIT(0), }; struct sieve_binary_header { uint32_t magic; uint16_t version_major; uint16_t version_minor; uint32_t blocks; uint32_t hdr_size; uint32_t flags; struct { uint64_t update_time; uint32_t cpu_time_msecs; } resource_usage; }; struct sieve_binary_file { pool_t pool; const char *path; struct sieve_binary *sbin; struct stat st; int fd; off_t offset; }; void sieve_binary_file_close(struct sieve_binary_file **_file); /* * Internal structures */ /* Extension registration */ struct sieve_binary_extension_reg { /* The identifier of the extension within this binary */ int index; /* Global extension object */ const struct sieve_extension *extension; /* Extension to the binary; typically used to manage extension-specific blocks in the binary and as a means to get a binary_free notification to release references held by extensions. */ const struct sieve_binary_extension *binext; /* Context data associated to the binary by this extension */ void *context; /* Main block for this extension */ unsigned int block_id; }; /* Block */ struct sieve_binary_block { struct sieve_binary *sbin; unsigned int id; int ext_index; buffer_t *data; uoff_t offset; }; /* * Binary object */ struct sieve_binary { pool_t pool; int refcount; struct sieve_instance *svinst; struct event *event; struct sieve_script *script; struct sieve_binary_file *file; struct sieve_binary_header header; struct sieve_resource_usage rusage; /* When the binary is loaded into memory or when it is being constructed by the generator, extensions can be associated to the binary. The extensions array is a sequential list of all linked extensions. The extension_index array is a mapping ext_id -> binary_extension. This is used to obtain the index code associated with an extension for this particular binary. The linked_extensions list all extensions linked to this binary object other than the preloaded language features implemented as 'extensions'. All arrays refer to the same extension registration objects. Upon loading a binary, the 'require'd extensions will sometimes need to associate context data to the binary object in memory. This is stored in these registration objects as well. */ ARRAY(struct sieve_binary_extension_reg *) extensions; ARRAY(struct sieve_binary_extension_reg *) extension_index; ARRAY(struct sieve_binary_extension_reg *) linked_extensions; /* Attributes of a loaded binary */ const char *path; /* Blocks */ ARRAY(struct sieve_binary_block *) blocks; bool rusage_updated:1; }; void sieve_binary_update_event(struct sieve_binary *sbin, const char *new_path) ATTR_NULL(2); struct sieve_binary * sieve_binary_create(struct sieve_instance *svinst, struct sieve_script *script); /* Blocks management */ static inline struct sieve_binary_block * sieve_binary_block_index(struct sieve_binary *sbin, unsigned int id) { struct sieve_binary_block *const *sblock; if (id >= array_count(&sbin->blocks)) return NULL; sblock = array_idx(&sbin->blocks, id); if (*sblock == NULL) return NULL; return *sblock; } static inline size_t _sieve_binary_block_get_size(const struct sieve_binary_block *sblock) { return buffer_get_used_size(sblock->data); } struct sieve_binary_block * sieve_binary_block_create_id(struct sieve_binary *sbin, unsigned int id); buffer_t *sieve_binary_block_get_buffer(struct sieve_binary_block *sblock); /* Extension registration */ static inline struct sieve_binary_extension_reg * sieve_binary_extension_create_reg(struct sieve_binary *sbin, const struct sieve_extension *ext) { int index = array_count(&sbin->extensions); struct sieve_binary_extension_reg *ereg; if (ext->id < 0) return NULL; ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1); ereg->index = index; ereg->extension = ext; array_idx_set(&sbin->extensions, (unsigned int) index, &ereg); array_idx_set(&sbin->extension_index, (unsigned int) ext->id, &ereg); return ereg; } static inline struct sieve_binary_extension_reg * sieve_binary_extension_get_reg(struct sieve_binary *sbin, const struct sieve_extension *ext, bool create) { struct sieve_binary_extension_reg *reg = NULL; if (ext->id >= 0 && ext->id < (int)array_count(&sbin->extension_index)) { struct sieve_binary_extension_reg *const *ereg = array_idx(&sbin->extension_index, (unsigned int)ext->id); reg = *ereg; } /* Register if not known */ if (reg == NULL && create) return sieve_binary_extension_create_reg(sbin, ext); return reg; } static inline int sieve_binary_extension_register(struct sieve_binary *sbin, const struct sieve_extension *ext, struct sieve_binary_extension_reg **reg_r) { struct sieve_binary_extension_reg *ereg; if ((ereg = sieve_binary_extension_get_reg(sbin, ext, FALSE)) == NULL) { ereg = sieve_binary_extension_create_reg(sbin, ext); if (ereg == NULL) return -1; array_append(&sbin->linked_extensions, &ereg, 1); } if (reg_r != NULL) *reg_r = ereg; return ereg->index; } /* Load/Save */ bool sieve_binary_load_block(struct sieve_binary_block *); /* * Resource limits */ bool sieve_binary_check_resource_usage(struct sieve_binary *sbin); int sieve_binary_file_update_resource_usage(struct sieve_binary *sbin, enum sieve_error *error_code_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-stringlist.h0000644000175100001700000000316715100335616025140 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_STRINGLIST_H #define SIEVE_STRINGLIST_H /* * Stringlist API */ struct sieve_stringlist { int (*next_item)(struct sieve_stringlist *strlist, string_t **str_r); void (*reset)(struct sieve_stringlist *strlist); int (*get_length)(struct sieve_stringlist *strlist); int (*read_all)(struct sieve_stringlist *strlist, pool_t pool, const char *const **list_r); void (*set_trace)(struct sieve_stringlist *strlist, bool trace); const struct sieve_runtime_env *runenv; int exec_status; bool trace:1; }; static inline void sieve_stringlist_set_trace(struct sieve_stringlist *strlist, bool trace) { strlist->trace = trace; if (strlist->set_trace != NULL) strlist->set_trace(strlist, trace); } static inline int sieve_stringlist_next_item(struct sieve_stringlist *strlist, string_t **str_r) { return strlist->next_item(strlist, str_r); } static inline void sieve_stringlist_reset(struct sieve_stringlist *strlist) { strlist->reset(strlist); } int sieve_stringlist_get_length(struct sieve_stringlist *strlist); int sieve_stringlist_read_all(struct sieve_stringlist *strlist, pool_t pool, const char *const **list_r); /* * Single Stringlist */ struct sieve_stringlist * sieve_single_stringlist_create(const struct sieve_runtime_env *renv, string_t *str, bool count_empty); struct sieve_stringlist * sieve_single_stringlist_create_cstr(const struct sieve_runtime_env *renv, const char *cstr, bool count_empty); /* * Index Stringlist */ struct sieve_stringlist * sieve_index_stringlist_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *source, int index); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/Makefile.am0000644000175100001700000001072715100335616023510 0ustar00buildbotbuildbot00000000000000SUBDIRS = util storage plugins dovecot_pkglib_LTLIBRARIES = libdovecot-sieve.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) \ -I$(top_srcdir)/src/lib-sieve/util \ -DMODULEDIR=\""$(dovecot_moduledir)"\" tests = \ tst-truefalse.c \ tst-not.c \ tst-anyof.c \ tst-allof.c \ tst-address.c \ tst-header.c \ tst-exists.c \ tst-size.c commands = \ cmd-require.c \ cmd-stop.c \ cmd-if.c \ cmd-keep.c \ cmd-redirect.c \ cmd-discard.c extensions = \ ext-fileinto.c \ ext-reject.c \ ext-envelope.c \ ext-encoded-character.c match_types = \ mcht-is.c \ mcht-contains.c \ mcht-matches.c comparators = \ cmp-i-octet.c \ cmp-i-ascii-casemap.c \ cmp-i-unicode-casemap.c if BUILD_UNFINISHED unfinished_storages = unfinished_plugins = endif strgdir = $(top_builddir)/src/lib-sieve/storage storages = \ $(strgdir)/data/libsieve_storage_data.la \ $(strgdir)/file/libsieve_storage_file.la \ $(strgdir)/dict/libsieve_storage_dict.la \ $(strgdir)/ldap/libsieve_storage_ldap.la \ $(unfinished_storages) extdir = $(top_builddir)/src/lib-sieve/plugins plugins = \ $(extdir)/vacation/libsieve_ext_vacation.la \ $(extdir)/subaddress/libsieve_ext_subaddress.la \ $(extdir)/comparator-i-ascii-numeric/libsieve_ext_comparator-i-ascii-numeric.la \ $(extdir)/relational/libsieve_ext_relational.la \ $(extdir)/regex/libsieve_ext_regex.la \ $(extdir)/copy/libsieve_ext_copy.la \ $(extdir)/imap4flags/libsieve_ext_imap4flags.la \ $(extdir)/include/libsieve_ext_include.la \ $(extdir)/body/libsieve_ext_body.la \ $(extdir)/variables/libsieve_ext_variables.la \ $(extdir)/enotify/libsieve_ext_enotify.la \ $(extdir)/environment/libsieve_ext_environment.la \ $(extdir)/mailbox/libsieve_ext_mailbox.la \ $(extdir)/date/libsieve_ext_date.la \ $(extdir)/spamvirustest/libsieve_ext_spamvirustest.la \ $(extdir)/ihave/libsieve_ext_ihave.la \ $(extdir)/editheader/libsieve_ext_editheader.la \ $(extdir)/duplicate/libsieve_ext_duplicate.la \ $(extdir)/index/libsieve_ext_index.la \ $(extdir)/metadata/libsieve_ext_metadata.la \ $(extdir)/mime/libsieve_ext_mime.la \ $(extdir)/special-use/libsieve_ext_special_use.la \ $(extdir)/extlists/libsieve_ext_extlists.la \ $(extdir)/vnd.dovecot/debug/libsieve_ext_debug.la \ $(extdir)/vnd.dovecot/environment/libsieve_ext_vnd_environment.la \ $(extdir)/vnd.dovecot/report/libsieve_ext_vnd_report.la \ $(unfinished_plugins) libdovecot_sieve_la_DEPENDENCIES = \ $(storages) \ $(plugins) \ $(top_builddir)/src/lib-sieve/util/libsieve_util.la \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) libdovecot_sieve_la_LIBADD = \ $(storages) \ $(plugins) \ $(top_builddir)/src/lib-sieve/util/libsieve_util.la \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) libdovecot_sieve_la_SOURCES = \ sieve-settings.c \ sieve-message.c \ sieve-smtp.c \ sieve-lexer.c \ sieve-script.c \ sieve-storage.c \ sieve-storage-settings.c \ sieve-storage-sync.c \ sieve-ast.c \ sieve-binary.c \ sieve-binary-file.c \ sieve-binary-code.c \ sieve-binary-debug.c \ sieve-parser.c \ sieve-address.c \ sieve-validator.c \ sieve-generator.c \ sieve-execute.c \ sieve-interpreter.c \ sieve-runtime-trace.c \ sieve-code-dumper.c \ sieve-binary-dumper.c \ sieve-result.c \ sieve-error.c \ sieve-objects.c \ sieve-stringlist.c \ sieve-comparators.c \ sieve-match-types.c \ sieve-address-parts.c \ sieve-address-source.c \ sieve-match.c \ sieve-commands.c \ sieve-code.c \ sieve-actions.c \ sieve-extensions.c \ sieve-plugins.c \ $(comparators) \ $(match_types) \ $(tests) \ $(commands) \ $(extensions) \ sieve.c headers = \ sieve-config.h \ sieve-types.h \ sieve-common.h \ sieve-limits.h \ sieve-settings.h \ sieve-message.h \ sieve-smtp.h \ sieve-lexer.h \ sieve-script.h \ sieve-script-private.h \ sieve-storage.h \ sieve-storage-private.h \ sieve-storage-settings.h \ sieve-ast.h \ sieve-binary.h \ sieve-binary-private.h \ sieve-parser.h \ sieve-address.h \ sieve-validator.h \ sieve-generator.h \ sieve-execute.h \ sieve-interpreter.h \ sieve-runtime-trace.h \ sieve-runtime.h \ sieve-code-dumper.h \ sieve-binary-dumper.h \ sieve-dump.h \ sieve-result.h \ sieve-error.h \ sieve-error-private.h \ sieve-objects.h \ sieve-stringlist.h \ sieve-match.h \ sieve-comparators.h \ sieve-match-types.h \ sieve-address-parts.h \ sieve-address-source.h \ sieve-commands.h \ sieve-code.h \ sieve-actions.h \ sieve-extensions.h \ sieve-plugins.h \ sieve.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-storage.h0000644000175100001700000001602515100335616024377 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_STORAGE_H #define SIEVE_STORAGE_H #include "sieve-common.h" #define MAILBOX_ATTRIBUTE_PREFIX_SIEVE \ MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER"sieve/" #define MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES \ MAILBOX_ATTRIBUTE_PREFIX_SIEVE"files/" #define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT \ MAILBOX_ATTRIBUTE_PREFIX_SIEVE"default" #define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK 'L' #define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT 'S' /* * Storage name */ bool sieve_storage_name_is_valid(const char *name); /* * Storage type */ /* Common storage types; others may be defined in specific contexts. */ #define SIEVE_STORAGE_TYPE_ANY "any" #define SIEVE_STORAGE_TYPE_PERSONAL "personal" #define SIEVE_STORAGE_TYPE_DEFAULT "default" #define SIEVE_STORAGE_TYPE_GLOBAL "global" #define SIEVE_STORAGE_TYPE_BEFORE "before" #define SIEVE_STORAGE_TYPE_AFTER "after" #define SIEVE_STORAGE_TYPE_DISCARD "discard" /* * Storage object */ enum sieve_storage_flags { /* Storage is opened for read/write access (e.g. ManageSieve) */ SIEVE_STORAGE_FLAG_READWRITE = 0x01, /* This storage is used for synchronization (and not normal ManageSieve) */ SIEVE_STORAGE_FLAG_SYNCHRONIZING = 0x02 }; struct sieve_storage; /* Determine whether storage driver exists. */ bool sieve_storage_class_exists(struct sieve_instance *svinst, const char *name); int sieve_storage_create(struct sieve_instance *svinst, struct event *event, const char *cause, const char *storage_name, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r); int sieve_storage_create_auto(struct sieve_instance *svinst, struct event *event, const char *cause, const char *type, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r); int sieve_storage_create_personal(struct sieve_instance *svinst, struct mail_user *user, const char *cause, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r); void sieve_storage_ref(struct sieve_storage *storage); void sieve_storage_unref(struct sieve_storage **_storage); /* * Script access */ int sieve_storage_get_script_direct(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r); int sieve_storage_get_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r); int sieve_storage_open_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r); int sieve_storage_check_script(struct sieve_storage *storage, const char *name, enum sieve_error *error_code_r); /* * Active script */ int sieve_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r); int sieve_storage_active_script_open(struct sieve_storage *storage, struct sieve_script **script_r, enum sieve_error *error_code_r); int sieve_storage_active_script_get_last_change(struct sieve_storage *storage, time_t *last_change_r); /* * Listing scripts in storage */ struct sieve_storage_list_context; /* Create a context for listing the scripts in the storage */ int sieve_storage_list_init(struct sieve_storage *storage, struct sieve_storage_list_context **lctx_r); /* Get the next script in the storage. */ const char *sieve_storage_list_next(struct sieve_storage_list_context *lctx, bool *active_r) ATTR_NULL(2); /* Destroy the listing context */ int sieve_storage_list_deinit(struct sieve_storage_list_context **lctx); /* * Saving scripts in storage */ struct sieve_storage_save_context; struct sieve_storage_save_context * sieve_storage_save_init(struct sieve_storage *storage, const char *scriptname, struct istream *input); int sieve_storage_save_continue(struct sieve_storage_save_context *sctx); int sieve_storage_save_finish(struct sieve_storage_save_context *sctx); struct sieve_script * sieve_storage_save_get_tempscript(struct sieve_storage_save_context *sctx); bool sieve_storage_save_will_activate(struct sieve_storage_save_context *sctx); void sieve_storage_save_set_mtime(struct sieve_storage_save_context *sctx, time_t mtime); void sieve_storage_save_cancel(struct sieve_storage_save_context **sctx); int sieve_storage_save_commit(struct sieve_storage_save_context **sctx); int sieve_storage_save_as(struct sieve_storage *storage, struct istream *input, const char *name); /* Saves input directly as a regular file at the active script path. * This is needed for the doveadm-sieve plugin. */ int sieve_storage_save_as_active(struct sieve_storage *storage, struct istream *input, time_t mtime); /* * Management */ int sieve_storage_deactivate(struct sieve_storage *storage, time_t mtime); /* * Storage quota */ enum sieve_storage_quota { SIEVE_STORAGE_QUOTA_NONE, SIEVE_STORAGE_QUOTA_MAXSIZE, SIEVE_STORAGE_QUOTA_MAXSCRIPTS, SIEVE_STORAGE_QUOTA_MAXSTORAGE }; bool sieve_storage_quota_validsize(struct sieve_storage *storage, size_t size, uint64_t *limit_r); uint64_t sieve_storage_quota_max_script_size(struct sieve_storage *storage); int sieve_storage_quota_havespace(struct sieve_storage *storage, const char *scriptname, size_t size, enum sieve_storage_quota *quota_r, uint64_t *limit_r); /* * Properties */ const char *sieve_storage_name(const struct sieve_storage *storage) ATTR_PURE; const char *sieve_storage_location(const struct sieve_storage *storage) ATTR_PURE; bool sieve_storage_is_default(const struct sieve_storage *storage) ATTR_PURE; bool sieve_storage_is_personal(struct sieve_storage *storage) ATTR_PURE; int sieve_storage_is_singular(struct sieve_storage *storage); /* * Error handling */ void sieve_storage_clear_error(struct sieve_storage *storage); void sieve_storage_set_error(struct sieve_storage *storage, enum sieve_error error_code, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_storage_set_critical(struct sieve_storage *storage, const char *fmt, ...) ATTR_FORMAT(2, 3); const char *sieve_storage_get_last_error(struct sieve_storage *storage, enum sieve_error *error_code_r); /* * */ int sieve_storage_get_last_change(struct sieve_storage *storage, time_t *last_change_r); void sieve_storage_set_modified(struct sieve_storage *storage, time_t mtime); /* * Storage sequence */ struct sieve_storage_sequence; int sieve_storage_sequence_create(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const char *type, struct sieve_storage_sequence **sseq_r, enum sieve_error *error_code_r, const char **error_r); int sieve_storage_sequence_next(struct sieve_storage_sequence *sseq, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r); void sieve_storage_sequence_free(struct sieve_storage_sequence **_sseq); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/cmd-discard.c0000644000175100001700000000771115100335616023771 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-dump.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" /* * Discard command * * Syntax * discard */ static bool cmd_discard_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx ATTR_UNUSED); const struct sieve_command_def cmd_discard = { .identifier = "discard", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .generate = cmd_discard_generate }; /* * Discard operation */ static bool cmd_discard_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_discard_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def cmd_discard_operation = { .mnemonic = "DISCARD", .code = SIEVE_OPERATION_DISCARD, .dump = cmd_discard_operation_dump, .execute = cmd_discard_operation_execute }; /* * Discard actions */ static bool act_discard_equals(const struct sieve_script_env *senv, const struct sieve_action *act1, const struct sieve_action *act2); static int act_discard_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_discard_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_discard_execute(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); const struct sieve_action_def act_discard = { .name = "discard", .equals = act_discard_equals, .check_duplicate = act_discard_check_duplicate, .print = act_discard_print, .execute = act_discard_execute, }; /* * Code generation */ static bool cmd_discard_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd ATTR_UNUSED) { sieve_operation_emit(cgenv->sblock, NULL, &cmd_discard_operation); return TRUE; } /* * Code dump */ static bool cmd_discard_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "DISCARD"); sieve_code_descend(denv); return (sieve_action_opr_optional_dump(denv, address, NULL) == 0); } /* * Interpretation */ static int cmd_discard_operation_execute(const struct sieve_runtime_env *renv ATTR_UNUSED, sieve_size_t *address ATTR_UNUSED) { sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "discard action; cancel implicit keep"); if (sieve_result_add_action(renv, NULL, "discard", &act_discard, NULL, NULL, 0, FALSE) < 0) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } /* * Action implementation */ static bool act_discard_equals(const struct sieve_script_env *senv ATTR_UNUSED, const struct sieve_action *act1 ATTR_UNUSED, const struct sieve_action *act2 ATTR_UNUSED) { return TRUE; } static int act_discard_check_duplicate(const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *act ATTR_UNUSED, const struct sieve_action *act_other ATTR_UNUSED) { return 1; } static void act_discard_print(const struct sieve_action *action ATTR_UNUSED, const struct sieve_result_print_env *rpenv, bool *keep) { sieve_result_action_printf(rpenv, "discard"); *keep = FALSE; } static int act_discard_execute(const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED, bool *keep) { const struct sieve_execute_env *eenv = aenv->exec_env; eenv->exec_status->significant_action_executed = TRUE; struct event_passthrough *e = sieve_action_create_finish_event(aenv); sieve_result_event_log(aenv, e->event(), "Marked message to be discarded if not explicitly delivered " "(discard action)"); *keep = FALSE; return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/ext-envelope.c0000644000175100001700000004520615100335616024233 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension envelope * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5228 * Implementation: full * Status: testing * */ #include "lib.h" #include "str-sanitize.h" #include "array.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-address.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-message.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" /* * Forward declarations */ static const struct sieve_command_def envelope_test; const struct sieve_operation_def envelope_operation; const struct sieve_extension_def envelope_extension; /* * Extension */ static bool ext_envelope_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_envelope_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); static bool ext_envelope_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, bool required); static int ext_envelope_interpreter_run(const struct sieve_extension *this_ext, const struct sieve_runtime_env *renv, void *context, bool deferred); const struct sieve_extension_def envelope_extension = { .name = "envelope", .interpreter_load = ext_envelope_interpreter_load, .validator_load = ext_envelope_validator_load, SIEVE_EXT_DEFINE_OPERATION(envelope_operation) }; const struct sieve_validator_extension envelope_validator_extension = { .ext = &envelope_extension, .validate = ext_envelope_validator_validate }; const struct sieve_interpreter_extension envelope_interpreter_extension = { .ext_def = &envelope_extension, .run = ext_envelope_interpreter_run }; static bool ext_envelope_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ sieve_validator_register_command(valdtr, ext, &envelope_test); sieve_validator_extension_register(valdtr, ext, &envelope_validator_extension, NULL); return TRUE; } static bool ext_envelope_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_interpreter_extension_register(renv->interp, ext, &envelope_interpreter_extension, NULL); return TRUE; } static bool ext_envelope_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg, bool required) { if (required) { enum sieve_compile_flags flags = sieve_validator_compile_flags(valdtr); if ((flags & SIEVE_COMPILE_FLAG_NO_ENVELOPE) != 0) { sieve_argument_validate_error( valdtr, require_arg, "the %s extension cannot be used in this context " "(needs access to message envelope)", sieve_extension_name(ext)); return FALSE; } } return TRUE; } static int ext_envelope_interpreter_run(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, void *context ATTR_UNUSED, bool deferred) { const struct sieve_execute_env *eenv = renv->exec_env; if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0) { if (!deferred) { sieve_runtime_error( renv, NULL, "the %s extension cannot be used in this context " "(needs access to message envelope)", sieve_extension_name(ext)); } return SIEVE_EXEC_FAILURE; } return SIEVE_EXEC_OK; } /* * Envelope test * * Syntax * envelope [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] * */ static bool tst_envelope_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_envelope_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_envelope_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); static const struct sieve_command_def envelope_test = { .identifier = "envelope", .type = SCT_TEST, .positional_args= 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_envelope_registered, .validate = tst_envelope_validate, .generate = tst_envelope_generate }; /* * Envelope operation */ static bool ext_envelope_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_envelope_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def envelope_operation = { .mnemonic = "ENVELOPE", .ext_def = &envelope_extension, .dump = ext_envelope_operation_dump, .execute = ext_envelope_operation_execute }; /* * Envelope parts * * FIXME: not available to extensions */ struct sieve_envelope_part { const char *identifier; const struct smtp_address *const *(*get_addresses) (const struct sieve_runtime_env *renv); const char *const *(*get_values) (const struct sieve_runtime_env *renv); }; static const struct smtp_address *const * _from_part_get_addresses(const struct sieve_runtime_env *renv); static const char *const * _from_part_get_values(const struct sieve_runtime_env *renv); static const struct smtp_address *const * _to_part_get_addresses(const struct sieve_runtime_env *renv); static const char *const * _to_part_get_values(const struct sieve_runtime_env *renv); static const char *const * _auth_part_get_values(const struct sieve_runtime_env *renv); static const struct sieve_envelope_part _from_part = { "from", _from_part_get_addresses, _from_part_get_values, }; static const struct sieve_envelope_part _to_part = { "to", _to_part_get_addresses, _to_part_get_values, }; static const struct sieve_envelope_part _auth_part = { "auth", NULL, _auth_part_get_values, }; static const struct sieve_envelope_part *_envelope_parts[] = { /* Required */ &_from_part, &_to_part, /* Non-standard */ &_auth_part }; static unsigned int _envelope_part_count = N_ELEMENTS(_envelope_parts); static const struct sieve_envelope_part * _envelope_part_find(const char *identifier) { unsigned int i; for (i = 0; i < _envelope_part_count; i++) { if (strcasecmp(_envelope_parts[i]->identifier, identifier) == 0) return _envelope_parts[i]; } return NULL; } /* Envelope parts implementation */ static const struct smtp_address *const * _from_part_get_addresses(const struct sieve_runtime_env *renv) { ARRAY(const struct smtp_address *) envelope_values; const struct smtp_address *address = sieve_message_get_sender(renv->msgctx); t_array_init(&envelope_values, 2); if (address == NULL) address = smtp_address_create_temp(NULL, NULL); array_append(&envelope_values, &address, 1); (void)array_append_space(&envelope_values); return array_idx(&envelope_values, 0); } static const char *const * _from_part_get_values(const struct sieve_runtime_env *renv) { ARRAY(const char *)envelope_values; const struct smtp_address *address = sieve_message_get_sender(renv->msgctx); const char *value; t_array_init(&envelope_values, 2); value = ""; if (!smtp_address_isnull(address)) value = smtp_address_encode(address); array_append(&envelope_values, &value, 1); (void)array_append_space(&envelope_values); return array_idx(&envelope_values, 0); } static const struct smtp_address *const * _to_part_get_addresses(const struct sieve_runtime_env *renv) { ARRAY(const struct smtp_address *) envelope_values; const struct smtp_address *address = sieve_message_get_orig_recipient(renv->msgctx); if (address != NULL && address->localpart != NULL) { t_array_init(&envelope_values, 2); array_append(&envelope_values, &address, 1); (void)array_append_space(&envelope_values); return array_idx(&envelope_values, 0); } return NULL; } static const char *const * _to_part_get_values(const struct sieve_runtime_env *renv) { ARRAY(const char *) envelope_values; const struct smtp_address *address = sieve_message_get_orig_recipient(renv->msgctx); t_array_init(&envelope_values, 2); if (address != NULL && address->localpart != NULL) { const char *value = smtp_address_encode(address); array_append(&envelope_values, &value, 1); } (void)array_append_space(&envelope_values); return array_idx(&envelope_values, 0); } static const char *const * _auth_part_get_values(const struct sieve_runtime_env *renv) { const struct sieve_execute_env *eenv = renv->exec_env; ARRAY(const char *) envelope_values; t_array_init(&envelope_values, 2); if (eenv->msgdata->auth_user != NULL) array_append(&envelope_values, &eenv->msgdata->auth_user, 1); (void)array_append_space(&envelope_values); return array_idx(&envelope_values, 0); } /* * Envelope address list */ /* Forward declarations */ static int sieve_envelope_address_list_next_string_item(struct sieve_stringlist *_strlist, string_t **str_r); static int sieve_envelope_address_list_next_item(struct sieve_address_list *_addrlist, struct smtp_address *addr_r, string_t **unparsed_r); static void sieve_envelope_address_list_reset(struct sieve_stringlist *_strlist); /* Stringlist object */ struct sieve_envelope_address_list { struct sieve_address_list addrlist; struct sieve_stringlist *env_parts; const struct smtp_address *const *cur_addresses; const char *const *cur_values; int value_index; }; static struct sieve_address_list * sieve_envelope_address_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *env_parts) { struct sieve_envelope_address_list *addrlist; addrlist = t_new(struct sieve_envelope_address_list, 1); addrlist->addrlist.strlist.runenv = renv; addrlist->addrlist.strlist.exec_status = SIEVE_EXEC_OK; addrlist->addrlist.strlist.next_item = sieve_envelope_address_list_next_string_item; addrlist->addrlist.strlist.reset = sieve_envelope_address_list_reset; addrlist->addrlist.next_item = sieve_envelope_address_list_next_item; addrlist->env_parts = env_parts; return &addrlist->addrlist; } static int sieve_envelope_address_list_next_item(struct sieve_address_list *_addrlist, struct smtp_address *addr_r, string_t **unparsed_r) { struct sieve_envelope_address_list *addrlist = (struct sieve_envelope_address_list *)_addrlist; const struct sieve_runtime_env *renv = _addrlist->strlist.runenv; if (addr_r != NULL) smtp_address_init(addr_r, NULL, NULL); if (unparsed_r != NULL) *unparsed_r = NULL; while (addrlist->cur_addresses == NULL && addrlist->cur_values == NULL) { const struct sieve_envelope_part *epart; string_t *envp_item = NULL; int ret; /* Read next header value from source list */ if ((ret = sieve_stringlist_next_item(addrlist->env_parts, &envp_item)) <= 0) return ret; if (_addrlist->strlist.trace) { sieve_runtime_trace( _addrlist->strlist.runenv, 0, "getting '%s' part from message envelope", str_sanitize(str_c(envp_item), 80)); } if ((epart=_envelope_part_find(str_c(envp_item))) != NULL) { addrlist->value_index = 0; if (epart->get_addresses != NULL) { /* Field contains addresses */ addrlist->cur_addresses = epart->get_addresses(renv); /* Drop empty list */ if (addrlist->cur_addresses != NULL && addrlist->cur_addresses[0] == NULL) addrlist->cur_addresses = NULL; } if (addrlist->cur_addresses == NULL && epart->get_values != NULL) { /* Field contains something else */ addrlist->cur_values = epart->get_values(renv); /* Drop empty list */ if (addrlist->cur_values != NULL && addrlist->cur_values[0] == NULL) addrlist->cur_values = NULL; } } } /* Return next item */ if (addrlist->cur_addresses != NULL) { const struct smtp_address *addr = addrlist->cur_addresses[addrlist->value_index]; if (addr->localpart == NULL) { /* Null path <> */ if (unparsed_r != NULL) *unparsed_r = t_str_new_const("", 0); } else { if (addr_r != NULL) *addr_r = *addr; } /* Advance to next value */ addrlist->value_index++; if (addrlist->cur_addresses[addrlist->value_index] == NULL) { addrlist->cur_addresses = NULL; addrlist->value_index = 0; } } else { if (unparsed_r != NULL) { const char *value = addrlist->cur_values[addrlist->value_index]; *unparsed_r = t_str_new_const(value, strlen(value)); } /* Advance to next value */ addrlist->value_index++; if (addrlist->cur_values[addrlist->value_index] == NULL) { addrlist->cur_values = NULL; addrlist->value_index = 0; } } return 1; } static int sieve_envelope_address_list_next_string_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct sieve_address_list *addrlist = (struct sieve_address_list *)_strlist; struct smtp_address addr; int ret; if ((ret=sieve_envelope_address_list_next_item(addrlist, &addr, str_r)) <= 0) return ret; if (addr.localpart != NULL) { const char *addr_str = smtp_address_encode(&addr); if (str_r != NULL) *str_r = t_str_new_const(addr_str, strlen(addr_str)); } return 1; } static void sieve_envelope_address_list_reset(struct sieve_stringlist *_strlist) { struct sieve_envelope_address_list *addrlist = (struct sieve_envelope_address_list *)_strlist; sieve_stringlist_reset(addrlist->env_parts); addrlist->cur_addresses = NULL; addrlist->cur_values = NULL; addrlist->value_index = 0; } /* * Command Registration */ static bool tst_envelope_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_address_parts_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART); return TRUE; } /* * Validation */ static int _envelope_part_is_supported(void *context, struct sieve_ast_argument *arg) { const struct sieve_envelope_part **not_address = (const struct sieve_envelope_part **) context; if (sieve_argument_is_string_literal(arg)) { const struct sieve_envelope_part *epart; if ((epart=_envelope_part_find( sieve_ast_strlist_strc(arg))) != NULL) { if (epart->get_addresses == NULL) { if (*not_address == NULL) *not_address = epart; } return 1; } return 0; } return 1; /* Can't check at compile time */ } static bool tst_envelope_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *epart; struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_envelope_part *not_address = NULL; if (!sieve_validate_positional_argument(valdtr, tst, arg, "envelope part", 1, SAAT_STRING_LIST)) { return FALSE; } if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Check whether supplied envelope parts are supported * FIXME: verify dynamic envelope parts at runtime */ epart = arg; if (sieve_ast_stringlist_map(&epart, ¬_address, _envelope_part_is_supported) <= 0) { i_assert(epart != NULL); sieve_argument_validate_error( valdtr, epart, "specified envelope part '%s' is not supported by the envelope test", str_sanitize(sieve_ast_strlist_strc(epart), 64)); return FALSE; } if (not_address != NULL) { struct sieve_ast_argument *addrp_arg = sieve_command_find_argument(tst, &address_part_tag); if (addrp_arg != NULL) { sieve_argument_validate_error( valdtr, addrp_arg, "address part ':%s' specified while non-address envelope part '%s' " "is tested with the envelope test", sieve_ast_argument_tag(addrp_arg), not_address->identifier); return FALSE; } } arg = sieve_ast_argument_next(arg); if (!sieve_validate_positional_argument(valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_envelope_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &envelope_operation); /* Generate arguments */ if (!sieve_generate_arguments(cgenv, cmd, NULL)) return FALSE; return TRUE; } /* * Code dump */ static bool ext_envelope_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "ENVELOPE"); sieve_code_descend(denv); /* Handle any optional arguments */ if (sieve_addrmatch_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return (sieve_opr_stringlist_dump(denv, address, "envelope part") && sieve_opr_stringlist_dump(denv, address, "key list")); } /* * Interpretation */ static int ext_envelope_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_address_part addrp = SIEVE_ADDRESS_PART_DEFAULT(all_address_part); struct sieve_stringlist *env_part_list, *value_list, *key_list; struct sieve_address_list *addr_list; int match, ret; /* * Read operands */ /* Read optional operands */ if (sieve_addrmatch_opr_optional_read(renv, address, NULL, &ret, &addrp, &mcht, &cmp) < 0) return ret; /* Read envelope-part */ if ((ret = sieve_opr_stringlist_read(renv, address, "envelope-part", &env_part_list)) <= 0) return ret; /* Read key-list */ if ((ret = sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) <= 0) return ret; /* * Perform test */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "envelope test"); /* Create value stringlist */ addr_list = sieve_envelope_address_list_create(renv, env_part_list); value_list = sieve_address_part_stringlist_create(renv, &addrp, addr_list); /* Perform match */ if ((match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-message.c0000644000175100001700000013606415100335616024360 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "ioloop.h" #include "mempool.h" #include "array.h" #include "str.h" #include "str-sanitize.h" #include "istream.h" #include "time-util.h" #include "rfc822-parser.h" #include "message-date.h" #include "message-parser.h" #include "message-decoder.h" #include "message-header-decode.h" #include "mail-html2text.h" #include "mail-storage.h" #include "mail-storage-service.h" #include "mail-user.h" #include "smtp-params.h" #include "master-service.h" #include "master-service-settings.h" #include "raw-storage.h" #include "edit-mail.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-address.h" #include "sieve-address-parts.h" #include "sieve-runtime.h" #include "sieve-runtime-trace.h" #include "sieve-match.h" #include "sieve-interpreter.h" #include "sieve-message.h" /* * Message transmission */ const char *sieve_message_get_new_id(const struct sieve_instance *svinst) { static int count = 0; return t_strdup_printf("", dec2str(ioloop_timeval.tv_sec), dec2str(ioloop_timeval.tv_usec), count++, svinst->hostname); } /* * Message context */ struct sieve_message_header { const char *name; const unsigned char *value, *utf8_value; size_t value_len, utf8_value_len; }; struct sieve_message_part { struct sieve_message_part *parent, *next, *children; ARRAY(struct sieve_message_header) headers; const char *content_type; const char *content_disposition; const char *decoded_body; const char *text_body; size_t decoded_body_size; size_t text_body_size; bool have_body:1; /* there's the empty end-of-headers line */ bool epilogue:1; /* this is a multipart epilogue */ }; struct sieve_message_version { struct mail *mail; struct mailbox *box; struct mailbox_transaction_context *trans; struct edit_mail *edit_mail; }; struct sieve_message_context { pool_t pool; pool_t context_pool; int refcount; struct sieve_instance *svinst; struct timeval time; struct mail_user *mail_user; const struct sieve_message_data *msgdata; /* Message versioning */ struct mail_user *raw_mail_user; ARRAY(struct sieve_message_version) versions; /* Context data for extensions */ ARRAY(void *) ext_contexts; /* Body */ ARRAY(struct sieve_message_part *) cached_body_parts; ARRAY(struct sieve_message_part_data) return_body_parts; buffer_t *raw_body; bool edit_snapshot:1; bool substitute_snapshot:1; }; /* * Message versions */ static inline struct sieve_message_version * sieve_message_version_new(struct sieve_message_context *msgctx) { return array_append_space(&msgctx->versions); } static inline struct sieve_message_version * sieve_message_version_get(struct sieve_message_context *msgctx) { struct sieve_message_version *versions; unsigned int count; versions = array_get_modifiable(&msgctx->versions, &count); if (count == 0) return array_append_space(&msgctx->versions); return &versions[count-1]; } static inline void sieve_message_version_free(struct sieve_message_version *version) { if (version->edit_mail != NULL) { edit_mail_unwrap(&version->edit_mail); version->edit_mail = NULL; } if (version->mail != NULL) { mail_free(&version->mail); mailbox_transaction_rollback(&version->trans); mailbox_free(&version->box); version->mail = NULL; } } /* * Message context object */ struct sieve_message_context * sieve_message_context_create(struct sieve_instance *svinst, struct mail_user *mail_user, const struct sieve_message_data *msgdata) { struct sieve_message_context *msgctx; msgctx = i_new(struct sieve_message_context, 1); msgctx->refcount = 1; msgctx->svinst = svinst; msgctx->mail_user = mail_user; msgctx->msgdata = msgdata; i_gettimeofday(&msgctx->time); sieve_message_context_reset(msgctx); return msgctx; } void sieve_message_context_ref(struct sieve_message_context *msgctx) { msgctx->refcount++; } static void sieve_message_context_clear(struct sieve_message_context *msgctx) { struct sieve_message_version *versions; unsigned int count, i; if (msgctx->pool != NULL) { versions = array_get_modifiable(&msgctx->versions, &count); for (i = 0; i < count; i++) sieve_message_version_free(&versions[i]); pool_unref(&(msgctx->pool)); } } void sieve_message_context_unref(struct sieve_message_context **msgctx) { i_assert((*msgctx)->refcount > 0); if (--(*msgctx)->refcount != 0) return; if ((*msgctx)->raw_mail_user != NULL) mail_user_unref(&(*msgctx)->raw_mail_user); sieve_message_context_clear(*msgctx); if ((*msgctx)->context_pool != NULL) pool_unref(&((*msgctx)->context_pool)); i_free(*msgctx); *msgctx = NULL; } static void sieve_message_context_flush(struct sieve_message_context *msgctx) { pool_t pool; if (msgctx->context_pool != NULL) pool_unref(&(msgctx->context_pool)); msgctx->context_pool = pool = pool_alloconly_create("sieve_message_context_data", 2048); p_array_init(&msgctx->ext_contexts, pool, sieve_extensions_get_count(msgctx->svinst)); p_array_init(&msgctx->cached_body_parts, pool, 8); p_array_init(&msgctx->return_body_parts, pool, 8); msgctx->raw_body = NULL; } void sieve_message_context_reset(struct sieve_message_context *msgctx) { sieve_message_context_clear(msgctx); msgctx->pool = pool_alloconly_create("sieve_message_context", 1024); p_array_init(&msgctx->versions, msgctx->pool, 4); sieve_message_context_flush(msgctx); } pool_t sieve_message_context_pool(struct sieve_message_context *msgctx) { return msgctx->context_pool; } void sieve_message_context_time(struct sieve_message_context *msgctx, struct timeval *time) { *time = msgctx->time; } /* Extension support */ void sieve_message_context_extension_set(struct sieve_message_context *msgctx, const struct sieve_extension *ext, void *context) { if (ext->id < 0) return; array_idx_set(&msgctx->ext_contexts, (unsigned int)ext->id, &context); } void *sieve_message_context_extension_get(struct sieve_message_context *msgctx, const struct sieve_extension *ext) { void *const *ctx; if (ext->id < 0 || ext->id >= (int)array_count(&msgctx->ext_contexts)) return NULL; ctx = array_idx(&msgctx->ext_contexts, (unsigned int)ext->id); return *ctx; } /* Envelope */ const struct smtp_address * sieve_message_get_orig_recipient(struct sieve_message_context *msgctx) { const struct sieve_message_data *msgdata = msgctx->msgdata; const struct smtp_address *orcpt_to = NULL; if (msgdata->envelope.rcpt_params != NULL) { orcpt_to = msgdata->envelope.rcpt_params->orcpt.addr; if (!smtp_address_isnull(orcpt_to)) return orcpt_to; } orcpt_to = msgdata->envelope.rcpt_to; return (!smtp_address_isnull(orcpt_to) ? orcpt_to : NULL); } const struct smtp_address * sieve_message_get_final_recipient(struct sieve_message_context *msgctx) { const struct sieve_message_data *msgdata = msgctx->msgdata; const struct smtp_address *rcpt_to = msgdata->envelope.rcpt_to; return (!smtp_address_isnull(rcpt_to) ? rcpt_to : NULL); } const struct smtp_address * sieve_message_get_sender(struct sieve_message_context *msgctx) { const struct sieve_message_data *msgdata = msgctx->msgdata; const struct smtp_address *mail_from = msgdata->envelope.mail_from; return (!smtp_address_isnull(mail_from) ? mail_from : NULL); } /* * Mail */ int sieve_message_substitute(struct sieve_message_context *msgctx, struct istream *input) { static const char *wanted_headers[] = { "From", "Message-ID", "Subject", "Return-Path", NULL }; static const struct smtp_address default_sender = { .localpart = DEFAULT_ENVELOPE_SENDER, .domain = NULL, }; struct mail_user *mail_user = msgctx->mail_user; struct sieve_message_version *version; struct mailbox_header_lookup_ctx *headers_ctx; struct mailbox *box = NULL; const struct smtp_address *sender; int ret; i_assert(input->blocking); if (msgctx->raw_mail_user == NULL) { struct mail_storage_service_ctx *storage_service = mail_storage_service_user_get_service_ctx( mail_user->service_user); struct settings_instance *set_instance = mail_storage_service_user_get_settings_instance(mail_user->service_user); msgctx->raw_mail_user = raw_storage_create_from_set(storage_service, set_instance); } i_stream_seek(input, 0); sender = sieve_message_get_sender(msgctx); sender = (sender == NULL ? &default_sender : sender); ret = raw_mailbox_alloc_stream(msgctx->raw_mail_user, input, (time_t)-1, smtp_address_encode(sender), &box); if (ret < 0) { e_error(msgctx->svinst->event, "can't open substituted mail as raw: %s", mailbox_get_last_internal_error(box, NULL)); return -1; } if (msgctx->substitute_snapshot) { version = sieve_message_version_new(msgctx); } else { version = sieve_message_version_get(msgctx); sieve_message_version_free(version); } version->box = box; version->trans = mailbox_transaction_begin(box, 0, __func__); headers_ctx = mailbox_header_lookup_init(box, wanted_headers); version->mail = mail_alloc(version->trans, 0, headers_ctx); mailbox_header_lookup_unref(&headers_ctx); mail_set_seq(version->mail, 1); sieve_message_context_flush(msgctx); msgctx->substitute_snapshot = FALSE; msgctx->edit_snapshot = FALSE; return 1; } struct mail *sieve_message_get_mail(struct sieve_message_context *msgctx) { const struct sieve_message_version *versions; unsigned int count; versions = array_get(&msgctx->versions, &count); if (count == 0) return msgctx->msgdata->mail; if (versions[count-1].edit_mail != NULL) return edit_mail_get_mail(versions[count-1].edit_mail); return versions[count-1].mail; } struct edit_mail *sieve_message_edit(struct sieve_message_context *msgctx) { struct sieve_message_version *version; version = sieve_message_version_get(msgctx); if (version->edit_mail == NULL) { version->edit_mail = edit_mail_wrap( (version->mail == NULL ? msgctx->msgdata->mail : version->mail)); } else if (msgctx->edit_snapshot) { version->edit_mail = edit_mail_snapshot(version->edit_mail); } msgctx->edit_snapshot = FALSE; return version->edit_mail; } void sieve_message_snapshot(struct sieve_message_context *msgctx) { msgctx->edit_snapshot = TRUE; msgctx->substitute_snapshot = TRUE; } /* * Message header list */ /* Forward declarations */ static int sieve_message_header_list_next_item(struct sieve_header_list *_hdrlist, const char **name_r, string_t **value_r); static int sieve_message_header_list_next_value(struct sieve_stringlist *_strlist, string_t **value_r); static void sieve_message_header_list_reset(struct sieve_stringlist *_strlist); /* String list object */ struct sieve_message_header_list { struct sieve_header_list hdrlist; struct sieve_stringlist *field_names; const char *header_name; const char *const *headers; int headers_index; bool mime_decode:1; }; struct sieve_header_list * sieve_message_header_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_names, bool mime_decode) { struct sieve_message_header_list *hdrlist; hdrlist = t_new(struct sieve_message_header_list, 1); hdrlist->hdrlist.strlist.runenv = renv; hdrlist->hdrlist.strlist.exec_status = SIEVE_EXEC_OK; hdrlist->hdrlist.strlist.next_item = sieve_message_header_list_next_value; hdrlist->hdrlist.strlist.reset = sieve_message_header_list_reset; hdrlist->hdrlist.next_item = sieve_message_header_list_next_item; hdrlist->field_names = field_names; hdrlist->mime_decode = mime_decode; return &hdrlist->hdrlist; } // NOTE: get rid of this once we have a proper Sieve string type static inline string_t *_header_right_trim(const char *raw) { string_t *result; const char *p, *pend; pend = raw + strlen(raw); if (raw == pend) { result = t_str_new(1); } else { for (p = pend-1; p >= raw; p--) { if (*p != ' ' && *p != '\t') break; } result = t_str_new(p - raw + 1); str_append_data(result, raw, p - raw + 1); } return result; } /* String list implementation */ static int sieve_message_header_list_next_item(struct sieve_header_list *_hdrlist, const char **name_r, string_t **value_r) { struct sieve_message_header_list *hdrlist = (struct sieve_message_header_list *)_hdrlist; const struct sieve_runtime_env *renv = _hdrlist->strlist.runenv; struct mail *mail = sieve_message_get_mail(renv->msgctx); if (name_r != NULL) *name_r = NULL; *value_r = NULL; /* Check for end of current header list */ if (hdrlist->headers == NULL) { hdrlist->headers_index = 0; } else if (hdrlist->headers[hdrlist->headers_index] == NULL) { hdrlist->headers = NULL; hdrlist->headers_index = 0; } /* Fetch next header */ while (hdrlist->headers == NULL) { string_t *hdr_item = NULL; int ret; /* Read next header name from source list */ if ((ret = sieve_stringlist_next_item(hdrlist->field_names, &hdr_item)) <= 0) return ret; hdrlist->header_name = str_c(hdr_item); if (_hdrlist->strlist.trace) { sieve_runtime_trace (renv, 0, "extracting '%s' headers from message", str_sanitize(str_c(hdr_item), 80)); } /* Fetch all matching headers from the e-mail */ if (hdrlist->mime_decode) { ret = mail_get_headers_utf8(mail, str_c(hdr_item), &hdrlist->headers); } else { ret = mail_get_headers(mail, str_c(hdr_item), &hdrlist->headers); } if (ret < 0) { _hdrlist->strlist.exec_status = sieve_runtime_mail_error( renv, mail, "failed to read header field '%s'", str_c(hdr_item)); return -1; } if (ret == 0 || hdrlist->headers[0] == NULL) { /* Try next item when no headers found */ hdrlist->headers = NULL; } } /* Return next item */ if (name_r != NULL) *name_r = hdrlist->header_name; *value_r = _header_right_trim( hdrlist->headers[hdrlist->headers_index++]); return 1; } static int sieve_message_header_list_next_value(struct sieve_stringlist *_strlist, string_t **value_r) { struct sieve_header_list *hdrlist = (struct sieve_header_list *)_strlist; return sieve_message_header_list_next_item(hdrlist, NULL, value_r); } static void sieve_message_header_list_reset(struct sieve_stringlist *strlist) { struct sieve_message_header_list *hdrlist = (struct sieve_message_header_list *)strlist; hdrlist->headers = NULL; hdrlist->headers_index = 0; sieve_stringlist_reset(hdrlist->field_names); } /* * Header override operand */ const struct sieve_operand_class sieve_message_override_operand_class = { "header-override" }; bool sieve_opr_message_override_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct sieve_message_override svmo; const struct sieve_message_override_def *hodef; if (!sieve_opr_object_dump(denv, &sieve_message_override_operand_class, address, &svmo.object)) return FALSE; hodef = svmo.def = (const struct sieve_message_override_def *)svmo.object.def; if (hodef->dump_context != NULL) { sieve_code_descend(denv); if (!hodef->dump_context(&svmo, denv, address)) return FALSE; sieve_code_ascend(denv); } return TRUE; } int sieve_opr_message_override_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_message_override *svmo) { const struct sieve_message_override_def *hodef; int ret; svmo->context = NULL; if (!sieve_opr_object_read(renv, &sieve_message_override_operand_class, address, &svmo->object)) return SIEVE_EXEC_BIN_CORRUPT; hodef = svmo->def = (const struct sieve_message_override_def *)svmo->object.def; if (hodef->read_context != NULL && (ret = hodef->read_context(svmo, renv, address, &svmo->context)) <= 0) return ret; return SIEVE_EXEC_OK; } /* * Optional operands */ int sieve_message_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code) { signed int _opt_code = 0; bool final = FALSE, opok = TRUE; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } while (opok) { int opt; if ((opt = sieve_addrmatch_opr_optional_dump(denv, address, opt_code)) <= 0) return opt; if (*opt_code == SIEVE_OPT_MESSAGE_OVERRIDE) { opok = sieve_opr_message_override_dump(denv, address); } else { return (final ? -1 : 1); } } return -1; } int sieve_message_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code, int *exec_status, struct sieve_address_part *addrp, struct sieve_match_type *mcht, struct sieve_comparator *cmp, ARRAY_TYPE(sieve_message_override) *svmos) { signed int _opt_code = 0; bool final = FALSE; int ret; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } if (exec_status != NULL) *exec_status = SIEVE_EXEC_OK; for (;;) { int opt; if ((opt = sieve_addrmatch_opr_optional_read( renv, address, opt_code, exec_status, addrp, mcht, cmp)) <= 0) return opt; if (*opt_code == SIEVE_OPT_MESSAGE_OVERRIDE) { struct sieve_message_override svmo; const struct sieve_message_override *svmo_idx; unsigned int count, i; if ((ret = sieve_opr_message_override_read( renv, address, &svmo)) <= 0) { if (exec_status != NULL) *exec_status = ret; return -1; } if (!array_is_created(svmos)) t_array_init(svmos, 8); /* insert in sorted sequence */ svmo_idx = array_get(svmos, &count); for (i = 0; i < count; i++) { if (svmo.def->sequence < svmo_idx[i].def->sequence) { array_insert(svmos, i, &svmo, 1); break; } } if (count == i) array_append(svmos, &svmo, 1); } else { if (final) { sieve_runtime_trace_error( renv, "invalid optional operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } return 1; } } i_unreached(); } /* * Message header */ int sieve_message_get_header_fields(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_names, ARRAY_TYPE(sieve_message_override) *svmos, bool mime_decode, struct sieve_stringlist **fields_r) { const struct sieve_message_override *svmo; unsigned int count, i; int ret; if (svmos == NULL || !array_is_created(svmos) || array_count(svmos) == 0) { struct sieve_header_list *headers; headers = sieve_message_header_list_create( renv, field_names, mime_decode); *fields_r = &headers->strlist; return SIEVE_EXEC_OK; } svmo = array_get(svmos, &count); if (svmo[0].def->sequence == 0 && svmo[0].def->header_override != NULL) { *fields_r = field_names; } else { struct sieve_header_list *headers; headers = sieve_message_header_list_create(renv, field_names, mime_decode); *fields_r = &headers->strlist; } for (i = 0; i < count; i++) { if (svmo[i].def->header_override != NULL && (ret = svmo[i].def->header_override( &svmo[i], renv, mime_decode, fields_r)) <= 0) return ret; } return SIEVE_EXEC_OK; } /* * Message part */ struct sieve_message_part * sieve_message_part_parent(struct sieve_message_part *mpart) { return mpart->parent; } struct sieve_message_part * sieve_message_part_next(struct sieve_message_part *mpart) { return mpart->next; } struct sieve_message_part * sieve_message_part_children(struct sieve_message_part *mpart) { return mpart->children; } const char * sieve_message_part_content_type(struct sieve_message_part *mpart) { return mpart->content_type; } const char * sieve_message_part_content_disposition(struct sieve_message_part *mpart) { return mpart->content_disposition; } int sieve_message_part_get_first_header(struct sieve_message_part *mpart, const char *field, const char **value_r) { const struct sieve_message_header *headers; unsigned int i, count; headers = array_get(&mpart->headers, &count); for (i = 0; i < count; i++) { if (strcasecmp(headers[i].name, field) == 0) { i_assert(headers[i].value[headers[i].value_len] == '\0'); *value_r = (const char *)headers[i].value; return 1; } } *value_r = NULL; return 0; } void sieve_message_part_get_data(struct sieve_message_part *mpart, struct sieve_message_part_data *data, bool text) { i_zero(data); data->content_type = mpart->content_type; data->content_disposition = mpart->content_disposition; if (!text) { data->content = mpart->decoded_body; data->size = mpart->decoded_body_size; } else if (mpart->children != NULL) { data->content = ""; data->size = 0; } else { data->content = mpart->text_body; data->size = mpart->text_body_size; } } /* * Message body */ static void str_replace_nuls(string_t *str) { char *data = str_c_modifiable(str); unsigned int i, len = str_len(str); for (i = 0; i < len; i++) { if (data[i] == '\0') data[i] = ' '; } } static bool _is_wanted_content_type(const char *const *wanted_types, const char *content_type) ATTR_NULL(1) { const char *subtype; size_t type_len; if (wanted_types == NULL) return TRUE; subtype = strchr(content_type, '/'); type_len = (subtype == NULL ? strlen(content_type) : (size_t)(subtype - content_type)); i_assert(wanted_types != NULL); for (; *wanted_types != NULL; wanted_types++) { const char *wanted_subtype; if (**wanted_types == '\0') { /* empty string matches everything */ return TRUE; } wanted_subtype = strchr(*wanted_types, '/'); if (wanted_subtype == NULL) { /* match only main type */ if (strlen(*wanted_types) == type_len && strncasecmp(*wanted_types, content_type, type_len) == 0) return TRUE; } else { /* match whole type/subtype */ if (strcasecmp(*wanted_types, content_type) == 0) return TRUE; } } return FALSE; } static bool sieve_message_body_get_return_parts(const struct sieve_runtime_env *renv, const char *const *wanted_types, bool extract_text) { struct sieve_message_context *msgctx = renv->msgctx; struct sieve_message_part *const *body_parts; unsigned int i, count; struct sieve_message_part_data *return_part; /* Check whether any body parts are cached already */ body_parts = array_get(&msgctx->cached_body_parts, &count); if (count == 0) return FALSE; /* Clear result array */ array_clear(&msgctx->return_body_parts); /* Fill result array with requested content_types */ for (i = 0; i < count; i++) { if (!body_parts[i]->have_body) { /* Part has no body; according to RFC this MUST not match to anything and therefore it is not included in the result. */ continue; } /* Skip content types that are not requested */ if (!_is_wanted_content_type(wanted_types, body_parts[i]->content_type)) continue; /* Add new item to the result */ return_part = array_append_space(&msgctx->return_body_parts); return_part->content_type = body_parts[i]->content_type; return_part->content_disposition = body_parts[i]->content_disposition; /* Depending on whether a decoded body part is requested, the appropriate cache item is read. If it is missing, this function fails and the cache needs to be completed by sieve_message_parts_add_missing(). */ if (extract_text) { if (body_parts[i]->text_body == NULL) return FALSE; return_part->content = body_parts[i]->text_body; return_part->size = body_parts[i]->text_body_size; } else { if (body_parts[i]->decoded_body == NULL) return FALSE; return_part->content = body_parts[i]->decoded_body; return_part->size = body_parts[i]->decoded_body_size; } } return TRUE; } static void sieve_message_part_save(const struct sieve_runtime_env *renv, buffer_t *buf, struct sieve_message_part *body_part, bool extract_text) { struct sieve_message_context *msgctx = renv->msgctx; pool_t pool = msgctx->context_pool; buffer_t *result_buf, *text_buf = NULL; char *part_data; size_t part_size; /* Extract text if requested */ result_buf = buf; if (extract_text && body_part->children == NULL && !body_part->epilogue) { if (buf->used > 0 && mail_html2text_content_type_match(body_part->content_type)) { struct mail_html2text *html2text; text_buf = buffer_create_dynamic(default_pool, 4096); /* Remove HTML markup */ html2text = mail_html2text_init(0); mail_html2text_more(html2text, buf->data, buf->used, text_buf); mail_html2text_deinit(&html2text); result_buf = text_buf; } } /* Add terminating NUL to the body part buffer */ buffer_append_c(result_buf, '\0'); /* Make copy of the buffer */ part_data = p_malloc(pool, result_buf->used); memcpy(part_data, result_buf->data, result_buf->used); part_size = result_buf->used - 1; /* Free text buffer if used */ if (text_buf != NULL) buffer_free(&text_buf); /* Depending on whether the part is processed into text, store message body in the appropriate cache location. */ if (!extract_text) { body_part->decoded_body = part_data; body_part->decoded_body_size = part_size; } else { body_part->text_body = part_data; body_part->text_body_size = part_size; } /* Clear buffer */ buffer_set_used_size(buf, 0); } static const char *_parse_content_type(const struct message_header_line *hdr) { struct rfc822_parser_context parser; string_t *content_type; /* Initialize parsing */ rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL); (void)rfc822_skip_lwsp(&parser); /* Parse content type */ content_type = t_str_new(64); if (rfc822_parse_content_type(&parser, content_type) < 0) return ""; /* Content-type value must end here, otherwise it is invalid after all */ (void)rfc822_skip_lwsp(&parser); if (parser.data != parser.end && *parser.data != ';') return ""; /* Success */ return str_c(content_type); } static const char * _parse_content_disposition(const struct message_header_line *hdr) { struct rfc822_parser_context parser; string_t *content_disp; /* Initialize parsing */ rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL); (void)rfc822_skip_lwsp(&parser); /* Parse content type */ content_disp = t_str_new(64); if (rfc822_parse_mime_token(&parser, content_disp) < 0) return ""; /* Content-type value must end here, otherwise it is invalid after all */ (void)rfc822_skip_lwsp(&parser); if (parser.data != parser.end && *parser.data != ';') return ""; /* Success */ return str_c(content_disp); } /* sieve_message_parts_add_missing(): * Add requested message body parts to the cache that are missing. */ static int sieve_message_parts_add_missing(const struct sieve_runtime_env *renv, const char *const *content_types, bool extract_text, bool iter_all) ATTR_NULL(2) { struct sieve_message_context *msgctx = renv->msgctx; pool_t pool = msgctx->context_pool; struct mail *mail = sieve_message_get_mail(renv->msgctx); struct message_parser_settings mparser_set = { .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP, .flags = MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS, }; ARRAY(struct sieve_message_header) headers; struct sieve_message_part *body_part, *header_part, *last_part; struct message_parser_ctx *parser; struct message_decoder_context *decoder; struct message_block block, decoded; struct message_part *mparts, *prev_mpart = NULL; buffer_t *buf; struct istream *input; unsigned int idx = 0; bool save_body = FALSE, have_all; string_t *hdr_content = NULL; /* First check whether any are missing */ if (!iter_all && sieve_message_body_get_return_parts( renv, content_types, extract_text)) { /* Cache hit; all are present */ return SIEVE_EXEC_OK; } /* Get the message stream */ if (mail_get_stream(mail, NULL, NULL, &input) < 0) { return sieve_runtime_mail_error( renv, mail, "failed to open input message"); } if (mail_get_parts(mail, &mparts) < 0) { return sieve_runtime_mail_error( renv, mail, "failed to parse input message parts"); } buf = buffer_create_dynamic(default_pool, 4096); body_part = header_part = last_part = NULL; if (iter_all) { t_array_init(&headers, 64); hdr_content = t_str_new(512); mparser_set.hdr_flags |= MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE; } else { i_zero(&headers); } /* Initialize body decoder */ decoder = message_decoder_init(NULL, 0); // FIXME: currently not tested with edit-mail. //parser = message_parser_init_from_parts(parts, input, // hparser_flags, mparser_flags); parser = message_parser_init(pool_datastack_create(), input, &mparser_set); while (message_parser_parse_next_block(parser, &block) > 0) { struct sieve_message_part **body_part_idx; struct message_header_line *hdr = block.hdr; struct sieve_message_header *header; unsigned char *data; if (block.part != prev_mpart) { bool message_rfc822 = FALSE; /* Save previous body part */ if (body_part != NULL) { /* Treat message/rfc822 separately; headers become content */ if (block.part->parent == prev_mpart && strcmp(body_part->content_type, "message/rfc822") == 0) { message_rfc822 = TRUE; } else if (save_body) { sieve_message_part_save( renv, buf, body_part, extract_text); } if (iter_all && !array_is_created(&body_part->headers) && array_count(&headers) > 0) { p_array_init(&body_part->headers, pool, array_count(&headers)); array_copy(&body_part->headers.arr, 0, &headers.arr, 0, array_count(&headers)); } } /* Start processing next part */ body_part_idx = array_idx_get_space( &msgctx->cached_body_parts, idx); if (*body_part_idx == NULL) { *body_part_idx = p_new( pool, struct sieve_message_part, 1); } body_part = *body_part_idx; body_part->content_type = "text/plain"; if (iter_all) array_clear(&headers); /* Copy tree structure */ if (block.part->context != NULL) { struct sieve_message_part *epipart = (struct sieve_message_part *) block.part->context; i_assert(epipart != NULL); /* multipart epilogue */ body_part->content_type = epipart->content_type; body_part->have_body = TRUE; body_part->epilogue = TRUE; save_body = iter_all || _is_wanted_content_type(content_types, body_part->content_type); } else { struct sieve_message_part *parent = NULL; if (block.part->parent != NULL) { body_part->parent = parent = (struct sieve_message_part *) block.part->parent->context; } /* new part */ block.part->context = body_part; if (last_part != NULL) { i_assert(parent != NULL); if (last_part->parent == parent) { last_part->next = body_part; } else if (parent->children == NULL) { parent->children = body_part; } else { struct sieve_message_part *child = parent->children; while (child->next != NULL && child != body_part) child = child->next; if (child != body_part) child->next = body_part; } } } last_part = body_part; /* If this is message/rfc822 content, retain the enveloping part for storing headers as content. */ if (message_rfc822) { i_assert(idx > 0); body_part_idx = array_idx_modifiable( &msgctx->cached_body_parts, idx-1); header_part = *body_part_idx; } else { header_part = NULL; } prev_mpart = block.part; idx++; } if (hdr != NULL || block.size == 0) { enum { _HDR_CONTENT_TYPE, _HDR_CONTENT_DISPOSITION, _HDR_OTHER } hdr_field; /* Reading headers */ i_assert(body_part != NULL); /* Decode block */ (void)message_decoder_decode_next_block(decoder, &block, &decoded); /* Check for end of headers */ if (hdr == NULL) { /* Save headers for message/rfc822 part */ if (header_part != NULL) { sieve_message_part_save(renv, buf, header_part, FALSE); header_part = NULL; } /* Save bodies only if we have a wanted content type */ save_body = iter_all || _is_wanted_content_type(content_types, body_part->content_type); continue; } /* Encountered the empty line that indicates the end of the headers and the start of the body */ if (hdr->eoh) { body_part->have_body = TRUE; continue; } else if (header_part != NULL) { /* Save message/rfc822 header as part content */ if (hdr->continued) { buffer_append(buf, hdr->value, hdr->value_len); } else { buffer_append(buf, hdr->name, hdr->name_len); buffer_append(buf, hdr->middle, hdr->middle_len); buffer_append(buf, hdr->value, hdr->value_len); } if (!hdr->no_newline) buffer_append(buf, "\r\n", 2); } if (strcasecmp(hdr->name, "Content-Type") == 0) hdr_field = _HDR_CONTENT_TYPE; else if (strcasecmp(hdr->name, "Content-Disposition") == 0) hdr_field = _HDR_CONTENT_DISPOSITION; else if (iter_all && !array_is_created(&body_part->headers)) hdr_field = _HDR_OTHER; else { /* Not interested in this header */ continue; } /* Header can have folding whitespace. Acquire the full value before continuing */ if (hdr->continues) { hdr->use_full_value = TRUE; continue; } if (iter_all && !array_is_created(&body_part->headers)) { const unsigned char *value, *vp; size_t vlen; /* Add header */ header = array_append_space(&headers); header->name = p_strdup(pool, hdr->name); /* Trim end of field value (not done by parser) */ value = hdr->full_value; vp = value + hdr->full_value_len; while (vp > value && (vp[-1] == '\t' || vp[-1] == ' ')) vp--; vlen = (size_t)(vp - value); /* Decode MIME encoded-words. */ str_truncate(hdr_content, 0); message_header_decode_utf8(value, vlen, hdr_content, NULL); if (vlen != str_len(hdr_content) || strncmp(str_c(hdr_content), (const char *)value, vlen) != 0) { if (strlen(str_c(hdr_content)) != str_len(hdr_content)) { /* replace NULs with spaces */ str_replace_nuls(hdr_content); } /* store raw */ data = p_malloc(pool, vlen + 1); data[vlen] = '\0'; header->value = memcpy(data, value, vlen); header->value_len = vlen; /* store decoded */ data = p_malloc(pool, str_len(hdr_content) + 1); data[str_len(hdr_content)] = '\0'; header->utf8_value = memcpy( data, str_data(hdr_content), str_len(hdr_content)); header->utf8_value_len = str_len(hdr_content); } else { /* raw == decoded */ data = p_malloc(pool, vlen + 1); data[vlen] = '\0'; header->value = header->utf8_value = memcpy(data, value, vlen); header->value_len = header->utf8_value_len = vlen; } if (hdr_field == _HDR_OTHER) continue; } /* Parse the content type from the Content-type header */ T_BEGIN { switch (hdr_field) { case _HDR_CONTENT_TYPE: body_part->content_type = p_strdup(pool, _parse_content_type(block.hdr)); break; case _HDR_CONTENT_DISPOSITION: body_part->content_disposition = p_strdup(pool, _parse_content_disposition(block.hdr)); break; default: i_unreached(); } } T_END; continue; } /* Reading body */ if (save_body) { (void)message_decoder_decode_next_block( decoder, &block, &decoded); buffer_append(buf, decoded.data, decoded.size); } } /* Even with an empty message there was at least the "end of headers" block, which set the body_part. */ i_assert(body_part != NULL); /* Save last body part if necessary */ if (header_part != NULL) sieve_message_part_save(renv, buf, header_part, FALSE); else if (save_body) sieve_message_part_save(renv, buf, body_part, extract_text); if (iter_all && !array_is_created(&body_part->headers) && array_count(&headers) > 0) { p_array_init(&body_part->headers, pool, array_count(&headers)); array_copy(&body_part->headers.arr, 0, &headers.arr, 0, array_count(&headers)); } /* Try to fill the return_body_parts array once more */ have_all = iter_all || sieve_message_body_get_return_parts(renv, content_types, extract_text); /* This time, failure is a bug */ i_assert(have_all); /* Cleanup */ (void)message_parser_deinit(&parser, &mparts); message_decoder_deinit(&decoder); buffer_free(&buf); /* Return status */ if (input->stream_errno != 0) { sieve_runtime_critical(renv, NULL, "failed to read input message", "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); return SIEVE_EXEC_TEMP_FAILURE; } return SIEVE_EXEC_OK; } int sieve_message_body_get_content(const struct sieve_runtime_env *renv, const char *const *content_types, struct sieve_message_part_data **parts_r) { struct sieve_message_context *msgctx = renv->msgctx; int status; T_BEGIN { /* Fill the return_body_parts array */ status = sieve_message_parts_add_missing(renv, content_types, FALSE, FALSE); } T_END; /* Check status */ if (status <= 0) return status; /* Return the array of body items */ (void)array_append_space(&msgctx->return_body_parts); /* NULL-terminate */ *parts_r = array_idx_modifiable(&msgctx->return_body_parts, 0); return status; } int sieve_message_body_get_text(const struct sieve_runtime_env *renv, struct sieve_message_part_data **parts_r) { static const char *const _text_content_types[] = { "application/xhtml+xml", "text", NULL }; struct sieve_message_context *msgctx = renv->msgctx; int status; /* We currently only support extracting plain text from: - text/html -> HTML - application/xhtml+xml -> XHTML Other text types are read as is. Any non-text types are skipped. */ T_BEGIN { /* Fill the return_body_parts array */ status = sieve_message_parts_add_missing( renv, _text_content_types, TRUE, FALSE); } T_END; /* Check status */ if (status <= 0) return status; /* Return the array of body items */ (void)array_append_space(&msgctx->return_body_parts); /* NULL-terminate */ *parts_r = array_idx_modifiable(&msgctx->return_body_parts, 0); return status; } int sieve_message_body_get_raw(const struct sieve_runtime_env *renv, struct sieve_message_part_data **parts_r) { struct sieve_message_context *msgctx = renv->msgctx; struct sieve_message_part_data *return_part; buffer_t *buf; if (msgctx->raw_body == NULL) { struct mail *mail = sieve_message_get_mail(renv->msgctx); struct istream *input; struct message_size hdr_size, body_size; const unsigned char *data; size_t size; int ret; msgctx->raw_body = buf = buffer_create_dynamic(msgctx->context_pool, 1024*64); /* Get stream for message */ if (mail_get_stream(mail, &hdr_size, &body_size, &input) < 0) { return sieve_runtime_mail_error( renv, mail, "failed to open input message"); } /* Skip stream to beginning of body */ i_stream_skip(input, hdr_size.physical_size); /* Read raw message body */ while ((ret = i_stream_read_more(input, &data, &size)) > 0) { buffer_append(buf, data, size); i_stream_skip(input, size); } if (ret < 0 && input->stream_errno != 0) { sieve_runtime_critical( renv, NULL, "failed to read input message", "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); return SIEVE_EXEC_TEMP_FAILURE; } /* Add terminating NUL to the body part buffer */ buffer_append_c(buf, '\0'); } else { buf = msgctx->raw_body; } /* Clear result array */ array_clear(&msgctx->return_body_parts); if (buf->used > 1) { const char *data = (const char *)buf->data; size_t size = buf->used - 1; i_assert(data[size] == '\0'); /* Add single item to the result */ return_part = array_append_space(&msgctx->return_body_parts); return_part->content = data; return_part->size = size; } /* Return the array of body items */ (void)array_append_space(&msgctx->return_body_parts); /* NULL-terminate */ *parts_r = array_idx_modifiable(&msgctx->return_body_parts, 0); return SIEVE_EXEC_OK; } /* * Message part iterator */ int sieve_message_part_iter_init(struct sieve_message_part_iter *iter, const struct sieve_runtime_env *renv) { struct sieve_message_context *msgctx = renv->msgctx; struct sieve_message_part *const *parts; unsigned int count; int status; T_BEGIN { /* Fill the return_body_parts array */ status = sieve_message_parts_add_missing( renv, NULL, TRUE, TRUE); } T_END; /* Check status */ if (status <= 0) return status; i_zero(iter); iter->renv = renv; iter->index = 0; iter->offset = 0; parts = array_get(&msgctx->cached_body_parts, &count); if (count == 0) iter->root = NULL; else iter->root = parts[0]; return SIEVE_EXEC_OK; } void sieve_message_part_iter_subtree(struct sieve_message_part_iter *iter, struct sieve_message_part_iter *subtree) { const struct sieve_runtime_env *renv = iter->renv; struct sieve_message_context *msgctx = renv->msgctx; struct sieve_message_part *const *parts; unsigned int count; *subtree = *iter; parts = array_get(&msgctx->cached_body_parts, &count); if (subtree->index >= count) subtree->root = NULL; else subtree->root = parts[subtree->index]; subtree->offset = subtree->index; } void sieve_message_part_iter_children(struct sieve_message_part_iter *iter, struct sieve_message_part_iter *child) { const struct sieve_runtime_env *renv = iter->renv; struct sieve_message_context *msgctx = renv->msgctx; struct sieve_message_part *const *parts; unsigned int count; *child = *iter; parts = array_get(&msgctx->cached_body_parts, &count); if ((child->index+1) >= count || parts[child->index]->children == NULL) child->root = NULL; else child->root = parts[child->index++]; child->offset = child->index; } struct sieve_message_part * sieve_message_part_iter_current(struct sieve_message_part_iter *iter) { const struct sieve_runtime_env *renv = iter->renv; struct sieve_message_context *msgctx = renv->msgctx; struct sieve_message_part *const *parts; unsigned int count; if (iter->root == NULL) return NULL; parts = array_get(&msgctx->cached_body_parts, &count); if (iter->index >= count) return NULL; do { if (parts[iter->index] == iter->root->next) return NULL; if (parts[iter->index] == iter->root->parent) return NULL; } while (parts[iter->index]->epilogue && ++iter->index < count); if (iter->index >= count) return NULL; return parts[iter->index]; } struct sieve_message_part * sieve_message_part_iter_next(struct sieve_message_part_iter *iter) { const struct sieve_runtime_env *renv = iter->renv; struct sieve_message_context *msgctx = renv->msgctx; if (iter->index >= array_count(&msgctx->cached_body_parts)) return NULL; iter->index++; return sieve_message_part_iter_current(iter); } void sieve_message_part_iter_reset(struct sieve_message_part_iter *iter) { iter->index = iter->offset; } /* * MIME header list */ /* Forward declarations */ static int sieve_mime_header_list_next_item(struct sieve_header_list *_hdrlist, const char **name_r, string_t **value_r); static int sieve_mime_header_list_next_value(struct sieve_stringlist *_strlist, string_t **value_r); static void sieve_mime_header_list_reset(struct sieve_stringlist *_strlist); /* Header list object */ struct sieve_mime_header_list { struct sieve_header_list hdrlist; struct sieve_stringlist *field_names; struct sieve_message_part_iter part_iter; const char *header_name; const struct sieve_message_header *headers; unsigned int headers_index, headers_count; bool mime_decode:1; bool children:1; }; struct sieve_header_list * sieve_mime_header_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_names, struct sieve_message_part_iter *part_iter, bool mime_decode, bool children) { struct sieve_mime_header_list *hdrlist; hdrlist = t_new(struct sieve_mime_header_list, 1); hdrlist->hdrlist.strlist.runenv = renv; hdrlist->hdrlist.strlist.exec_status = SIEVE_EXEC_OK; hdrlist->hdrlist.strlist.next_item = sieve_mime_header_list_next_value; hdrlist->hdrlist.strlist.reset = sieve_mime_header_list_reset; hdrlist->hdrlist.next_item = sieve_mime_header_list_next_item; hdrlist->field_names = field_names; hdrlist->mime_decode = mime_decode; hdrlist->children = children; sieve_message_part_iter_subtree(part_iter, &hdrlist->part_iter); return &hdrlist->hdrlist; } /* MIME list implementation */ static void sieve_mime_header_list_next_name(struct sieve_mime_header_list *hdrlist) { struct sieve_message_part *mpart; sieve_message_part_iter_reset(&hdrlist->part_iter); mpart = sieve_message_part_iter_current(&hdrlist->part_iter); if (mpart != NULL && array_is_created(&mpart->headers)) { hdrlist->headers = array_get(&mpart->headers, &hdrlist->headers_count); hdrlist->headers_index = 0; } } static int sieve_mime_header_list_next_item(struct sieve_header_list *_hdrlist, const char **name_r, string_t **value_r) { struct sieve_mime_header_list *hdrlist = (struct sieve_mime_header_list *)_hdrlist; const struct sieve_runtime_env *renv = _hdrlist->strlist.runenv; if (name_r != NULL) *name_r = NULL; *value_r = NULL; for (;;) { /* Check for end of current header list */ if (hdrlist->headers_count == 0 || hdrlist->headers_index >= hdrlist->headers_count) { hdrlist->headers_count = 0; hdrlist->headers_index = 0; hdrlist->headers = NULL; } /* Fetch more headers */ while (hdrlist->headers_count == 0) { string_t *hdr_item = NULL; int ret; if (hdrlist->header_name != NULL && hdrlist->children) { struct sieve_message_part *mpart; mpart = sieve_message_part_iter_next( &hdrlist->part_iter); if (mpart != NULL && array_is_created(&mpart->headers)) { hdrlist->headers = array_get( &mpart->headers, &hdrlist->headers_count); hdrlist->headers_index = 0; } if (hdrlist->headers_count > 0) { if (_hdrlist->strlist.trace) { sieve_runtime_trace( renv, 0, "moving to next message part"); } break; } } /* Read next header name from source list */ if ((ret = sieve_stringlist_next_item( hdrlist->field_names, &hdr_item)) <= 0) return ret; hdrlist->header_name = str_c(hdr_item); if (_hdrlist->strlist.trace) { sieve_runtime_trace( renv, 0, "extracting '%s' headers from message part", str_sanitize(str_c(hdr_item), 80)); } sieve_mime_header_list_next_name(hdrlist); } for (; hdrlist->headers_index < hdrlist->headers_count; hdrlist->headers_index++) { const struct sieve_message_header *header = &hdrlist->headers[hdrlist->headers_index]; if (strcasecmp(header->name, hdrlist->header_name) == 0) { if (name_r != NULL) *name_r = hdrlist->header_name; if (hdrlist->mime_decode) { *value_r = t_str_new_const( (const char *)header->utf8_value, header->utf8_value_len); } else { *value_r = t_str_new_const( (const char *)header->value, header->value_len); } hdrlist->headers_index++; return 1; } } } i_unreached(); } static int sieve_mime_header_list_next_value(struct sieve_stringlist *_strlist, string_t **value_r) { struct sieve_header_list *hdrlist = (struct sieve_header_list *)_strlist; return sieve_mime_header_list_next_item(hdrlist, NULL, value_r); } static void sieve_mime_header_list_reset(struct sieve_stringlist *strlist) { struct sieve_mime_header_list *hdrlist = (struct sieve_mime_header_list *)strlist; sieve_stringlist_reset(hdrlist->field_names); hdrlist->header_name = NULL; } dovecot-pigeonhole-2.4.2/src/lib-sieve/ext-fileinto.c0000644000175100001700000001172615100335616024227 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension fileinto * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5228 * Implementation: full * Status: testing * */ #include "lib.h" #include "str-sanitize.h" #include "unichar.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-binary.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-result.h" /* * Forward declarations */ static const struct sieve_command_def fileinto_command; const struct sieve_operation_def fileinto_operation; const struct sieve_extension_def fileinto_extension; /* * Extension */ static bool ext_fileinto_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def fileinto_extension = { .name = "fileinto", .validator_load = ext_fileinto_validator_load, SIEVE_EXT_DEFINE_OPERATION(fileinto_operation), }; static bool ext_fileinto_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ sieve_validator_register_command(valdtr, ext, &fileinto_command); return TRUE; } /* * Fileinto command * * Syntax: * fileinto */ static bool cmd_fileinto_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_fileinto_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); static const struct sieve_command_def fileinto_command = { .identifier = "fileinto", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_fileinto_validate, .generate = cmd_fileinto_generate, }; /* * Fileinto operation */ static bool ext_fileinto_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_fileinto_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def fileinto_operation = { .mnemonic = "FILEINTO", .ext_def = &fileinto_extension, .dump = ext_fileinto_operation_dump, .execute = ext_fileinto_operation_execute, }; /* * Validation */ static bool cmd_fileinto_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; if (!sieve_validate_positional_argument(valdtr, cmd, arg, "folder", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; /* Check name validity when folder argument is not a variable */ if (sieve_argument_is_string_literal(arg)) { const char *folder = sieve_ast_argument_strc(arg), *error; if (!sieve_mailbox_check_name(folder, &error)) { sieve_command_validate_error( valdtr, cmd, "fileinto command: " "invalid folder name '%s' specified: %s", str_sanitize(folder, 256), error); return FALSE; } } return TRUE; } /* * Code generation */ static bool cmd_fileinto_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &fileinto_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool ext_fileinto_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "FILEINTO"); sieve_code_descend(denv); if (sieve_action_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return sieve_opr_string_dump(denv, address, "folder"); } /* * Execution */ static int ext_fileinto_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_side_effects_list *slist = NULL; string_t *folder; const char *error; bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS); int ret = 0; /* * Read operands */ /* Optional operands (side effects only) */ if (sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0) return ret; /* Folder operand */ ret = sieve_opr_string_read(renv, address, "folder", &folder); if (ret <= 0) return ret; /* * Perform operation */ if (trace) { sieve_runtime_trace(renv, 0, "fileinto action"); sieve_runtime_trace_descend(renv); } if (!sieve_mailbox_check_name(str_c(folder), &error)) { sieve_runtime_error( renv, NULL, "fileinto command: " "invalid folder name '%s' specified: %s", str_c(folder), error); return SIEVE_EXEC_FAILURE; } if (trace) { sieve_runtime_trace(renv, 0, "store message in mailbox '%s'", str_sanitize(str_c(folder), 80)); } /* Add action to result */ if (sieve_act_store_add_to_result(renv, "fileinto", slist, str_c(folder)) < 0) return SIEVE_EXEC_FAILURE; sieve_message_snapshot(renv->msgctx); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-size.c0000644000175100001700000001635315100335616023403 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" /* * Size test * * Syntax: * size <":over" / ":under"> */ static bool tst_size_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_size_pre_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_size_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_size_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def tst_size = { .identifier = "size", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_size_registered, .pre_validate = tst_size_pre_validate, .validate = tst_size_validate, .generate = tst_size_generate }; /* * Size operations */ static bool tst_size_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_size_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_size_over_operation = { .mnemonic = "SIZE-OVER", .code = SIEVE_OPERATION_SIZE_OVER, .dump = tst_size_operation_dump, .execute = tst_size_operation_execute }; const struct sieve_operation_def tst_size_under_operation = { .mnemonic = "SIZE-UNDER", .code = SIEVE_OPERATION_SIZE_UNDER, .dump = tst_size_operation_dump, .execute = tst_size_operation_execute }; /* * Context data */ struct tst_size_context_data { enum { SIZE_UNASSIGNED, SIZE_UNDER, SIZE_OVER } type; }; #define TST_SIZE_ERROR_DUP_TAG \ "exactly one of the ':under' or ':over' tags must be specified " \ "for the size test, but more were found" /* * Tag validation */ static bool tst_size_validate_over_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *)tst->data; if (ctx_data->type != SIZE_UNASSIGNED) { sieve_argument_validate_error(valdtr, *arg, TST_SIZE_ERROR_DUP_TAG); return FALSE; } ctx_data->type = SIZE_OVER; /* Delete this tag */ *arg = sieve_ast_arguments_detach(*arg, 1); return TRUE; } static bool tst_size_validate_under_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg ATTR_UNUSED, struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *)tst->data; if (ctx_data->type != SIZE_UNASSIGNED) { sieve_argument_validate_error(valdtr, *arg, TST_SIZE_ERROR_DUP_TAG); return FALSE; } ctx_data->type = SIZE_UNDER; /* Delete this tag */ *arg = sieve_ast_arguments_detach(*arg, 1); return TRUE; } /* * Test registration */ static const struct sieve_argument_def size_over_tag = { .identifier = "over", .validate = tst_size_validate_over_tag }; static const struct sieve_argument_def size_under_tag = { .identifier = "under", .validate = tst_size_validate_under_tag, }; static bool tst_size_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* Register our tags */ sieve_validator_register_tag(valdtr, cmd_reg, NULL, &size_over_tag, 0); sieve_validator_register_tag(valdtr, cmd_reg, NULL, &size_under_tag, 0); return TRUE; } /* * Test validation */ static bool tst_size_pre_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst) { struct tst_size_context_data *ctx_data; /* Assign context */ ctx_data = p_new(sieve_command_pool(tst), struct tst_size_context_data, 1); ctx_data->type = SIZE_UNASSIGNED; tst->data = ctx_data; return TRUE; } static bool tst_size_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *)tst->data; struct sieve_ast_argument *arg = tst->first_positional; if (ctx_data->type == SIZE_UNASSIGNED) { sieve_command_validate_error(valdtr, tst, "the size test requires either the :under or the :over tag " "to be specified"); return FALSE; } if (!sieve_validate_positional_argument(valdtr, tst, arg, "limit", 1, SAAT_NUMBER)) return FALSE; return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* * Code generation */ bool tst_size_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *)tst->data; if (ctx_data->type == SIZE_OVER) { sieve_operation_emit(cgenv->sblock, NULL, &tst_size_over_operation); } else { sieve_operation_emit(cgenv->sblock, NULL, &tst_size_under_operation); } /* Generate arguments */ if (!sieve_generate_arguments(cgenv, tst, NULL)) return FALSE; return TRUE; } /* * Code dump */ static bool tst_size_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(denv->oprtn)); sieve_code_descend(denv); return sieve_opr_number_dump(denv, address, "limit"); } /* * Code execution */ static inline bool tst_size_get(const struct sieve_runtime_env *renv, sieve_number_t *size) { struct mail *mail = sieve_message_get_mail(renv->msgctx); uoff_t psize; if (mail_get_physical_size(mail, &psize) < 0) return FALSE; *size = psize; return TRUE; } static int tst_size_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { sieve_number_t mail_size, limit; int ret; /* * Read operands */ /* Read size limit */ if ((ret = sieve_opr_number_read(renv, address, "limit", &limit)) <= 0) return ret; /* * Perform test */ /* Get the size of the message */ if (!tst_size_get(renv, &mail_size)) { /* FIXME: improve this error */ e_error(renv->event, "failed to assess message size"); return SIEVE_EXEC_FAILURE; } /* Perform the test */ if (sieve_operation_is(renv->oprtn, tst_size_over_operation)) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "size :over test"); if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING)) { sieve_runtime_trace_descend(renv); sieve_runtime_trace( renv, 0, "comparing message size %llu", (unsigned long long)mail_size); sieve_runtime_trace( renv, 0, "with upper limit %llu", (unsigned long long)limit); } sieve_interpreter_set_test_result(renv->interp, (mail_size > limit)); } else { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "size :under test"); if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING)) { sieve_runtime_trace_descend(renv); sieve_runtime_trace( renv, 0, "comparing message size %llu", (unsigned long long)mail_size); sieve_runtime_trace( renv, 0, "with lower limit %llu", (unsigned long long)limit); } sieve_interpreter_set_test_result(renv->interp, (mail_size < limit)); } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-objects.c0000644000175100001700000000511215100335616024352 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-dump.h" #include "sieve-interpreter.h" #include "sieve-objects.h" /* * Object coding */ void sieve_opr_object_emit (struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_object_def *obj_def) { struct sieve_extension_objects *objs = (struct sieve_extension_objects *) obj_def->operand->interface; (void) sieve_operand_emit(sblock, ext, obj_def->operand); if ( objs->count > 1 ) { (void) sieve_binary_emit_byte(sblock, obj_def->code); } } bool sieve_opr_object_read_data (struct sieve_binary_block *sblock, const struct sieve_operand *operand, const struct sieve_operand_class *opclass, sieve_size_t *address, struct sieve_object *obj) { const struct sieve_extension_objects *objs; unsigned int obj_code; if ( operand == NULL || operand->def->class != opclass ) return FALSE; objs = (struct sieve_extension_objects *) operand->def->interface; if ( objs == NULL ) return FALSE; if ( objs->count > 1 ) { if ( !sieve_binary_read_byte(sblock, address, &obj_code) ) return FALSE; if ( obj_code < objs->count ) { const struct sieve_object_def *const *objects = (const struct sieve_object_def *const *) objs->objects; obj->def = objects[obj_code]; obj->ext = operand->ext; return TRUE; } } obj->def = (const struct sieve_object_def *) objs->objects; obj->ext = operand->ext; return TRUE; } bool sieve_opr_object_read (const struct sieve_runtime_env *renv, const struct sieve_operand_class *opclass, sieve_size_t *address, struct sieve_object *obj) { struct sieve_operand operand; if ( !sieve_operand_read(renv->sblock, address, NULL, &operand) ) { return FALSE; } return sieve_opr_object_read_data (renv->sblock, &operand, opclass, address, obj); } bool sieve_opr_object_dump (const struct sieve_dumptime_env *denv, const struct sieve_operand_class *opclass, sieve_size_t *address, struct sieve_object *obj) { struct sieve_operand operand; struct sieve_object obj_i; const char *class; if ( obj == NULL ) obj = &obj_i; sieve_code_mark(denv); if ( !sieve_operand_read(denv->sblock, address, NULL, &operand) ) { return FALSE; } if ( !sieve_opr_object_read_data (denv->sblock, &operand, opclass, address, obj) ) return FALSE; if ( operand.def->class == NULL ) class = "OBJECT"; else class = operand.def->class->name; sieve_code_dumpf(denv, "%s: %s", class, obj->def->identifier); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-address.c0000644000175100001700000001742215100335616024054 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-message.h" #include "sieve-address.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include /* * Address test * * Syntax: * address [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE] * */ static bool tst_address_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_address_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_address_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def tst_address = { .identifier = "address", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_address_registered, .validate = tst_address_validate, .generate = tst_address_generate }; /* * Address operation */ static bool tst_address_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_address_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_address_operation = { .mnemonic = "ADDRESS", .code = SIEVE_OPERATION_ADDRESS, .dump = tst_address_operation_dump, .execute = tst_address_operation_execute }; /* * Test registration */ static bool tst_address_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_address_parts_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART); return TRUE; } /* * Validation */ /* List of valid headers: Implementations MUST restrict the address test to headers that contain addresses, but MUST include at least From, To, Cc, Bcc, Sender, Resent-From, and Resent-To, and it SHOULD include any other header that utilizes an "address-list" structured header body. This list explicitly does not contain the envelope-to and return-path headers. The envelope test must be used to test against these addresses. FIXME: this restriction is somewhat odd. Sieve list advises to allow any other header as long as its content matches the address-list grammar. */ static const char *const _allowed_headers[] = { /* Required */ "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to", /* Additional (RFC 822 / RFC 2822) */ "reply-to", "resent-reply-to", "resent-sender", "resent-cc", "resent-bcc", /* Non-standard (RFC 2076, draft-palme-mailext-headers-08.txt) */ "for-approval", "for-handling", "for-comment", "apparently-to", "errors-to", "delivered-to", "return-receipt-to", "x-admin", "read-receipt-to", "x-confirm-reading-to", "return-receipt-requested", "registered-mail-reply-requested-by", "mail-followup-to", "mail-reply-to", "abuse-reports-to", "x-complaints-to", "x-report-abuse-to", /* Undocumented */ "x-beenthere", "x-original-from", "x-original-to", NULL }; static int _header_is_allowed(void *context ATTR_UNUSED, struct sieve_ast_argument *arg) { if (sieve_argument_is_string_literal(arg)) { const char *header = sieve_ast_strlist_strc(arg); const char *const *hdsp = _allowed_headers; while (*hdsp != NULL) { if (strcasecmp(*hdsp, header) == 0) return 1; hdsp++; } return 0; } return 1; } static bool tst_address_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *header; struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); if (!sieve_validate_positional_argument(valdtr, tst, arg, "header list", 1, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; if (!sieve_command_verify_headers_argument(valdtr, arg)) return FALSE; /* Check if supplied header names are allowed FIXME: verify dynamic header names at runtime */ header = arg; if (sieve_ast_stringlist_map(&header, NULL, _header_is_allowed) <= 0) { i_assert(header != NULL); sieve_argument_validate_error( valdtr, header, "specified header '%s' is not allowed for the address test", str_sanitize(sieve_ast_strlist_strc(header), 64)); return FALSE; } /* Check key list */ arg = sieve_ast_argument_next(arg); if (!sieve_validate_positional_argument(valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_address_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { sieve_operation_emit(cgenv->sblock, NULL, &tst_address_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_address_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "ADDRESS"); sieve_code_descend(denv); /* Handle any optional arguments */ if (sieve_message_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return (sieve_opr_stringlist_dump(denv, address, "header list") && sieve_opr_stringlist_dump(denv, address, "key list")); } /* * Code execution */ static int tst_address_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_address_part addrp = SIEVE_ADDRESS_PART_DEFAULT(all_address_part); struct sieve_stringlist *hdr_list, *hdr_value_list, *value_list, *key_list; struct sieve_address_list *addr_list; ARRAY_TYPE(sieve_message_override) svmos; int match, ret; /* Read optional operands */ i_zero(&svmos); if (sieve_message_opr_optional_read(renv, address, NULL, &ret, &addrp, &mcht, &cmp, &svmos) < 0) return ret; /* Read header-list */ if ((ret = sieve_opr_stringlist_read(renv, address, "header-list", &hdr_list)) <= 0) return ret; /* Read key-list */ if ((ret = sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) <= 0) return ret; sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "address test"); /* Get header */ sieve_runtime_trace_descend(renv); if ((ret = sieve_message_get_header_fields( renv, hdr_list, &svmos, FALSE, &hdr_value_list)) <= 0) return ret; sieve_runtime_trace_ascend(renv); /* Create value stringlist */ addr_list = sieve_header_address_list_create(renv, hdr_value_list); value_list = sieve_address_part_stringlist_create( renv, &addrp, addr_list); /* Perform match */ if ((match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-comparators.h0000644000175100001700000000771215100335616025270 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_COMPARATORS_H #define SIEVE_COMPARATORS_H #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-objects.h" #include "sieve-code.h" /* * Core comparators */ enum sieve_comparator_code { SIEVE_COMPARATOR_I_OCTET, SIEVE_COMPARATOR_I_ASCII_CASEMAP, SIEVE_COMPARATOR_I_UNICODE_CASEMAP, SIEVE_COMPARATOR_CUSTOM }; extern const struct sieve_comparator_def i_octet_comparator; extern const struct sieve_comparator_def i_ascii_casemap_comparator; extern const struct sieve_comparator_def i_unicode_casemap_comparator; /* * Comparator flags */ enum sieve_comparator_flags { SIEVE_COMPARATOR_FLAG_ORDERING = (1 << 0), SIEVE_COMPARATOR_FLAG_EQUALITY = (1 << 1), SIEVE_COMPARATOR_FLAG_PREFIX_MATCH = (1 << 2), SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH = (1 << 3), }; /* * Comparator definition */ struct sieve_comparator_def { struct sieve_object_def obj_def; unsigned int flags; /* Equality and ordering */ int (*compare)(const struct sieve_comparator *cmp, const char *val1, size_t val1_size, const char *val2, size_t val2_size); /* Prefix and substring match */ bool (*char_match)(const struct sieve_comparator *cmp, const char **val, const char *val_end, const char **key, const char *key_end); bool (*char_skip)(const struct sieve_comparator *cmp, const char **val, const char *val_end); }; /* * Comparator instance */ struct sieve_comparator { struct sieve_object object; const struct sieve_comparator_def *def; }; #define SIEVE_COMPARATOR_DEFAULT(definition) \ { SIEVE_OBJECT_DEFAULT(definition), &(definition) } #define sieve_comparator_name(cmp) \ ((cmp)->object.def->identifier) #define sieve_comparator_is(cmp, definition) \ ((cmp)->def == &(definition)) static inline const struct sieve_comparator * sieve_comparator_copy(pool_t pool, const struct sieve_comparator *cmp_orig) { struct sieve_comparator *cmp = p_new(pool, struct sieve_comparator, 1); *cmp = *cmp_orig; return cmp; } /* * Comparator tagged argument */ extern const struct sieve_argument_def comparator_tag; static inline bool sieve_argument_is_comparator(struct sieve_ast_argument *arg) { return (arg->argument != NULL && (arg->argument->def == &comparator_tag)); } void sieve_comparators_link_tag(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, int id_code); bool sieve_comparator_tag_is(struct sieve_ast_argument *tag, const struct sieve_comparator_def *cmp); const struct sieve_comparator * sieve_comparator_tag_get(struct sieve_ast_argument *tag); void sieve_comparator_register(struct sieve_validator *validator, const struct sieve_extension *ext, const struct sieve_comparator_def *cmp); /* * Comparator operand */ #define SIEVE_EXT_DEFINE_COMPARATOR(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_COMPARATORS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) extern const struct sieve_operand_class sieve_comparator_operand_class; extern const struct sieve_operand_def comparator_operand; static inline void sieve_opr_comparator_emit(struct sieve_binary_block *sblock, const struct sieve_comparator *cmp) { sieve_opr_object_emit(sblock, cmp->object.ext, cmp->object.def); } static inline bool sieve_opr_comparator_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { return sieve_opr_object_dump(denv, &sieve_comparator_operand_class, address, NULL); } static inline int sieve_opr_comparator_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_comparator *cmp) { if (!sieve_opr_object_read(renv, &sieve_comparator_operand_class, address, &cmp->object)) return SIEVE_EXEC_BIN_CORRUPT; cmp->def = (const struct sieve_comparator_def *)cmp->object.def; return SIEVE_EXEC_OK; } /* * Trivial/Common comparator method implementations */ bool sieve_comparator_octet_skip(const struct sieve_comparator *cmp ATTR_UNUSED, const char **val, const char *val_end); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-message.h0000644000175100001700000001710115100335616024353 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_MESSAGE_H #define SIEVE_MESSAGE_H #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-objects.h" /* * Message transmission */ const char *sieve_message_get_new_id(const struct sieve_instance *svinst); /* * Message context */ struct sieve_message_context; struct sieve_message_context * sieve_message_context_create(struct sieve_instance *svinst, struct mail_user *mail_user, const struct sieve_message_data *msgdata); void sieve_message_context_ref(struct sieve_message_context *msgctx); void sieve_message_context_unref(struct sieve_message_context **msgctx); void sieve_message_context_reset(struct sieve_message_context *msgctx); pool_t sieve_message_context_pool( struct sieve_message_context *msgctx) ATTR_PURE; void sieve_message_context_time(struct sieve_message_context *msgctx, struct timeval *time); /* Extension support */ void sieve_message_context_extension_set(struct sieve_message_context *msgctx, const struct sieve_extension *ext, void *context); void *sieve_message_context_extension_get(struct sieve_message_context *msgctx, const struct sieve_extension *ext); /* Envelope */ const struct smtp_address * sieve_message_get_final_recipient(struct sieve_message_context *msgctx); const struct smtp_address * sieve_message_get_orig_recipient(struct sieve_message_context *msgctx); const struct smtp_address * sieve_message_get_sender(struct sieve_message_context *msgctx); /* Mail */ struct mail *sieve_message_get_mail(struct sieve_message_context *msgctx); int sieve_message_substitute(struct sieve_message_context *msgctx, struct istream *input); struct edit_mail *sieve_message_edit(struct sieve_message_context *msgctx); void sieve_message_snapshot(struct sieve_message_context *msgctx); /* * Header stringlist */ struct sieve_header_list { struct sieve_stringlist strlist; int (*next_item)(struct sieve_header_list *_hdrlist, const char **name_r, string_t **value_r) ATTR_NULL(2); }; static inline int sieve_header_list_next_item(struct sieve_header_list *hdrlist, const char **name_r, string_t **value_r) ATTR_NULL(2) { return hdrlist->next_item(hdrlist, name_r, value_r); } static inline void sieve_header_list_reset(struct sieve_header_list *hdrlist) { sieve_stringlist_reset(&hdrlist->strlist); } static inline int sieve_header_list_get_length(struct sieve_header_list *hdrlist) { return sieve_stringlist_get_length(&hdrlist->strlist); } static inline void sieve_header_list_set_trace(struct sieve_header_list *hdrlist, bool trace) { sieve_stringlist_set_trace(&hdrlist->strlist, trace); } struct sieve_header_list * sieve_message_header_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_names, bool mime_decode); /* * Message override */ /* Header override object */ struct sieve_message_override_def { struct sieve_object_def obj_def; unsigned int sequence; /* Context coding */ bool (*dump_context)(const struct sieve_message_override *svmo, const struct sieve_dumptime_env *denv, sieve_size_t *address); int (*read_context)(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context); /* Override */ int (*header_override)(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, bool mime_decode, struct sieve_stringlist **headers); }; struct sieve_message_override { struct sieve_object object; const struct sieve_message_override_def *def; void *context; }; ARRAY_DEFINE_TYPE(sieve_message_override, struct sieve_message_override); /* * Message override operand */ #define SIEVE_EXT_DEFINE_MESSAGE_OVERRIDE(SVMO) SIEVE_EXT_DEFINE_OBJECT(SVMO) #define SIEVE_EXT_DEFINE_MESSAGE_OVERRIDES(SVMOS) SIEVE_EXT_DEFINE_OBJECTS(SMOS) #define SIEVE_OPT_MESSAGE_OVERRIDE (-2) extern const struct sieve_operand_class sieve_message_override_operand_class; static inline void sieve_opr_message_override_emit(struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_message_override_def *seff) { sieve_opr_object_emit(sblock, ext, &seff->obj_def); } bool sieve_opr_message_override_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); int sieve_opr_message_override_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_message_override *svmo); /* * Optional operands */ int sieve_message_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code); int sieve_message_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code, int *exec_status, struct sieve_address_part *addrp, struct sieve_match_type *mcht, struct sieve_comparator *cmp, ARRAY_TYPE(sieve_message_override) *svmos); /* * Message header */ int sieve_message_get_header_fields(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_names, ARRAY_TYPE(sieve_message_override) *svmos, bool mime_decode, struct sieve_stringlist **fields_r); /* * Message part */ struct sieve_message_part; struct sieve_message_part_data { const char *content_type; const char *content_disposition; const char *content; unsigned long size; }; struct sieve_message_part * sieve_message_part_parent(struct sieve_message_part *mpart) ATTR_PURE; struct sieve_message_part * sieve_message_part_next(struct sieve_message_part *mpart) ATTR_PURE; struct sieve_message_part * sieve_message_part_children(struct sieve_message_part *mpart) ATTR_PURE; const char * sieve_message_part_content_type(struct sieve_message_part *mpart) ATTR_PURE; const char * sieve_message_part_content_disposition(struct sieve_message_part *mpart) ATTR_PURE; int sieve_message_part_get_first_header(struct sieve_message_part *mpart, const char *field, const char **value_r); void sieve_message_part_get_data(struct sieve_message_part *mpart, struct sieve_message_part_data *data, bool text); /* * Message body */ int sieve_message_body_get_content(const struct sieve_runtime_env *renv, const char *const *content_types, struct sieve_message_part_data **parts_r); int sieve_message_body_get_text(const struct sieve_runtime_env *renv, struct sieve_message_part_data **parts_r); int sieve_message_body_get_raw(const struct sieve_runtime_env *renv, struct sieve_message_part_data **parts_r); /* * Message part iterator */ struct sieve_message_part_iter { const struct sieve_runtime_env *renv; struct sieve_message_part *root; unsigned int index, offset; }; int sieve_message_part_iter_init(struct sieve_message_part_iter *iter, const struct sieve_runtime_env *renv); void sieve_message_part_iter_subtree(struct sieve_message_part_iter *iter, struct sieve_message_part_iter *subtree); void sieve_message_part_iter_children(struct sieve_message_part_iter *iter, struct sieve_message_part_iter *child); struct sieve_message_part * sieve_message_part_iter_current(struct sieve_message_part_iter *iter); struct sieve_message_part * sieve_message_part_iter_next(struct sieve_message_part_iter *iter); void sieve_message_part_iter_reset(struct sieve_message_part_iter *iter); /* * MIME header list */ struct sieve_header_list * sieve_mime_header_list_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_names, struct sieve_message_part_iter *part_iter, bool mime_decode, bool children); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/mcht-is.c0000644000175100001700000000203415100335616023154 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Match-type ':is': */ #include "lib.h" #include "sieve-match-types.h" #include "sieve-comparators.h" #include "sieve-match.h" #include #include /* * Forward declarations */ static int mcht_is_match_key (struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size); /* * Match-type object */ const struct sieve_match_type_def is_match_type = { SIEVE_OBJECT("is", &match_type_operand, SIEVE_MATCH_TYPE_IS), .match_key = mcht_is_match_key }; /* * Match-type implementation */ static int mcht_is_match_key (struct sieve_match_context *mctx ATTR_UNUSED, const char *val, size_t val_size, const char *key, size_t key_size) { if ( val_size == 0 ) return ( key_size == 0 ? 1 : 0 ); if ( mctx->comparator->def != NULL && mctx->comparator->def->compare != NULL ) return (mctx->comparator->def->compare(mctx->comparator, val, val_size, key, key_size) == 0 ? 1 : 0 ); return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-smtp.c0000644000175100001700000000402115100335616023702 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "smtp-address.h" #include "sieve-common.h" #include "sieve-smtp.h" struct sieve_smtp_context { const struct sieve_script_env *senv; void *handle; bool sent:1; }; bool sieve_smtp_available (const struct sieve_script_env *senv) { return ( senv->smtp_start != NULL && senv->smtp_add_rcpt != NULL && senv->smtp_send != NULL && senv->smtp_finish != NULL ); } struct sieve_smtp_context *sieve_smtp_start (const struct sieve_script_env *senv, const struct smtp_address *mail_from) { struct sieve_smtp_context *sctx; void *handle; if ( !sieve_smtp_available(senv) ) return NULL; handle = senv->smtp_start(senv, mail_from); i_assert( handle != NULL ); sctx = i_new(struct sieve_smtp_context, 1); sctx->senv = senv; sctx->handle = handle; return sctx; } void sieve_smtp_add_rcpt (struct sieve_smtp_context *sctx, const struct smtp_address *rcpt_to) { i_assert(!sctx->sent); sctx->senv->smtp_add_rcpt(sctx->senv, sctx->handle, rcpt_to); } struct ostream *sieve_smtp_send (struct sieve_smtp_context *sctx) { i_assert(!sctx->sent); sctx->sent = TRUE; return sctx->senv->smtp_send(sctx->senv, sctx->handle); } struct sieve_smtp_context *sieve_smtp_start_single (const struct sieve_script_env *senv, const struct smtp_address *rcpt_to, const struct smtp_address *mail_from, struct ostream **output_r) { struct sieve_smtp_context *sctx; sctx = sieve_smtp_start(senv, mail_from); sieve_smtp_add_rcpt(sctx, rcpt_to); *output_r = sieve_smtp_send(sctx); return sctx; } void sieve_smtp_abort (struct sieve_smtp_context *sctx) { const struct sieve_script_env *senv = sctx->senv; void *handle = sctx->handle; i_free(sctx); i_assert(senv->smtp_abort != NULL); senv->smtp_abort(senv, handle); } int sieve_smtp_finish (struct sieve_smtp_context *sctx, const char **error_r) { const struct sieve_script_env *senv = sctx->senv; void *handle = sctx->handle; i_free(sctx); return senv->smtp_finish(senv, handle, error_r); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-actions.h0000644000175100001700000001770515100335616024401 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_ACTIONS_H #define SIEVE_ACTIONS_H #include "lib.h" #include "mail-types.h" #include "mail-error.h" #include "sieve-common.h" #include "sieve-objects.h" #include "sieve-extensions.h" #include "sieve-execute.h" /* * Action execution environment */ struct sieve_action_exec_env { const struct sieve_execute_env *exec_env; struct sieve_result_execution *rexec; const struct sieve_action *action; struct event *event; struct sieve_result *result; struct sieve_error_handler *ehandler; struct sieve_message_context *msgctx; }; struct event_passthrough * sieve_action_create_finish_event(const struct sieve_action_exec_env *aenv); /* * Action flags */ enum sieve_action_flags { SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0), SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1), SIEVE_ACTFLAG_MAIL_STORAGE = (1 << 2) }; /* * Action definition */ struct sieve_action_def { const char *name; unsigned int flags; bool (*equals)(const struct sieve_script_env *senv, const struct sieve_action *act1, const struct sieve_action *act2); /* Result verification */ int (*check_duplicate)(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); int (*check_conflict)(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); /* Result printing */ void (*print)(const struct sieve_action *action, const struct sieve_result_print_env *penv, bool *keep); /* Result execution */ int (*start)(const struct sieve_action_exec_env *aenv, void **tr_context); int (*execute)(const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); int (*commit)(const struct sieve_action_exec_env *aenv, void *tr_context); void (*rollback)(const struct sieve_action_exec_env *aenv, void *tr_context, bool success); void (*finish)(const struct sieve_action_exec_env *aenv, void *tr_context, int status); }; /* * Action instance */ struct sieve_action { const struct sieve_action_def *def; const struct sieve_extension *ext; struct event *event; const char *name; const char *location; unsigned int exec_seq; void *context; struct mail *mail; bool keep:1; }; #define sieve_action_is(act, definition) ((act)->def == &(definition)) #define sieve_action_name(act) ((act)->name) bool sieve_action_is_executed(const struct sieve_action *act, struct sieve_result *result); /* * Action side effects */ /* Side effect object */ struct sieve_side_effect_def { struct sieve_object_def obj_def; /* Precedence (side effects with higher value are executed first) */ unsigned int precedence; /* The action it is supposed to link to */ const struct sieve_action_def *to_action; /* Context coding */ bool (*dump_context)(const struct sieve_side_effect *seffect, const struct sieve_dumptime_env *renv, sieve_size_t *address); int (*read_context)(const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context); /* Result verification */ int (*merge)(const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_side_effect *old_seffect, const struct sieve_side_effect *new_seffect, void **old_context); /* Result printing */ void (*print)(const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_result_print_env *penv, bool *keep); /* Result execution */ int (*pre_execute)(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context); int (*post_execute)(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void *se_tr_context, bool *keep); void (*post_commit)(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void *se_tr_context, int commit_status); void (*rollback)(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void *se_tr_context, bool success); }; struct sieve_side_effect { struct sieve_object object; const struct sieve_side_effect_def *def; void *context; }; /* * Side effect operand */ #define SIEVE_EXT_DEFINE_SIDE_EFFECT(SEF) SIEVE_EXT_DEFINE_OBJECT(SEF) #define SIEVE_EXT_DEFINE_SIDE_EFFECTS(SEFS) SIEVE_EXT_DEFINE_OBJECTS(SEFS) #define SIEVE_OPT_SIDE_EFFECT (-1) extern const struct sieve_operand_class sieve_side_effect_operand_class; static inline void sieve_opr_side_effect_emit(struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_side_effect_def *seff) { sieve_opr_object_emit(sblock, ext, &seff->obj_def); } bool sieve_opr_side_effect_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); int sieve_opr_side_effect_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_side_effect *seffect); /* * Optional operands */ int sieve_action_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code); int sieve_action_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code, int *exec_status, struct sieve_side_effects_list **list); /* * Core actions */ extern const struct sieve_action_def act_redirect; extern const struct sieve_action_def act_store; extern const struct sieve_action_def act_discard; /* * Store action */ struct act_store_context { /* Folder name represented in utf-8 */ const char *mailbox; }; struct act_store_transaction { struct act_store_context *context; struct mailbox *box; struct mailbox_transaction_context *mail_trans; const char *mailbox_name; const char *mailbox_identifier; const char *error; enum mail_error error_code; enum mail_flags flags; ARRAY_TYPE(const_string) keywords; bool flags_altered:1; bool disabled:1; bool redundant:1; }; int sieve_act_store_add_to_result(const struct sieve_runtime_env *renv, const char *name, struct sieve_side_effects_list *seffects, const char *folder); void sieve_act_store_add_flags(const struct sieve_action_exec_env *aenv, void *tr_context, const char *const *keywords, enum mail_flags flags); void sieve_act_store_get_storage_error(const struct sieve_action_exec_env *aenv, struct act_store_transaction *trans); /* * Redirect action */ struct act_redirect_context { const struct smtp_address *to_address; }; int sieve_act_redirect_add_to_result(const struct sieve_runtime_env *renv, const char *name, struct sieve_side_effects_list *seffects, const struct smtp_address *to_address); /* * Checking for duplicates */ static inline bool sieve_action_duplicate_check_available(const struct sieve_action_exec_env *aenv) { const struct sieve_execute_env *eenv = aenv->exec_env; return sieve_execute_duplicate_check_available(eenv); } static inline int sieve_action_duplicate_check(const struct sieve_action_exec_env *aenv, const void *id, size_t id_size, bool *duplicate_r) { const struct sieve_execute_env *eenv = aenv->exec_env; return sieve_execute_duplicate_check(eenv, id, id_size, duplicate_r); } static inline void sieve_action_duplicate_mark(const struct sieve_action_exec_env *aenv, const void *id, size_t id_size, time_t time) { const struct sieve_execute_env *eenv = aenv->exec_env; return sieve_execute_duplicate_mark(eenv, id, id_size, time); } /* * Action utility functions */ /* Rejecting mail */ int sieve_action_reject_mail(const struct sieve_action_exec_env *aenv, const struct smtp_address *recipient, const char *reason); /* * Mailbox */ // FIXME: move this to a more appropriate location bool sieve_mailbox_check_name(const char *mailbox, const char **error_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-result.h0000644000175100001700000001702415100335616024251 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_RESULT_H #define SIEVE_RESULT_H #include "sieve-common.h" #include "sieve-error.h" #include "sieve-execute.h" /* * Types */ struct sieve_side_effects_list; /* * Result object */ struct sieve_result; struct sieve_result * sieve_result_create(struct sieve_instance *svinst, pool_t pool, const struct sieve_execute_env *eenv); void sieve_result_ref(struct sieve_result *result); void sieve_result_unref(struct sieve_result **result); pool_t sieve_result_pool(struct sieve_result *result); /* * Getters/Setters */ const struct sieve_script_env * sieve_result_get_script_env(struct sieve_result *result); const struct sieve_message_data * sieve_result_get_message_data(struct sieve_result *result); struct sieve_message_context * sieve_result_get_message_context(struct sieve_result *result); unsigned int sieve_result_get_exec_seq(struct sieve_result *result); /* * Extension support */ void sieve_result_extension_set_context(struct sieve_result *result, const struct sieve_extension *ext, void *context); const void * sieve_result_extension_get_context(struct sieve_result *result, const struct sieve_extension *ext); /* * Result printing */ struct sieve_result_print_env { struct sieve_result *result; const struct sieve_script_env *scriptenv; struct ostream *stream; }; void sieve_result_vprintf(const struct sieve_result_print_env *penv, const char *fmt, va_list args) ATTR_FORMAT(2, 0); void sieve_result_printf(const struct sieve_result_print_env *penv, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_result_action_printf(const struct sieve_result_print_env *penv, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_result_seffect_printf(const struct sieve_result_print_env *penv, const char *fmt, ...) ATTR_FORMAT(2, 3); bool sieve_result_print(struct sieve_result *result, const struct sieve_script_env *senv, struct ostream *stream, bool *keep); /* * Result composition */ void sieve_result_add_implicit_side_effect( struct sieve_result *result, const struct sieve_action_def *to_action, bool to_keep, const struct sieve_extension *ext, const struct sieve_side_effect_def *seffect, void *context); int sieve_result_add_action(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, const char *name, const struct sieve_action_def *act_def, struct sieve_side_effects_list *seffects, void *context, unsigned int instance_limit, bool preserve_mail); int sieve_result_add_keep(const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects); void sieve_result_set_keep_action(struct sieve_result *result, const struct sieve_extension *ext, const struct sieve_action_def *act_def); void sieve_result_set_failure_action(struct sieve_result *result, const struct sieve_extension *ext, const struct sieve_action_def *act_def); /* * Result execution */ struct sieve_result_execution; void sieve_result_mark_executed(struct sieve_result *result); struct sieve_result_execution * sieve_result_execution_create(struct sieve_result *result, pool_t pool); void sieve_result_execution_destroy(struct sieve_result_execution **_rexec); void *sieve_result_execution_get_dup_transaction( struct sieve_result_execution *rexec); int sieve_result_execute(struct sieve_result_execution *rexec, int status, bool commit, struct sieve_error_handler *ehandler, bool *keep_r); bool sieve_result_executed(struct sieve_result_execution *rexec); bool sieve_result_committed(struct sieve_result_execution *rexec); bool sieve_result_executed_delivery(struct sieve_result_execution *rexec); /* * Result evaluation */ struct sieve_result_iterate_context; struct sieve_result_iterate_context * sieve_result_iterate_init(struct sieve_result *result); const struct sieve_action * sieve_result_iterate_next(struct sieve_result_iterate_context *rictx, bool *keep); void sieve_result_iterate_delete(struct sieve_result_iterate_context *rictx); /* * Side effects list */ struct sieve_side_effects_list * sieve_side_effects_list_create(struct sieve_result *result); void sieve_side_effects_list_add(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect); /* * Error handling */ void sieve_result_error(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_error(aenv, ...) \ sieve_result_error(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_global_error(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_global_error(aenv, ...) \ sieve_result_global_error(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_warning(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_warning(aenv, ...) \ sieve_result_warning(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_global_warning(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_global_warning(aenv, ...) \ sieve_result_global_warning(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_log(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_log(aenv, ...) \ sieve_result_log(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_global_log(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_global_log(aenv, ...) \ sieve_result_global_log(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_global_log_error(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_global_log_error(aenv, ...) \ sieve_result_global_log_error(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_global_log_warning(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(4, 5); #define sieve_result_global_log_warning(aenv, ...) \ sieve_result_global_log_warning(aenv, __FILE__, __LINE__, __VA_ARGS__) void sieve_result_event_log(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, struct event *event, const char *fmt, ...) ATTR_FORMAT(5, 0); #define sieve_result_event_log(aenv, event, ...) \ sieve_result_event_log(aenv, __FILE__, __LINE__, event, __VA_ARGS__) void sieve_result_critical(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *user_prefix, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_result_critical(aenv, ...) \ sieve_result_critical(aenv, __FILE__, __LINE__, __VA_ARGS__) int sieve_result_mail_error(const struct sieve_action_exec_env *aenv, struct mail *mail, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_result_mail_error(aenv, mail, ...) \ sieve_result_mail_error(aenv, mail, __FILE__, __LINE__, __VA_ARGS__) #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-extensions.c0000644000175100001700000006214615100335616025132 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "mempool.h" #include "hash.h" #include "array.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" /* * Forward declarations */ static void sieve_extension_registry_init(struct sieve_instance *svinst); static void sieve_extension_registry_deinit(struct sieve_instance *svinst); static void sieve_capability_registry_init(struct sieve_instance *svinst); static void sieve_capability_registry_deinit(struct sieve_instance *svinst); static int _sieve_extension_register(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, bool required, struct sieve_extension **ext_r); static int sieve_extensions_set_array(struct sieve_instance *svinst, const ARRAY_TYPE(const_string) *ext_names, bool global, bool implicit); /* * Instance global context */ struct sieve_extension_registry { ARRAY(struct sieve_extension *) extensions; HASH_TABLE(const char *, struct sieve_extension *) extension_index; HASH_TABLE(const char *, struct sieve_capability_registration *) capabilities_index; /* Core language 'extensions' */ const struct sieve_extension *comparator_extension; const struct sieve_extension *match_type_extension; const struct sieve_extension *address_part_extension; /* Preloaded extensions */ ARRAY(const struct sieve_extension *) preloaded_extensions; }; /* * Pre-loaded 'extensions' */ extern const struct sieve_extension_def comparator_extension; extern const struct sieve_extension_def match_type_extension; extern const struct sieve_extension_def address_part_extension; /* * Dummy extensions */ /* FIXME: This is stupid. Define a comparator-* extension and be done with it */ const struct sieve_extension_def comparator_i_octet_extension = { .name = "comparator-i;octet", }; const struct sieve_extension_def comparator_i_ascii_casemap_extension = { .name = "comparator-i;ascii-casemap", }; const struct sieve_extension_def comparator_i_unicode_casemap_extension = { .name = "comparator-i;unicode-casemap", }; /* * List of native extensions */ /* Dummy extensions */ extern const struct sieve_extension_def comparator_i_octet_extension; extern const struct sieve_extension_def comparator_i_ascii_casemap_extension; extern const struct sieve_extension_def comparator_i_unicode_casemap_extension; const struct sieve_extension_def *sieve_dummy_extensions[] = { &comparator_i_octet_extension, &comparator_i_ascii_casemap_extension, &comparator_i_unicode_casemap_extension, }; const unsigned int sieve_dummy_extensions_count = N_ELEMENTS(sieve_dummy_extensions); /* Core */ extern const struct sieve_extension_def fileinto_extension; extern const struct sieve_extension_def reject_extension; extern const struct sieve_extension_def envelope_extension; extern const struct sieve_extension_def encoded_character_extension; extern const struct sieve_extension_def vacation_extension; extern const struct sieve_extension_def subaddress_extension; extern const struct sieve_extension_def comparator_i_ascii_numeric_extension; extern const struct sieve_extension_def relational_extension; extern const struct sieve_extension_def regex_extension; extern const struct sieve_extension_def imap4flags_extension; extern const struct sieve_extension_def copy_extension; extern const struct sieve_extension_def include_extension; extern const struct sieve_extension_def body_extension; extern const struct sieve_extension_def variables_extension; extern const struct sieve_extension_def enotify_extension; extern const struct sieve_extension_def environment_extension; extern const struct sieve_extension_def mailbox_extension; extern const struct sieve_extension_def date_extension; extern const struct sieve_extension_def index_extension; extern const struct sieve_extension_def ihave_extension; extern const struct sieve_extension_def duplicate_extension; extern const struct sieve_extension_def mime_extension; extern const struct sieve_extension_def foreverypart_extension; extern const struct sieve_extension_def extracttext_extension; extern const struct sieve_extension_def mboxmetadata_extension; extern const struct sieve_extension_def servermetadata_extension; extern const struct sieve_extension_def vacation_seconds_extension; extern const struct sieve_extension_def spamtest_extension; extern const struct sieve_extension_def spamtestplus_extension; extern const struct sieve_extension_def virustest_extension; extern const struct sieve_extension_def editheader_extension; extern const struct sieve_extension_def special_use_extension; extern const struct sieve_extension_def extlists_extension; extern const struct sieve_extension_def vnd_debug_extension; extern const struct sieve_extension_def vnd_environment_extension; extern const struct sieve_extension_def vnd_report_extension; #ifdef HAVE_SIEVE_UNFINISHED extern const struct sieve_extension_def ereject_extension; #endif const struct sieve_extension_def *sieve_extensions[] = { /* Core extensions */ &fileinto_extension, &reject_extension, &envelope_extension, &encoded_character_extension, /* 'Plugins' */ &vacation_extension, &subaddress_extension, &comparator_i_ascii_numeric_extension, &relational_extension, ®ex_extension, &imap4flags_extension, ©_extension, &include_extension, &body_extension, &variables_extension, &enotify_extension, &environment_extension, &mailbox_extension, &date_extension, &index_extension, &ihave_extension, &duplicate_extension, &mime_extension, &foreverypart_extension, &extracttext_extension, /* Extra; These are not enabled by default, e.g. because explicit configuration is necessary to make these useful. */ &vacation_seconds_extension, &spamtest_extension, &spamtestplus_extension, &virustest_extension, &editheader_extension, &mboxmetadata_extension, &servermetadata_extension, &special_use_extension, &extlists_extension, /* vnd.dovecot. */ &vnd_debug_extension, &vnd_environment_extension, &vnd_report_extension, #ifdef HAVE_SIEVE_UNFINISHED /* Unfinished extensions */ &ereject_extension, #endif }; const unsigned int sieve_extensions_count = N_ELEMENTS(sieve_extensions); /* * Extensions init/deinit */ int sieve_extensions_init(struct sieve_instance *svinst) { unsigned int i; struct sieve_extension_registry *ext_reg = p_new(svinst->pool, struct sieve_extension_registry, 1); int ret; svinst->ext_reg = ext_reg; sieve_extension_registry_init(svinst); sieve_capability_registry_init(svinst); /* Preloaded 'extensions' */ ret = sieve_extension_register(svinst, &comparator_extension, TRUE, &ext_reg->comparator_extension); i_assert(ret == 0); ret = sieve_extension_register(svinst, &match_type_extension, TRUE, &ext_reg->match_type_extension); i_assert(ret == 0); ret = sieve_extension_register(svinst, &address_part_extension, TRUE, &ext_reg->address_part_extension); i_assert(ret == 0); p_array_init(&ext_reg->preloaded_extensions, svinst->pool, 5); array_append(&ext_reg->preloaded_extensions, &ext_reg->comparator_extension, 1); array_append(&ext_reg->preloaded_extensions, &ext_reg->match_type_extension, 1); array_append(&ext_reg->preloaded_extensions, &ext_reg->address_part_extension, 1); /* Pre-load dummy extensions */ for (i = 0; i < sieve_dummy_extensions_count; i++) { struct sieve_extension *ext; if (_sieve_extension_register(svinst, sieve_dummy_extensions[i], TRUE, FALSE, &ext) < 0) return -1; ext->dummy = TRUE; } /* Pre-load core extensions */ for (i = 0; i < sieve_extensions_count; i++) { if (sieve_extension_register(svinst, sieve_extensions[i], FALSE, NULL) < 0) return -1; } /* More extensions can be added through plugins */ return 0; } int sieve_extensions_load(struct sieve_instance *svinst) { /* Apply sieve_extensions configuration */ if (sieve_extensions_set_array(svinst, &svinst->set->extensions, FALSE, FALSE) < 0) return -1; /* Apply sieve_global_extensions configuration */ if (sieve_extensions_set_array(svinst, &svinst->set->global_extensions, TRUE, FALSE) < 0) return -1; /* Apply sieve_implicit_extensions configuration */ if (sieve_extensions_set_array(svinst, &svinst->set->implicit_extensions, FALSE, TRUE) < 0) return -1; return 0; } void sieve_extensions_deinit(struct sieve_instance *svinst) { sieve_extension_registry_deinit(svinst); sieve_capability_registry_deinit(svinst); } /* * Pre-loaded extensions */ const struct sieve_extension *const * sieve_extensions_get_preloaded(struct sieve_instance *svinst, unsigned int *count_r) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; return array_get(&ext_reg->preloaded_extensions, count_r); } /* * Extension registry */ static void _sieve_extension_unload(struct sieve_extension *ext); static int _sieve_extension_load(struct sieve_extension *ext) { int ret; /* Drop context if this is a reload */ if (ext->context != NULL) _sieve_extension_unload(ext); /* Call load handler */ if (ext->def == NULL || ext->def->load == NULL) return 0; ret = ext->def->load(ext, &ext->context); i_assert(ret <= 0); if (ret < 0) { e_error(ext->svinst->event, "failed to load '%s' extension support.", ext->def->name); return -1; } return 0; } static void _sieve_extension_unload(struct sieve_extension *ext) { /* Call unload handler */ if (ext->def != NULL && ext->def->unload != NULL) ext->def->unload(ext); ext->context = NULL; } static void sieve_extension_registry_init(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; p_array_init(&ext_reg->extensions, svinst->pool, 50); hash_table_create(&ext_reg->extension_index, default_pool, 0, str_hash, strcmp); } static void sieve_extension_registry_deinit(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; struct sieve_extension *const *exts; unsigned int i, ext_count; if (!hash_table_is_created(ext_reg->extension_index)) return; exts = array_get_modifiable(&ext_reg->extensions, &ext_count); for (i = 0; i < ext_count; i++) _sieve_extension_unload(exts[i]); hash_table_destroy(&ext_reg->extension_index); } static struct sieve_extension * sieve_extension_lookup(struct sieve_instance *svinst, const char *name) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; return hash_table_lookup(ext_reg->extension_index, name); } static struct sieve_extension * sieve_extension_alloc(struct sieve_instance *svinst, const struct sieve_extension_def *extdef) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; struct sieve_extension *ext, **extr; int ext_id; ext_id = (int)array_count(&ext_reg->extensions); /* Add extension to the registry */ extr = array_append_space(&ext_reg->extensions); *extr = ext = p_new(svinst->pool, struct sieve_extension, 1); ext->id = ext_id; ext->def = extdef; ext->svinst = svinst; return ext; } static int _sieve_extension_register(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, bool required, struct sieve_extension **ext_r) { struct sieve_extension *ext; if (ext_r != NULL) *ext_r = NULL; ext = sieve_extension_lookup(svinst, extdef->name); /* Register extension if it is not registered already */ if (ext == NULL) { ext = sieve_extension_alloc(svinst, extdef); hash_table_insert(svinst->ext_reg->extension_index, extdef->name, ext); } else if (ext->overridden) { /* Create a dummy */ ext = sieve_extension_alloc(svinst, extdef); } else { /* Re-register it if it were previously unregistered * (not going to happen) */ i_assert(ext->def == NULL || ext->def == extdef); ext->def = extdef; } /* Enable extension */ if (load || required) { ext->enabled = (ext->enabled || load); /* Call load handler if extension was not loaded already */ if (!ext->loaded) { if (_sieve_extension_load(ext) < 0) return -1; } ext->loaded = TRUE; } ext->required = (ext->required || required); if (ext_r != NULL) *ext_r = ext; return 0; } static inline int _sieve_extension_register_const(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, bool required, const struct sieve_extension **ext_r) { struct sieve_extension *ext; if (_sieve_extension_register(svinst, extdef, load, required, &ext) < 0) { if (ext_r != NULL) *ext_r = NULL; return -1; } if (ext_r != NULL) *ext_r = ext; return 0; } int sieve_extension_register(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, const struct sieve_extension **ext_r) { return _sieve_extension_register_const(svinst, extdef, load, FALSE, ext_r); } void sieve_extension_unregister(const struct sieve_extension *ext) { if (ext == NULL) return; struct sieve_extension_registry *ext_reg = ext->svinst->ext_reg; struct sieve_extension *const *mod_ext; int ext_id = ext->id; if (ext_id >= 0 && ext_id < (int) array_count(&ext_reg->extensions)) { mod_ext = array_idx(&ext_reg->extensions, ext_id); sieve_extension_capabilities_unregister(*mod_ext); _sieve_extension_unload(*mod_ext); (*mod_ext)->loaded = FALSE; (*mod_ext)->enabled = FALSE; (*mod_ext)->def = NULL; } } int sieve_extension_require(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, const struct sieve_extension **ext_r) { return _sieve_extension_register_const(svinst, extdef, load, TRUE, ext_r); } int sieve_extension_reload(const struct sieve_extension *ext) { struct sieve_extension_registry *ext_reg = ext->svinst->ext_reg; struct sieve_extension *const *mod_ext; int ext_id = ext->id; /* Let's not just cast the 'const' away */ i_assert(ext_id >= 0 && ext_id < (int) array_count(&ext_reg->extensions)); mod_ext = array_idx(&ext_reg->extensions, ext_id); return _sieve_extension_load(*mod_ext); } int sieve_extension_replace(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, const struct sieve_extension **ext_r) { struct sieve_extension *ext; ext = sieve_extension_lookup(svinst, extdef->name); if (ext != NULL) sieve_extension_unregister(ext); return sieve_extension_register(svinst, extdef, load, ext_r); } void sieve_extension_override(struct sieve_instance *svinst, const char *name, const struct sieve_extension *ext) { struct sieve_extension_registry *ext_reg = ext->svinst->ext_reg; struct sieve_extension *const *mod_ext; struct sieve_extension *old_ext; old_ext = sieve_extension_lookup(svinst, name); if (old_ext == ext) return; i_assert(old_ext == NULL || !old_ext->overridden); i_assert(ext->id >= 0 && ext->id < (int)array_count(&ext_reg->extensions)); mod_ext = array_idx(&ext_reg->extensions, ext->id); hash_table_update(ext_reg->extension_index, name, *mod_ext); if (old_ext != NULL) old_ext->overridden = TRUE; } unsigned int sieve_extensions_get_count(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; return array_count(&ext_reg->extensions); } const struct sieve_extension *const * sieve_extensions_get_all(struct sieve_instance *svinst, unsigned int *count_r) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; return (const struct sieve_extension *const *) array_get(&ext_reg->extensions, count_r); } const struct sieve_extension * sieve_extension_get_by_id(struct sieve_instance *svinst, unsigned int ext_id) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; struct sieve_extension *const *ext; if (ext_id < array_count(&ext_reg->extensions)) { ext = array_idx(&ext_reg->extensions, ext_id); if ((*ext)->def != NULL && ((*ext)->enabled || (*ext)->required)) return *ext; } return NULL; } const struct sieve_extension * sieve_extension_get_by_name(struct sieve_instance *svinst, const char *name) { const struct sieve_extension *ext; if (*name == '@') return NULL; if (strlen(name) > 128) return NULL; ext = sieve_extension_lookup(svinst, name); if (ext == NULL || ext->def == NULL || (!ext->enabled && !ext->required)) return NULL; return ext; } static inline bool _sieve_extension_listable(const struct sieve_extension *ext) { return (ext->enabled && ext->def != NULL && *(ext->def->name) != '@' && !ext->dummy && !ext->global && !ext->overridden); } const char *sieve_extensions_get_string(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; string_t *extstr = t_str_new(256); struct sieve_extension *const *exts; unsigned int i, ext_count; exts = array_get(&ext_reg->extensions, &ext_count); if (ext_count > 0) { i = 0; /* Find first listable extension */ while (i < ext_count && !_sieve_extension_listable(exts[i])) i++; if (i < ext_count) { /* Add first to string */ str_append(extstr, exts[i]->def->name); i++; /* Add others */ for (; i < ext_count; i++) { if (_sieve_extension_listable(exts[i])) { str_append_c(extstr, ' '); str_append(extstr, exts[i]->def->name); } } } } return str_c(extstr); } static int sieve_extension_set_enabled(struct sieve_extension *ext, bool enabled) { int ret = 0; if (enabled) { ext->enabled = TRUE; if (!ext->loaded) ret = _sieve_extension_load(ext); ext->loaded = TRUE; } else { ext->enabled = FALSE; } return ret; } static int sieve_extension_set_global(struct sieve_extension *ext, bool enabled) { int ret = 0; if (enabled) { ret = sieve_extension_set_enabled(ext, TRUE); ext->global = TRUE; } else { ext->global = FALSE; } return ret; } static int sieve_extension_set_implicit(struct sieve_extension *ext, bool enabled) { int ret = 0; if (enabled) { ret = sieve_extension_set_enabled(ext, TRUE); ext->implicit = TRUE; } else { ext->implicit = FALSE; } return ret; } static int sieve_extensions_set_array(struct sieve_instance *svinst, const ARRAY_TYPE(const_string) *ext_names, bool global, bool implicit) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; const char *name; if (array_is_empty(ext_names)) return 0; int ret = 0; array_foreach_elem(ext_names, name) { struct sieve_extension *ext; ext = hash_table_lookup(ext_reg->extension_index, name); if (ext == NULL || ext->def == NULL || *(ext->def->name) == '@') { e_warning(svinst->event, "ignored unknown extension '%s' " "while configuring available extensions", name); continue; } if (ext->id < 0) continue; /* Perform actual activation/deactivation */ if (global) { if (sieve_extension_set_global(ext, TRUE) < 0) { ret = -1; break; } } else if (implicit) { if (sieve_extension_set_implicit(ext, TRUE) < 0) { ret = -1; break; } } else { if (sieve_extension_set_enabled(ext, TRUE) < 0) { ret = -1; break; } } } return ret; } int sieve_extensions_set_string(struct sieve_instance *svinst, const char *ext_string, bool global, bool implicit) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; ARRAY(const struct sieve_extension *) enabled_extensions; ARRAY(const struct sieve_extension *) disabled_extensions; const struct sieve_extension *const *ext_enabled; const struct sieve_extension *const *ext_disabled; struct sieve_extension **exts; const char **ext_names; unsigned int i, ext_count, ena_count, dis_count; bool relative = FALSE; if (ext_string == NULL) { if (global || implicit) return 0; /* Enable all */ exts = array_get_modifiable(&ext_reg->extensions, &ext_count); for (i = 0; i < ext_count; i++) { if (sieve_extension_set_enabled(exts[i], TRUE) < 0) return -1; } return 0; } int ret = 0; T_BEGIN { t_array_init(&enabled_extensions, array_count(&ext_reg->extensions)); t_array_init(&disabled_extensions, array_count(&ext_reg->extensions)); ext_names = t_strsplit_spaces(ext_string, " \t"); while (*ext_names != NULL) { const char *name = *ext_names; ext_names++; if (*name != '\0') { const struct sieve_extension *ext; char op = '\0'; /* No add/remove operation */ if (*name == '+' || /* Add to existing config */ *name == '-') { /* Remove from existing config */ op = *name++; relative = TRUE; } if (*name == '@') ext = NULL; else { ext = hash_table_lookup(ext_reg->extension_index, name); } if (ext == NULL || ext->def == NULL) { e_warning(svinst->event, "ignored unknown extension '%s' while configuring " "available extensions", name); continue; } if (op == '-') { array_append(&disabled_extensions, &ext, 1); } else { array_append(&enabled_extensions, &ext, 1); } } } exts = array_get_modifiable(&ext_reg->extensions, &ext_count); ext_enabled = array_get(&enabled_extensions, &ena_count); ext_disabled = array_get(&disabled_extensions, &dis_count); /* Set new extension status */ for (i = 0; i < ext_count; i++) { unsigned int j; bool enabled = FALSE; if (exts[i]->id < 0 || exts[i]->def == NULL || *(exts[i]->def->name) == '@') continue; /* If extensions are specified relative to the default set, we first need to check which ones are disabled */ if (relative) { if (global) enabled = exts[i]->global; else if (implicit) enabled = exts[i]->implicit; else enabled = exts[i]->enabled; if (enabled) { /* Disable if explicitly disabled */ for (j = 0; j < dis_count; j++) { if (ext_disabled[j]->def == exts[i]->def) { enabled = FALSE; break; } } } } /* Enable if listed with '+' or no prefix */ for (j = 0; j < ena_count; j++) { if (ext_enabled[j]->def == exts[i]->def) { enabled = TRUE; break; } } /* Perform actual activation/deactivation */ if (global) { if (sieve_extension_set_global(exts[i], enabled) < 0) { ret = -1; break; } } else if (implicit) { if (sieve_extension_set_implicit(exts[i], enabled) < 0) { ret = -1; break; } } else { if (sieve_extension_set_enabled(exts[i], enabled) < 0) { ret = -1; break; } } } } T_END; return ret; } const struct sieve_extension * sieve_get_match_type_extension(struct sieve_instance *svinst) { return svinst->ext_reg->match_type_extension; } const struct sieve_extension * sieve_get_comparator_extension(struct sieve_instance *svinst) { return svinst->ext_reg->comparator_extension; } const struct sieve_extension * sieve_get_address_part_extension(struct sieve_instance *svinst) { return svinst->ext_reg->address_part_extension; } void sieve_enable_debug_extension(struct sieve_instance *svinst) { const struct sieve_extension *ext; int ret; ret = sieve_extension_register(svinst, &vnd_debug_extension, TRUE, &ext); i_assert(ret == 0); } /* * Extension capabilities */ struct sieve_capability_registration { const struct sieve_extension *ext; const struct sieve_extension_capabilities *capabilities; }; void sieve_capability_registry_init(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; hash_table_create(&ext_reg->capabilities_index, default_pool, 0, str_hash, strcmp); } void sieve_capability_registry_deinit(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; if (!hash_table_is_created(ext_reg->capabilities_index)) return; hash_table_destroy(&svinst->ext_reg->capabilities_index); } void sieve_extension_capabilities_register( const struct sieve_extension *ext, const struct sieve_extension_capabilities *cap) { struct sieve_instance *svinst = ext->svinst; struct sieve_extension_registry *ext_reg = svinst->ext_reg; struct sieve_capability_registration *reg; reg = hash_table_lookup(ext_reg->capabilities_index, cap->name); if (reg != NULL) { /* Already registered */ return; } reg = p_new(svinst->pool, struct sieve_capability_registration, 1); reg->ext = ext; reg->capabilities = cap; hash_table_insert(ext_reg->capabilities_index, cap->name, reg); } void sieve_extension_capabilities_unregister(const struct sieve_extension *ext) { struct sieve_extension_registry *ext_reg = ext->svinst->ext_reg; struct hash_iterate_context *hictx; const char *name; struct sieve_capability_registration *reg; hictx = hash_table_iterate_init(ext_reg->capabilities_index); while (hash_table_iterate(hictx, ext_reg->capabilities_index, &name, ®)) { if (reg->ext == ext) hash_table_remove(ext_reg->capabilities_index, name); } hash_table_iterate_deinit(&hictx); } const char * sieve_extension_capabilities_get_string(struct sieve_instance *svinst, const char *cap_name) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; const struct sieve_capability_registration *cap_reg = hash_table_lookup(ext_reg->capabilities_index, cap_name); const struct sieve_extension_capabilities *cap; if (cap_reg == NULL || cap_reg->capabilities == NULL) return NULL; cap = cap_reg->capabilities; if (cap->get_string == NULL || !cap_reg->ext->enabled) return NULL; return cap->get_string(cap_reg->ext); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-script.h0000644000175100001700000001303415100335616024234 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_SCRIPT_H #define SIEVE_SCRIPT_H #include "sieve-common.h" #include /* * Sieve script name */ bool sieve_script_name_is_valid(const char *scriptname); /* * Sieve script file */ bool sieve_script_file_has_extension(const char *filename); const char *sieve_script_file_get_scriptname(const char *filename); const char *sieve_script_file_from_name(const char *name); /* * Sieve script class */ void sieve_script_class_register(struct sieve_instance *svinst, const struct sieve_script *script_class); void sieve_script_class_unregister(struct sieve_instance *svinst, const struct sieve_script *script_class); /* * Sieve script instance */ struct sieve_script; ARRAY_DEFINE_TYPE(sieve_script, struct sieve_script *); int sieve_script_create(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r); int sieve_script_create_in(struct sieve_instance *svinst, const char *cause, const char *storage_name, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r); void sieve_script_ref(struct sieve_script *script); void sieve_script_unref(struct sieve_script **script); int sieve_script_open(struct sieve_script *script, enum sieve_error *error_code_r); int sieve_script_open_as(struct sieve_script *script, const char *name, enum sieve_error *error_code_r); int sieve_script_create_open(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r); int sieve_script_create_open_in(struct sieve_instance *svinst, const char *cause, const char *storage_name, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r); int sieve_script_check(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, enum sieve_error *error_code_r, const char **error_r); /* * Data script */ struct sieve_script * sieve_data_script_create_from_input(struct sieve_instance *svinst, const char *cause, const char *name, struct istream *input); /* * Binary */ int sieve_script_binary_read_metadata(struct sieve_script *script, struct sieve_binary_block *sblock, sieve_size_t *offset); void sieve_script_binary_write_metadata(struct sieve_script *script, struct sieve_binary_block *sblock); bool sieve_script_binary_dump_metadata(struct sieve_script *script, struct sieve_dumptime_env *denv, struct sieve_binary_block *sblock, sieve_size_t *offset) ATTR_NULL(1); int sieve_script_binary_load(struct sieve_script *script, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); int sieve_script_binary_save(struct sieve_script *script, struct sieve_binary *sbin, bool update, enum sieve_error *error_code_r); const char *sieve_script_binary_get_prefix(struct sieve_script *script); /* * Stream management */ int sieve_script_get_stream(struct sieve_script *script, struct istream **stream_r, enum sieve_error *error_code_r); /* * Management */ // FIXME: check read/write flag! int sieve_script_rename(struct sieve_script *script, const char *newname); int sieve_script_is_active(struct sieve_script *script); int sieve_script_activate(struct sieve_script *script, time_t mtime); int sieve_script_delete(struct sieve_script *script, bool ignore_active); /* * Properties */ const char *sieve_script_name(const struct sieve_script *script) ATTR_PURE; const char *sieve_script_label(const struct sieve_script *script) ATTR_PURE; const char * sieve_script_storage_type(const struct sieve_script *script) ATTR_PURE; const char *sieve_script_cause(const struct sieve_script *script) ATTR_PURE; struct sieve_instance * sieve_script_svinst(const struct sieve_script *script) ATTR_PURE; int sieve_script_get_size(struct sieve_script *script, uoff_t *size_r); bool sieve_script_is_open(const struct sieve_script *script) ATTR_PURE; bool sieve_script_is_default(const struct sieve_script *script) ATTR_PURE; const char * sieve_file_script_get_dir_path(const struct sieve_script *script) ATTR_PURE; const char * sieve_file_script_get_path(const struct sieve_script *script) ATTR_PURE; /* * Comparison */ int sieve_script_cmp(const struct sieve_script *script1, const struct sieve_script *script2); static inline bool sieve_script_equals(const struct sieve_script *script1, const struct sieve_script *script2) { return (sieve_script_cmp(script1, script2) == 0); } unsigned int sieve_script_hash(const struct sieve_script *script); /* * Error handling */ const char *sieve_script_get_last_error(struct sieve_script *script, enum sieve_error *error_code_r); const char *sieve_script_get_last_error_lcase(struct sieve_script *script); /* * Script sequence */ struct sieve_script_sequence; int sieve_script_sequence_create(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const char *type, struct sieve_script_sequence **sseq_r, enum sieve_error *error_code_r, const char **error_r); int sieve_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r); void sieve_script_sequence_free(struct sieve_script_sequence **_seq); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary-code.c0000644000175100001700000002157015100335616025123 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "mempool.h" #include "buffer.h" #include "hash.h" #include "array.h" #include "ostream.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-script.h" #include "sieve-binary-private.h" /* * Forward declarations */ static inline sieve_size_t sieve_binary_emit_dynamic_data(struct sieve_binary_block *sblock, const void *data, size_t size); /* * Emission functions */ /* Low-level emission functions */ static inline void _sieve_binary_emit_data(struct sieve_binary_block *sblock, const void *data, sieve_size_t size) { buffer_append(sblock->data, data, size); } static inline void _sieve_binary_emit_byte(struct sieve_binary_block *sblock, uint8_t byte) { _sieve_binary_emit_data(sblock, &byte, 1); } static inline void _sieve_binary_update_data(struct sieve_binary_block *sblock, sieve_size_t address, const void *data, sieve_size_t size) { buffer_write(sblock->data, address, data, size); } sieve_size_t sieve_binary_emit_data(struct sieve_binary_block *sblock, const void *data, sieve_size_t size) { sieve_size_t address = _sieve_binary_block_get_size(sblock); _sieve_binary_emit_data(sblock, data, size); return address; } sieve_size_t sieve_binary_emit_byte(struct sieve_binary_block *sblock, uint8_t byte) { sieve_size_t address = _sieve_binary_block_get_size(sblock); _sieve_binary_emit_data(sblock, &byte, 1); return address; } void sieve_binary_update_data(struct sieve_binary_block *sblock, sieve_size_t address, const void *data, sieve_size_t size) { _sieve_binary_update_data(sblock, address, data, size); } /* Offset emission functions */ sieve_size_t sieve_binary_emit_offset(struct sieve_binary_block *sblock, sieve_offset_t offset) { sieve_size_t address = _sieve_binary_block_get_size(sblock); uint8_t encoded[sizeof(offset)]; int i; for (i = sizeof(offset)-1; i >= 0; i--) { encoded[i] = (uint8_t)offset; offset >>= 8; } _sieve_binary_emit_data(sblock, encoded, sizeof(offset)); return address; } void sieve_binary_resolve_offset(struct sieve_binary_block *sblock, sieve_size_t address) { sieve_size_t cur_address = _sieve_binary_block_get_size(sblock); sieve_offset_t offset; uint8_t encoded[sizeof(offset)]; int i; i_assert(cur_address > address); i_assert((cur_address - address) <= (sieve_offset_t)-1); offset = cur_address - address; for (i = sizeof(offset)-1; i >= 0; i--) { encoded[i] = (uint8_t)offset; offset >>= 8; } _sieve_binary_update_data(sblock, address, encoded, sizeof(offset)); } /* Literal emission */ sieve_size_t sieve_binary_emit_integer(struct sieve_binary_block *sblock, sieve_number_t integer) { sieve_size_t address = _sieve_binary_block_get_size(sblock); uint8_t buffer[sizeof(sieve_number_t) + 1]; int bufpos = sizeof(buffer) - 1; /* Encode last byte [0xxxxxxx]; msb == 0 marks the last byte */ buffer[bufpos] = integer & 0x7F; bufpos--; /* Encode first bytes [1xxxxxxx] */ integer >>= 7; while (integer > 0) { buffer[bufpos] = (integer & 0x7F) | 0x80; bufpos--; integer >>= 7; } /* Emit encoded integer */ bufpos++; _sieve_binary_emit_data(sblock, buffer + bufpos, sizeof(buffer) - bufpos); return address; } static inline sieve_size_t sieve_binary_emit_dynamic_data(struct sieve_binary_block *sblock, const void *data, sieve_size_t size) { sieve_size_t address = sieve_binary_emit_integer(sblock, (sieve_number_t)size); _sieve_binary_emit_data(sblock, data, size); return address; } sieve_size_t sieve_binary_emit_cstring(struct sieve_binary_block *sblock, const char *str) { sieve_size_t address = sieve_binary_emit_dynamic_data(sblock, str, (sieve_size_t)strlen(str)); _sieve_binary_emit_byte(sblock, 0); return address; } sieve_size_t sieve_binary_emit_string(struct sieve_binary_block *sblock, const string_t *str) { sieve_size_t address = sieve_binary_emit_dynamic_data(sblock, str_data(str), (sieve_size_t)str_len(str)); _sieve_binary_emit_byte(sblock, 0); return address; } /* * Extension emission */ sieve_size_t sieve_binary_emit_extension(struct sieve_binary_block *sblock, const struct sieve_extension *ext, unsigned int offset) { sieve_size_t address = _sieve_binary_block_get_size(sblock); struct sieve_binary_extension_reg *ereg = NULL; (void)sieve_binary_extension_register(sblock->sbin, ext, &ereg); i_assert(ereg != NULL); _sieve_binary_emit_byte(sblock, offset + ereg->index); return address; } void sieve_binary_emit_extension_object( struct sieve_binary_block *sblock, const struct sieve_extension_objects *objs, unsigned int code) { if (objs->count > 1) _sieve_binary_emit_byte(sblock, code); } /* * Code retrieval */ #define ADDR_CODE_READ(block) \ size_t _code_size; \ const int8_t *_code = buffer_get_data((block)->data, &_code_size) #define ADDR_CODE_AT(address) \ ((int8_t)(_code[*address])) #define ADDR_DATA_AT(address) \ ((uint8_t)(_code[*address])) #define ADDR_POINTER(address) \ ((const int8_t *)(&_code[*address])) #define ADDR_BYTES_LEFT(address) \ ((*address) > _code_size ? 0 : ((_code_size) - (*address))) #define ADDR_JUMP(address, offset) \ (*address) += offset /* Literals */ bool sieve_binary_read_byte(struct sieve_binary_block *sblock, sieve_size_t *address, unsigned int *byte_r) { ADDR_CODE_READ(sblock); if (ADDR_BYTES_LEFT(address) >= 1) { if (byte_r != NULL) *byte_r = ADDR_DATA_AT(address); ADDR_JUMP(address, 1); return TRUE; } if (byte_r != NULL) *byte_r = 0; return FALSE; } bool sieve_binary_read_code(struct sieve_binary_block *sblock, sieve_size_t *address, signed int *code_r) { ADDR_CODE_READ(sblock); if (ADDR_BYTES_LEFT(address) >= 1) { if (code_r != NULL) *code_r = ADDR_CODE_AT(address); ADDR_JUMP(address, 1); return TRUE; } if (code_r != NULL) *code_r = 0; return FALSE; } bool sieve_binary_read_offset(struct sieve_binary_block *sblock, sieve_size_t *address, sieve_offset_t *offset_r) { sieve_offset_t offs = 0; ADDR_CODE_READ(sblock); if (ADDR_BYTES_LEFT(address) >= 4) { int i; for (i = 0; i < 4; i++) { offs = (offs << 8) + ADDR_DATA_AT(address); ADDR_JUMP(address, 1); } if (offset_r != NULL) *offset_r = offs; return TRUE; } return FALSE; } /* FIXME: might need negative numbers in the future */ bool sieve_binary_read_integer(struct sieve_binary_block *sblock, sieve_size_t *address, sieve_number_t *int_r) { int bits = sizeof(sieve_number_t) * 8; sieve_number_t integer = 0; ADDR_CODE_READ(sblock); if (ADDR_BYTES_LEFT(address) == 0) return FALSE; /* Read first integer bytes [1xxxxxxx] */ while ((ADDR_DATA_AT(address) & 0x80) > 0) { if (ADDR_BYTES_LEFT(address) > 0 && bits > 0) { integer |= ADDR_DATA_AT(address) & 0x7F; ADDR_JUMP(address, 1); /* Each byte encodes 7 bits of the integer */ integer <<= 7; bits -= 7; } else { /* This is an error */ return FALSE; } } /* Read last byte [0xxxxxxx] */ integer |= ADDR_DATA_AT(address) & 0x7F; ADDR_JUMP(address, 1); if (int_r != NULL) *int_r = integer; return TRUE; } bool sieve_binary_read_string(struct sieve_binary_block *sblock, sieve_size_t *address, string_t **str_r) { unsigned int strlen = 0; const char *strdata; ADDR_CODE_READ(sblock); if (!sieve_binary_read_unsigned(sblock, address, &strlen)) return FALSE; if (strlen > ADDR_BYTES_LEFT(address)) return FALSE; strdata = (const char *)ADDR_POINTER(address); ADDR_JUMP(address, strlen); if (ADDR_CODE_AT(address) != 0) return FALSE; if (str_r != NULL) *str_r = t_str_new_const(strdata, strlen); ADDR_JUMP(address, 1); return TRUE; } bool sieve_binary_read_extension(struct sieve_binary_block *sblock, sieve_size_t *address, unsigned int *offset_r, const struct sieve_extension **ext_r) { unsigned int code; unsigned int offset = *offset_r; const struct sieve_extension *ext = NULL; ADDR_CODE_READ(sblock); if (ADDR_BYTES_LEFT(address) == 0) return FALSE; *offset_r = code = ADDR_DATA_AT(address); ADDR_JUMP(address, 1); if (code >= offset) { ext = sieve_binary_extension_get_by_index(sblock->sbin, (code - offset)); if (ext == NULL) return FALSE; } if (ext_r != NULL) *ext_r = ext; return TRUE; } const void * sieve_binary_read_extension_object(struct sieve_binary_block *sblock, sieve_size_t *address, const struct sieve_extension_objects *objs) { unsigned int code; ADDR_CODE_READ(sblock); if (objs->count == 0) return NULL; if (objs->count == 1) return objs->objects; if (ADDR_BYTES_LEFT(address) == 0) return NULL; code = ADDR_DATA_AT(address); ADDR_JUMP(address, 1); if (code >= objs->count) return NULL; return ((const void *const *)objs->objects)[code]; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-limits.h0000644000175100001700000000144615100335616024235 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_LIMITS_H #define SIEVE_LIMITS_H /* * Scripts */ #define SIEVE_MAX_SCRIPT_NAME_LEN 256 #define SIEVE_MAX_LOOP_DEPTH 4 /* * Lexer */ #define SIEVE_MAX_STRING_LEN (1 << 20) #define SIEVE_MAX_IDENTIFIER_LEN 32 /* * AST */ #define SIEVE_MAX_COMMAND_ARGUMENTS 32 #define SIEVE_MAX_BLOCK_NESTING 32 #define SIEVE_MAX_TEST_NESTING 32 /* * Runtime */ #define SIEVE_MAX_MATCH_VALUES 32 #define SIEVE_HIGH_CPU_TIME_MSECS 1500 #define SIEVE_DEFAULT_RESOURCE_USAGE_TIMEOUT_SECS /* * Actions */ #define SIEVE_MAX_SUBJECT_HEADER_CODEPOINTS 256 #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-error.h0000644000175100001700000001741015100335616024063 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_ERROR_H #define SIEVE_ERROR_H #include "lib.h" #include "compat.h" #include /* * Forward declarations */ struct var_expand_table; struct sieve_instance; struct sieve_script; struct sieve_error_handler; /* * Types */ enum sieve_error_flags { SIEVE_ERROR_FLAG_GLOBAL = (1 << 0), SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO = (1 << 1), }; struct sieve_error_params { enum log_type log_type; struct event *event; /* Location log command in C source code */ struct { const char *filename; unsigned int linenum; } csrc; /* Location in Sieve source script */ const char *location; }; /* * Utility */ /* Converts external messages to a style that better matches Sieve user errors */ const char *sieve_error_from_external(const char *msg); /* * Global (user+system) errors */ void sieve_global_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_info_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *fmt, va_list args) ATTR_FORMAT(4, 0); void sieve_global_error(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(6, 7); #define sieve_global_error(svinst, ehandler, ...) \ sieve_global_error(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_global_warning(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(6, 7); #define sieve_global_warning(svinst, ehandler, ...) \ sieve_global_warning(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_global_info(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(6, 7); #define sieve_global_info(svinst, ehandler, ...) \ sieve_global_info(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_global_info_error(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(6, 7); #define sieve_global_info_error(svinst, ehandler, ...) \ sieve_global_info_error(svinst, ehandler, __FILE__, __LINE__, \ __VA_ARGS__) void sieve_global_info_warning(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(6, 7); #define sieve_global_info_warning(svinst, ehandler, ...) \ sieve_global_info_warning(svinst, ehandler, __FILE__, __LINE__, \ __VA_ARGS__) /* * Main (user) error functions */ /* For these functions it is the responsibility of the caller to * manage the datastack. */ const char * sieve_error_script_location(const struct sieve_script *script, unsigned int source_line); void sieve_logv(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *fmt, va_list args) ATTR_FORMAT(3, 0); void sieve_event_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, struct event *event, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *location, enum sieve_error_flags flags, const char *fmt, va_list args) ATTR_FORMAT(9, 0); void sieve_event_log(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, struct event *event, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *location, enum sieve_error_flags flags, const char *fmt, ...) ATTR_FORMAT(9, 10); #define sieve_event_log(svinst, ehandler, event, log_type, ...) \ sieve_event_log(svinst, ehandler, event, log_type, __FILE__, __LINE__, \ __VA_ARGS__) void sieve_criticalv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *user_prefix, const char *fmt, va_list args) ATTR_FORMAT(5, 0); void sieve_error(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_error(ehandler, ...) \ sieve_error(ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_warning(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_warning(ehandler, ...) \ sieve_warning(ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_info(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_info(ehandler, ...) \ sieve_info(ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_debug(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_debug(ehandler, ...) \ sieve_debug(ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_critical(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *user_prefix, const char *fmt, ...) ATTR_FORMAT(7, 8); #define sieve_critical(svinst, ehandler, ...) \ sieve_critical(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__) void sieve_internal_error_params(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, const char *user_prefix); void sieve_internal_error(struct sieve_error_handler *ehandler, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *user_prefix) ATTR_NULL(1, 4, 5); #define sieve_internal_error(ehandler, ...) \ sieve_internal_error(ehandler, __FILE__, __LINE__, __VA_ARGS__) /* * Error handler configuration */ void sieve_error_handler_accept_infolog(struct sieve_error_handler *ehandler, bool enable); void sieve_error_handler_accept_debuglog(struct sieve_error_handler *ehandler, bool enable); /* * Error handler statistics */ unsigned int sieve_get_errors(struct sieve_error_handler *ehandler); unsigned int sieve_get_warnings(struct sieve_error_handler *ehandler); bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler); /* * Error handler object */ void sieve_error_handler_ref(struct sieve_error_handler *ehandler); void sieve_error_handler_unref(struct sieve_error_handler **ehandler); void sieve_error_handler_reset(struct sieve_error_handler *ehandler); /* * Error handlers */ /* Write errors to dovecot master log */ struct sieve_error_handler * sieve_master_ehandler_create(struct sieve_instance *svinst, unsigned int max_errors); /* Write errors to stderr */ struct sieve_error_handler * sieve_stderr_ehandler_create(struct sieve_instance *svinst, unsigned int max_errors); /* Write errors into a string buffer */ struct sieve_error_handler * sieve_strbuf_ehandler_create(struct sieve_instance *svinst, string_t *strbuf, bool crlf, unsigned int max_errors); /* Write errors to a logfile */ struct sieve_error_handler * sieve_logfile_ehandler_create(struct sieve_instance *svinst, const char *logfile, unsigned int max_errors); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-ast.c0000644000175100001700000006225315100335616023521 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "mempool.h" #include "array.h" #include "sieve-common.h" #include "sieve-script.h" #include "sieve-extensions.h" #include "sieve-ast.h" #include /* * Forward declarations */ static struct sieve_ast_node * sieve_ast_node_create(struct sieve_ast *ast, struct sieve_ast_node *parent, enum sieve_ast_type type, unsigned int source_line); /* * Types */ /* Extensions to the AST */ struct sieve_ast_extension_reg { const struct sieve_extension *ext; const struct sieve_ast_extension *ast_ext; void *context; bool required:1; }; /* * AST object */ struct sieve_ast { pool_t pool; int refcount; struct sieve_instance *svinst; struct sieve_script *script; struct sieve_ast_node *root; ARRAY(const struct sieve_extension *) linked_extensions; ARRAY(struct sieve_ast_extension_reg) extensions; }; struct sieve_ast *sieve_ast_create(struct sieve_script *script) { pool_t pool; struct sieve_ast *ast; unsigned int ext_count; pool = pool_alloconly_create("sieve_ast", 32768); ast = p_new(pool, struct sieve_ast, 1); ast->pool = pool; ast->refcount = 1; ast->script = script; sieve_script_ref(script); ast->svinst = sieve_script_svinst(script); ast->root = sieve_ast_node_create(ast, NULL, SAT_ROOT, 0); ast->root->identifier = "ROOT"; ext_count = sieve_extensions_get_count(ast->svinst); p_array_init(&ast->linked_extensions, pool, ext_count); p_array_init(&ast->extensions, pool, ext_count); return ast; } void sieve_ast_ref(struct sieve_ast *ast) { ast->refcount++; } void sieve_ast_unref(struct sieve_ast **ast) { unsigned int i, ext_count; const struct sieve_ast_extension_reg *extrs; i_assert((*ast)->refcount > 0); if (--(*ast)->refcount != 0) return; /* Release script reference */ sieve_script_unref(&(*ast)->script); /* Signal registered extensions that the AST is being destroyed */ extrs = array_get(&(*ast)->extensions, &ext_count); for (i = 0; i < ext_count; i++) { if (extrs[i].ast_ext != NULL && extrs[i].ast_ext->free != NULL) extrs[i].ast_ext->free(extrs[i].ext, *ast, extrs[i].context); } /* Destroy AST */ pool_unref(&(*ast)->pool); *ast = NULL; } struct sieve_ast_node *sieve_ast_root(struct sieve_ast *ast) { return ast->root; } pool_t sieve_ast_pool(struct sieve_ast *ast) { return ast->pool; } struct sieve_script *sieve_ast_script(struct sieve_ast *ast) { return ast->script; } /* * Extension support */ void sieve_ast_extension_link(struct sieve_ast *ast, const struct sieve_extension *ext, bool required) { unsigned int i, ext_count; const struct sieve_extension *const *extensions; struct sieve_ast_extension_reg *reg; if (ext->id < 0) return; /* Initialize registration */ reg = array_idx_get_space(&ast->extensions, (unsigned int)ext->id); i_assert(reg->ext == NULL || reg->ext == ext); reg->ext = ext; reg->required = reg->required || required; /* Prevent duplicates */ extensions = array_get(&ast->linked_extensions, &ext_count); for (i = 0; i < ext_count; i++) { if (extensions[i] == ext) return; } /* Add extension */ array_append(&ast->linked_extensions, &ext, 1); } const struct sieve_extension *const * sieve_ast_extensions_get(struct sieve_ast *ast, unsigned int *count_r) { return array_get(&ast->linked_extensions, count_r); } void sieve_ast_extension_register(struct sieve_ast *ast, const struct sieve_extension *ext, const struct sieve_ast_extension *ast_ext, void *context) { struct sieve_ast_extension_reg *reg; if (ext->id < 0) return; /* Initialize registration */ reg = array_idx_get_space(&ast->extensions, (unsigned int)ext->id); i_assert(reg->ext == NULL || reg->ext == ext); reg->ext = ext; reg->ast_ext = ast_ext; reg->context = context; } void sieve_ast_extension_set_context(struct sieve_ast *ast, const struct sieve_extension *ext, void *context) { struct sieve_ast_extension_reg *reg; if (ext->id < 0) return; reg = array_idx_get_space(&ast->extensions, (unsigned int)ext->id); reg->context = context; } void *sieve_ast_extension_get_context(struct sieve_ast *ast, const struct sieve_extension *ext) { const struct sieve_ast_extension_reg *reg; if (ext->id < 0 || ext->id >= (int)array_count(&ast->extensions)) return NULL; reg = array_idx(&ast->extensions, (unsigned int)ext->id); return reg->context; } bool sieve_ast_extension_is_required (struct sieve_ast *ast, const struct sieve_extension *ext) { const struct sieve_ast_extension_reg *reg; i_assert(ext->id >= 0 && ext->id < (int)array_count(&ast->extensions)); reg = array_idx(&ast->extensions, (unsigned int)ext->id); return reg->required; } /* * AST list implementations */ /* Very simplistic linked list implementation FIXME: Merge with core */ #define __LIST_CREATE(pool, type) { \ type *list = p_new(pool, type, 1); \ list->head = NULL; \ list->tail = NULL; \ list->len = 0; \ return list; \ } #define __LIST_ADD(list, node) { \ if (list->len + 1 < list->len) \ return FALSE; \ \ node->next = NULL; \ if (list->head == NULL) { \ node->prev = NULL; \ list->head = node; \ list->tail = node; \ } else { \ list->tail->next = node; \ node->prev = list->tail; \ list->tail = node; \ } \ list->len++; \ node->list = list; \ return TRUE; \ } #define __LIST_INSERT(list, before, node) { \ if (list->len + 1 < list->len) \ return FALSE; \ \ node->next = before; \ if (list->head == before) { \ node->prev = NULL; \ list->head = node; \ } else { \ before->prev->next = node; \ } \ node->prev = before->prev; \ before->prev = node; \ list->len++; \ node->list = list; \ \ return TRUE; \ } #define __LIST_JOIN(list, node_type, items) { \ node_type *node; \ \ if (list->len + items->len < list->len) \ return FALSE; \ \ if (items->len == 0) \ return TRUE; \ \ if (list->head == NULL) { \ list->head = items->head; \ list->tail = items->tail; \ } else { \ list->tail->next = items->head; \ items->head->prev = list->tail; \ list->tail = items->tail; \ } \ list->len += items->len; \ \ node = items->head; \ while (node != NULL) { \ node->list = list; \ node = node->next; \ } \ return TRUE; \ } #define __LIST_DETACH(first, node_type, count) { \ node_type *last, *result; \ unsigned int left; \ \ i_assert(first->list != NULL); \ \ left = count - 1; \ last = first; \ while (left > 0 && last->next != NULL) { \ left--; \ last = last->next; \ } \ \ if (first->list->head == first) \ first->list->head = last->next; \ if (first->list->tail == last) \ first->list->tail = first->prev; \ \ if (first->prev != NULL) \ first->prev->next = last->next; \ if (last->next != NULL) \ last->next->prev = first->prev; \ \ first->list->len -= count - left; \ \ result = last->next; \ first->prev = NULL; \ last->next = NULL; \ \ return result; \ } /* List of AST nodes */ static struct sieve_ast_list * sieve_ast_list_create(pool_t pool) __LIST_CREATE(pool, struct sieve_ast_list) static bool sieve_ast_list_add(struct sieve_ast_list *list, struct sieve_ast_node *node) __LIST_ADD(list, node) static struct sieve_ast_node * sieve_ast_list_detach(struct sieve_ast_node *first, unsigned int count) __LIST_DETACH(first, struct sieve_ast_node, count) /* List of argument AST nodes */ struct sieve_ast_arg_list *sieve_ast_arg_list_create(pool_t pool) __LIST_CREATE(pool, struct sieve_ast_arg_list) bool sieve_ast_arg_list_add(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument) __LIST_ADD(list, argument) bool sieve_ast_arg_list_insert(struct sieve_ast_arg_list *list, struct sieve_ast_argument *before, struct sieve_ast_argument *argument) __LIST_INSERT(list, before, argument) static bool sieve_ast_arg_list_join(struct sieve_ast_arg_list *list, struct sieve_ast_arg_list *items) __LIST_JOIN(list, struct sieve_ast_argument, items) static struct sieve_ast_argument * sieve_ast_arg_list_detach(struct sieve_ast_argument *first, const unsigned int count) __LIST_DETACH(first, struct sieve_ast_argument, count) void sieve_ast_arg_list_substitute(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument, struct sieve_ast_argument *replacement) { if (list->head == argument) list->head = replacement; if (list->tail == argument) list->tail = replacement; if (argument->prev != NULL) argument->prev->next = replacement; if (argument->next != NULL) argument->next->prev = replacement; replacement->prev = argument->prev; replacement->next = argument->next; replacement->list = argument->list; argument->next = NULL; argument->prev = NULL; } /* * AST node */ static struct sieve_ast_node * sieve_ast_node_create(struct sieve_ast *ast, struct sieve_ast_node *parent, enum sieve_ast_type type, unsigned int source_line) { struct sieve_ast_node *node = p_new(ast->pool, struct sieve_ast_node, 1); node->ast = ast; node->parent = parent; node->type = type; node->prev = NULL; node->next = NULL; node->arguments = NULL; node->tests = NULL; node->commands = NULL; node->test_list = FALSE; node->block = FALSE; node->source_line = source_line; return node; } static bool sieve_ast_node_add_command(struct sieve_ast_node *node, struct sieve_ast_node *command) { i_assert(command->type == SAT_COMMAND && (node->type == SAT_ROOT || node->type == SAT_COMMAND)); if (node->commands == NULL) node->commands = sieve_ast_list_create(node->ast->pool); return sieve_ast_list_add(node->commands, command); } static bool sieve_ast_node_add_test(struct sieve_ast_node *node, struct sieve_ast_node *test) { i_assert(test->type == SAT_TEST && (node->type == SAT_TEST || node->type == SAT_COMMAND)); if (node->tests == NULL) node->tests = sieve_ast_list_create(node->ast->pool); return sieve_ast_list_add(node->tests, test); } static bool sieve_ast_node_add_argument(struct sieve_ast_node *node, struct sieve_ast_argument *argument) { i_assert(node->type == SAT_TEST || node->type == SAT_COMMAND); if (node->arguments == NULL) node->arguments = sieve_ast_arg_list_create(node->ast->pool); return sieve_ast_arg_list_add(node->arguments, argument); } struct sieve_ast_node *sieve_ast_node_detach(struct sieve_ast_node *first) { return sieve_ast_list_detach(first, 1); } const char *sieve_ast_type_name(enum sieve_ast_type ast_type) { switch (ast_type) { case SAT_NONE: return "none"; case SAT_ROOT: return "ast root node"; case SAT_COMMAND: return "command"; case SAT_TEST: return "test"; default: return "??AST NODE??"; } } /* * Argument AST node */ struct sieve_ast_argument * sieve_ast_argument_create(struct sieve_ast *ast, unsigned int source_line) { struct sieve_ast_argument *arg = p_new(ast->pool, struct sieve_ast_argument, 1); arg->ast = ast; arg->prev = NULL; arg->next = NULL; arg->source_line = source_line; arg->argument = NULL; return arg; } static void sieve_ast_argument_substitute(struct sieve_ast_argument *argument, struct sieve_ast_argument *replacement) { sieve_ast_arg_list_substitute(argument->list, argument, replacement); } struct sieve_ast_argument * sieve_ast_argument_string_create_raw(struct sieve_ast *ast, string_t *str, unsigned int source_line) { struct sieve_ast_argument *argument = sieve_ast_argument_create(ast, source_line); argument->type = SAAT_STRING; argument->_value.str = str; return argument; } struct sieve_ast_argument * sieve_ast_argument_string_create(struct sieve_ast_node *node, const string_t *str, unsigned int source_line) { struct sieve_ast_argument *argument; string_t *newstr; /* Allocate new internal string buffer */ newstr = str_new(node->ast->pool, str_len(str)); /* Clone string */ str_append_str(newstr, str); /* Create string argument */ argument = sieve_ast_argument_string_create_raw( node->ast, newstr, source_line); /* Add argument to command/test node */ sieve_ast_node_add_argument(node, argument); return argument; } struct sieve_ast_argument * sieve_ast_argument_cstring_create(struct sieve_ast_node *node, const char *str, unsigned int source_line) { struct sieve_ast_argument *argument; string_t *newstr; /* Allocate new internal string buffer */ newstr = str_new(node->ast->pool, strlen(str)); /* Clone string */ str_append(newstr, str); /* Create string argument */ argument = sieve_ast_argument_string_create_raw( node->ast, newstr, source_line); /* Add argument to command/test node */ sieve_ast_node_add_argument(node, argument); return argument; } void sieve_ast_argument_string_set(struct sieve_ast_argument *argument, string_t *newstr) { i_assert(argument->type == SAAT_STRING); argument->_value.str = newstr; } void sieve_ast_argument_string_setc(struct sieve_ast_argument *argument, const char *newstr) { i_assert(argument->type == SAAT_STRING); str_truncate(argument->_value.str, 0); str_append(argument->_value.str, newstr); } void sieve_ast_argument_number_substitute(struct sieve_ast_argument *argument, sieve_number_t number) { argument->type = SAAT_NUMBER; argument->_value.number = number; } struct sieve_ast_argument * sieve_ast_argument_stringlist_create(struct sieve_ast_node *node, unsigned int source_line) { struct sieve_ast_argument *argument = sieve_ast_argument_create(node->ast, source_line); argument->type = SAAT_STRING_LIST; argument->_value.strlist = NULL; sieve_ast_node_add_argument(node, argument); return argument; } struct sieve_ast_argument * sieve_ast_argument_stringlist_substitute(struct sieve_ast_node *node, struct sieve_ast_argument *arg) { struct sieve_ast_argument *argument = sieve_ast_argument_create(node->ast, arg->source_line); argument->type = SAAT_STRING_LIST; argument->_value.strlist = NULL; sieve_ast_argument_substitute(arg, argument); return argument; } static inline bool _sieve_ast_stringlist_add_item(struct sieve_ast_argument *list, struct sieve_ast_argument *item) { i_assert(list->type == SAAT_STRING_LIST); if (list->_value.strlist == NULL) { list->_value.strlist = sieve_ast_arg_list_create(list->ast->pool); } return sieve_ast_arg_list_add(list->_value.strlist, item); } static bool sieve_ast_stringlist_add_stringlist(struct sieve_ast_argument *list, struct sieve_ast_argument *items) { i_assert(list->type == SAAT_STRING_LIST); i_assert(items->type == SAAT_STRING_LIST); if (list->_value.strlist == NULL) { list->_value.strlist = sieve_ast_arg_list_create(list->ast->pool); } return sieve_ast_arg_list_join(list->_value.strlist, items->_value.strlist); } static bool _sieve_ast_stringlist_add_str(struct sieve_ast_argument *list, string_t *str, unsigned int source_line) { struct sieve_ast_argument *stritem; stritem = sieve_ast_argument_create(list->ast, source_line); stritem->type = SAAT_STRING; stritem->_value.str = str; return _sieve_ast_stringlist_add_item(list, stritem); } bool sieve_ast_stringlist_add(struct sieve_ast_argument *list, const string_t *str, unsigned int source_line) { string_t *copied_str = str_new(list->ast->pool, str_len(str)); str_append_str(copied_str, str); return _sieve_ast_stringlist_add_str(list, copied_str, source_line); } bool sieve_ast_stringlist_add_strc(struct sieve_ast_argument *list, const char *str, unsigned int source_line) { string_t *copied_str = str_new(list->ast->pool, strlen(str)); str_append(copied_str, str); return _sieve_ast_stringlist_add_str(list, copied_str, source_line); } struct sieve_ast_argument * sieve_ast_argument_tag_create(struct sieve_ast_node *node, const char *tag, unsigned int source_line) { struct sieve_ast_argument *argument = sieve_ast_argument_create(node->ast, source_line); argument->type = SAAT_TAG; argument->_value.tag = p_strdup(node->ast->pool, tag); if (!sieve_ast_node_add_argument(node, argument)) return NULL; return argument; } struct sieve_ast_argument * sieve_ast_argument_tag_insert(struct sieve_ast_argument *before, const char *tag, unsigned int source_line) { struct sieve_ast_argument *argument = sieve_ast_argument_create(before->ast, source_line); argument->type = SAAT_TAG; argument->_value.tag = p_strdup(before->ast->pool, tag); if (!sieve_ast_arg_list_insert(before->list, before, argument)) return NULL; return argument; } struct sieve_ast_argument * sieve_ast_argument_number_create(struct sieve_ast_node *node, sieve_number_t number, unsigned int source_line) { struct sieve_ast_argument *argument = sieve_ast_argument_create(node->ast, source_line); argument->type = SAAT_NUMBER; argument->_value.number = number; if (!sieve_ast_node_add_argument(node, argument)) return NULL; return argument; } void sieve_ast_argument_number_set(struct sieve_ast_argument *argument, sieve_number_t newnum) { i_assert(argument->type == SAAT_NUMBER); argument->_value.number = newnum; } struct sieve_ast_argument * sieve_ast_arguments_detach(struct sieve_ast_argument *first, unsigned int count) { return sieve_ast_arg_list_detach(first, count); } bool sieve_ast_argument_attach(struct sieve_ast_node *node, struct sieve_ast_argument *argument) { return sieve_ast_node_add_argument(node, argument); } const char *sieve_ast_argument_type_name(enum sieve_ast_argument_type arg_type) { switch (arg_type) { case SAAT_NONE: return "none"; case SAAT_STRING_LIST: return "a string list"; case SAAT_STRING: return "a string"; case SAAT_NUMBER: return "a number"; case SAAT_TAG: return "a tag"; default: return "??ARGUMENT??"; } } /* Test AST node */ struct sieve_ast_node * sieve_ast_test_create(struct sieve_ast_node *parent, const char *identifier, unsigned int source_line) { struct sieve_ast_node *test = sieve_ast_node_create( parent->ast, parent, SAT_TEST, source_line); test->identifier = p_strdup(parent->ast->pool, identifier); if (!sieve_ast_node_add_test(parent, test)) return NULL; return test; } /* Command AST node */ struct sieve_ast_node * sieve_ast_command_create(struct sieve_ast_node *parent, const char *identifier, unsigned int source_line) { struct sieve_ast_node *command = sieve_ast_node_create( parent->ast, parent, SAT_COMMAND, source_line); command->identifier = p_strdup(parent->ast->pool, identifier); if (!sieve_ast_node_add_command(parent, command)) return NULL; return command; } /* * Utility */ int sieve_ast_stringlist_map( struct sieve_ast_argument **listitem, void *context, int (*map_function)(void *context, struct sieve_ast_argument *arg)) { if (sieve_ast_argument_type(*listitem) == SAAT_STRING) { /* Single string */ return map_function(context, *listitem); } else if (sieve_ast_argument_type(*listitem) == SAAT_STRING_LIST) { int ret = 0; /* String list */ *listitem = sieve_ast_strlist_first(*listitem); while (*listitem != NULL) { if ((ret = map_function(context, *listitem)) <= 0) return ret; *listitem = sieve_ast_strlist_next(*listitem); } return ret; } i_unreached(); } struct sieve_ast_argument * sieve_ast_stringlist_join(struct sieve_ast_argument *list, struct sieve_ast_argument *items) { enum sieve_ast_argument_type list_type, items_type; struct sieve_ast_argument *newlist; list_type = sieve_ast_argument_type(list); items_type = sieve_ast_argument_type(items); switch (list_type) { case SAAT_STRING: switch (items_type) { case SAAT_STRING: newlist = sieve_ast_argument_create( list->ast, list->source_line); newlist->type = SAAT_STRING_LIST; newlist->_value.strlist = NULL; sieve_ast_argument_substitute(list, newlist); sieve_ast_arguments_detach(items, 1); if (!_sieve_ast_stringlist_add_item(newlist, list) || !_sieve_ast_stringlist_add_item(newlist, items)) return NULL; return newlist; case SAAT_STRING_LIST: /* Adding stringlist to string; make them swith places and add one to the other. */ sieve_ast_arguments_detach(items, 1); sieve_ast_argument_substitute(list, items); if (!_sieve_ast_stringlist_add_item(items, list)) return NULL; return list; default: i_unreached(); } break; case SAAT_STRING_LIST: switch (items_type) { case SAAT_STRING: /* Adding string to stringlist; straightforward add */ sieve_ast_arguments_detach(items, 1); if (!_sieve_ast_stringlist_add_item(list, items)) return NULL; return list; case SAAT_STRING_LIST: /* Adding stringlist to stringlist; perform actual join */ sieve_ast_arguments_detach(items, 1); if (!sieve_ast_stringlist_add_stringlist(list, items)) return NULL; return list; default: i_unreached(); } break; default: i_unreached(); } return NULL; } /* Debug */ /* Unparsing, currently implemented using plain printf()s */ static void sieve_ast_unparse_string(const string_t *strval) { char *str = t_strdup_noconst(str_c((string_t *)strval)); if (strchr(str, '\n') != NULL && str[strlen(str)-1] == '\n') { /* Print it as a multi-line string and do required dotstuffing */ char *spos = str; char *epos = strchr(str, '\n'); printf("text:\n"); while (epos != NULL) { *epos = '\0'; if (*spos == '.') printf("."); printf("%s\n", spos); spos = epos+1; epos = strchr(spos, '\n'); } if (*spos == '.') printf("."); printf("%s\n.\n", spos); } else { /* Print it as a quoted string and escape " */ char *spos = str; char *epos = strchr(str, '"'); printf("\""); while (epos != NULL) { *epos = '\0'; printf("%s\\\"", spos); spos = epos+1; epos = strchr(spos, '"'); } printf("%s\"", spos); } } static void sieve_ast_unparse_argument(struct sieve_ast_argument *argument, int level); static void sieve_ast_unparse_stringlist(struct sieve_ast_argument *strlist, int level) { struct sieve_ast_argument *stritem; if (sieve_ast_strlist_count(strlist) > 1) { int i; printf("[\n"); /* Create indent */ for (i = 0; i < level+2; i++) printf(" "); stritem = sieve_ast_strlist_first(strlist); if (stritem != NULL) { sieve_ast_unparse_string( sieve_ast_strlist_str(stritem)); stritem = sieve_ast_strlist_next(stritem); while (stritem != NULL) { printf(",\n"); for (i = 0; i < level+2; i++) printf(" "); sieve_ast_unparse_string( sieve_ast_strlist_str(stritem)); stritem = sieve_ast_strlist_next(stritem); } } printf(" ]"); } else { stritem = sieve_ast_strlist_first(strlist); if (stritem != NULL) { sieve_ast_unparse_string( sieve_ast_strlist_str(stritem)); } } } static void sieve_ast_unparse_argument(struct sieve_ast_argument *argument, int level) { switch (argument->type) { case SAAT_STRING: sieve_ast_unparse_string(sieve_ast_argument_str(argument)); break; case SAAT_STRING_LIST: sieve_ast_unparse_stringlist(argument, level+1); break; case SAAT_NUMBER: printf("%"SIEVE_PRI_NUMBER, sieve_ast_argument_number(argument)); break; case SAAT_TAG: printf(":%s", sieve_ast_argument_tag(argument)); break; default: printf("??ARGUMENT??"); break; } } static void sieve_ast_unparse_test(struct sieve_ast_node *node, int level); static void sieve_ast_unparse_tests(struct sieve_ast_node *node, int level) { struct sieve_ast_node *test; if (sieve_ast_test_count(node) > 1) { int i; printf(" (\n"); /* Create indent */ for (i = 0; i < level+2; i++) printf(" "); test = sieve_ast_test_first(node); sieve_ast_unparse_test(test, level+1); test = sieve_ast_test_next(test); while (test != NULL) { printf(", \n"); for (i = 0; i < level+2; i++) printf(" "); sieve_ast_unparse_test(test, level+1); test = sieve_ast_test_next(test); } printf(" )"); } else { test = sieve_ast_test_first(node); if (test != NULL) sieve_ast_unparse_test(test, level); } } static void sieve_ast_unparse_test(struct sieve_ast_node *node, int level) { struct sieve_ast_argument *argument; printf(" %s", node->identifier); argument = sieve_ast_argument_first(node); while (argument != NULL) { printf(" "); sieve_ast_unparse_argument(argument, level); argument = sieve_ast_argument_next(argument); } sieve_ast_unparse_tests(node, level); } static void sieve_ast_unparse_command(struct sieve_ast_node *node, int level) { struct sieve_ast_node *command; struct sieve_ast_argument *argument; int i; /* Create indent */ for (i = 0; i < level; i++) printf(" "); printf("%s", node->identifier); argument = sieve_ast_argument_first(node); while (argument != NULL) { printf(" "); sieve_ast_unparse_argument(argument, level); argument = sieve_ast_argument_next(argument); } sieve_ast_unparse_tests(node, level); command = sieve_ast_command_first(node); if (command != NULL) { printf(" {\n"); while (command != NULL) { sieve_ast_unparse_command(command, level+1); command = sieve_ast_command_next(command); } for (i = 0; i < level; i++) printf(" "); printf("}\n"); } else printf(";\n"); } void sieve_ast_unparse(struct sieve_ast *ast) { struct sieve_ast_node *command; printf("Unparsing Abstract Syntax Tree:\n"); T_BEGIN { command = sieve_ast_command_first(sieve_ast_root(ast)); while (command != NULL) { sieve_ast_unparse_command(command, 0); command = sieve_ast_command_next(command); } } T_END; } dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-header.c0000644000175100001700000001204615100335616023654 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" /* * Header test * * Syntax: * header [COMPARATOR] [MATCH-TYPE] * */ static bool tst_header_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_header_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_header_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *tst); const struct sieve_command_def tst_header = { .identifier = "header", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_header_registered, .validate = tst_header_validate, .generate = tst_header_generate }; /* * Header operation */ static bool tst_header_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_header_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_header_operation = { .mnemonic = "HEADER", .code = SIEVE_OPERATION_HEADER, .dump = tst_header_operation_dump, .execute = tst_header_operation_execute }; /* * Test registration */ static bool tst_header_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); return TRUE; } /* * Validation */ static bool tst_header_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "header names", 1, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; if ( !sieve_command_verify_headers_argument(valdtr, arg) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate (valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_header_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { sieve_operation_emit(cgenv->sblock, NULL, &tst_header_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_header_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "HEADER"); sieve_code_descend(denv); /* Optional operands */ if ( sieve_message_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return sieve_opr_stringlist_dump(denv, address, "header names") && sieve_opr_stringlist_dump(denv, address, "key list"); } /* * Code execution */ static int tst_header_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_stringlist *hdr_list, *key_list, *value_list; ARRAY_TYPE(sieve_message_override) svmos; int match, ret; /* * Read operands */ /* Optional operands */ i_zero(&svmos); if ( sieve_message_opr_optional_read (renv, address, NULL, &ret, NULL, &mcht, &cmp, &svmos) < 0 ) return ret; /* Read header-list */ if ( (ret=sieve_opr_stringlist_read(renv, address, "header-list", &hdr_list)) <= 0 ) return ret; /* Read key-list */ if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) <= 0 ) return ret; /* * Perform test */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "header test"); /* Get header */ sieve_runtime_trace_descend(renv); if ( (ret=sieve_message_get_header_fields (renv, hdr_list, &svmos, TRUE, &value_list)) <= 0 ) return ret; sieve_runtime_trace_ascend(renv); /* Perform match */ if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-allof.c0000644000175100001700000000531115100335616023516 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-binary.h" /* * Allof test * * Syntax * allof */ static bool tst_allof_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true); static bool tst_allof_validate_const (struct sieve_validator *valdtr, struct sieve_command *tst, int *const_current, int const_new); const struct sieve_command_def tst_allof = { .identifier = "allof", .type = SCT_TEST, .positional_args = 0, .subtests = 2, .block_allowed = FALSE, .block_required = FALSE, .validate_const = tst_allof_validate_const, .control_generate = tst_allof_generate }; /* * Code validation */ static bool tst_allof_validate_const (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst ATTR_UNUSED, int *const_current, int const_next) { if ( const_next == 0 ) { *const_current = 0; return FALSE; } if ( *const_current != -1 ) *const_current = const_next; return TRUE; } /* * Code generation */ static bool tst_allof_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true) { struct sieve_binary_block *sblock = cgenv->sblock; struct sieve_ast_node *test; struct sieve_jumplist false_jumps; if ( sieve_ast_test_count(ctx->ast_node) > 1 ) { if ( jump_true ) { /* Prepare jumplist */ sieve_jumplist_init_temp(&false_jumps, sblock); } test = sieve_ast_test_first(ctx->ast_node); while ( test != NULL ) { bool result; /* If this test list must jump on false, all sub-tests can simply add their jumps * to the caller's jump list, otherwise this test redirects all false jumps to the * end of the currently generated code. This is just after a final jump to the true * case */ if ( jump_true ) result = sieve_generate_test(cgenv, test, &false_jumps, FALSE); else result = sieve_generate_test(cgenv, test, jumps, FALSE); if ( !result ) return FALSE; test = sieve_ast_test_next(test); } if ( jump_true ) { /* All tests succeeded, jump to case TRUE */ sieve_operation_emit(cgenv->sblock, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(sblock, 0)); /* All false exits jump here */ sieve_jumplist_resolve(&false_jumps); } } else { /* Script author is being inefficient; we can optimize the allof test away */ test = sieve_ast_test_first(ctx->ast_node); sieve_generate_test(cgenv, test, jumps, jump_true); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-code-dumper.h0000644000175100001700000000306215100335616025134 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_CODE_DUMPER_H #define SIEVE_CODE_DUMPER_H #include "sieve-common.h" struct sieve_code_dumper; struct sieve_code_dumper *sieve_code_dumper_create (struct sieve_dumptime_env *denv); void sieve_code_dumper_free (struct sieve_code_dumper **_dumper); pool_t sieve_code_dumper_pool (struct sieve_code_dumper *dumper); /* * Extension support */ struct sieve_code_dumper_extension { const struct sieve_extension_def *ext; void (*free)(struct sieve_code_dumper *dumper, void *context); }; void sieve_dump_extension_register (struct sieve_code_dumper *dumper, const struct sieve_extension *ext, const struct sieve_code_dumper_extension *dump_ext, void *context); void sieve_dump_extension_set_context (struct sieve_code_dumper *dumper, const struct sieve_extension *ext, void *context); void *sieve_dump_extension_get_context (struct sieve_code_dumper *dumper, const struct sieve_extension *ext); /* Dump functions */ void sieve_code_dumpf (const struct sieve_dumptime_env *denv, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_code_mark(const struct sieve_dumptime_env *denv); void sieve_code_mark_specific (const struct sieve_dumptime_env *denv, sieve_size_t location); void sieve_code_descend(const struct sieve_dumptime_env *denv); void sieve_code_ascend(const struct sieve_dumptime_env *denv); /* Operations and operands */ bool sieve_code_dumper_print_optional_operands (const struct sieve_dumptime_env *denv, sieve_size_t *address); /* Code dump (debugging purposes) */ void sieve_code_dumper_run(struct sieve_code_dumper *dumper); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-address-parts.h0000644000175100001700000000672615100335616025516 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_ADDRESS_PARTS_H #define SIEVE_ADDRESS_PARTS_H #include "message-address.h" #include "sieve-common.h" #include "sieve-match.h" #include "sieve-extensions.h" #include "sieve-objects.h" /* * Address part definition */ struct sieve_address_part_def { struct sieve_object_def obj_def; const char * (*extract_from)(const struct sieve_address_part *addrp, const struct smtp_address *address); }; /* * Address part instance */ struct sieve_address_part { struct sieve_object object; const struct sieve_address_part_def *def; }; #define SIEVE_ADDRESS_PART_DEFAULT(definition) \ { SIEVE_OBJECT_DEFAULT(definition), &(definition) }; #define sieve_address_part_name(addrp) \ ( (addrp)->object.def->identifier ) #define sieve_address_part_is(addrp, definition) \ ( (addrp)->def == &(definition) ) /* * Core address parts */ enum sieve_address_part_code { SIEVE_ADDRESS_PART_ALL, SIEVE_ADDRESS_PART_LOCAL, SIEVE_ADDRESS_PART_DOMAIN, SIEVE_ADDRESS_PART_CUSTOM }; extern const struct sieve_address_part_def all_address_part; extern const struct sieve_address_part_def local_address_part; extern const struct sieve_address_part_def domain_address_part; /* * Address part tagged argument */ extern const struct sieve_argument_def address_part_tag; void sieve_address_parts_link_tags(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code); /* * Address part registry */ void sieve_address_part_register(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_address_part_def *addrp); /* * Address part operand */ extern const struct sieve_operand_def address_part_operand; extern const struct sieve_operand_class sieve_address_part_operand_class; #define SIEVE_EXT_DEFINE_ADDRESS_PART(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_ADDRESS_PARTS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) static inline void sieve_opr_address_part_emit(struct sieve_binary_block *sblock, const struct sieve_address_part *addrp) { sieve_opr_object_emit(sblock, addrp->object.ext, addrp->object.def); } static inline bool sieve_opr_address_part_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { return sieve_opr_object_dump(denv, &sieve_address_part_operand_class, address, NULL); } static inline int sieve_opr_address_part_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_address_part *addrp) { if (!sieve_opr_object_read(renv, &sieve_address_part_operand_class, address, &addrp->object)) return SIEVE_EXEC_BIN_CORRUPT; addrp->def = (const struct sieve_address_part_def *)addrp->object.def; return SIEVE_EXEC_OK; } /* * Address-part string list */ struct sieve_stringlist * sieve_address_part_stringlist_create(const struct sieve_runtime_env *renv, const struct sieve_address_part *addrp, struct sieve_address_list *addresses); /* * Match utility */ enum sieve_addrmatch_opt_operand { SIEVE_AM_OPT_ADDRESS_PART = SIEVE_MATCH_OPT_LAST, SIEVE_AM_OPT_LAST }; int sieve_addrmatch_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code); int sieve_addrmatch_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code, int *exec_status, struct sieve_address_part *addrp, struct sieve_match_type *mtch, struct sieve_comparator *cmp); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-validator.c0000644000175100001700000013003715100335616024713 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "array.h" #include "buffer.h" #include "mempool.h" #include "hash.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-script.h" #include "sieve-ast.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-comparators.h" #include "sieve-address-parts.h" /* * Forward declarations */ static void sieve_validator_register_core_commands(struct sieve_validator *valdtr); static void sieve_validator_register_core_tests(struct sieve_validator *valdtr); /* * Types */ /* Tag registration */ struct sieve_tag_registration { const struct sieve_argument_def *tag_def; const struct sieve_extension *ext; const char *identifier; int id_code; }; /* Command registration */ struct sieve_command_registration { const struct sieve_command_def *cmd_def; const struct sieve_extension *ext; ARRAY(struct sieve_tag_registration *) normal_tags; ARRAY(struct sieve_tag_registration *) instanced_tags; ARRAY(struct sieve_tag_registration *) persistent_tags; }; /* Default (literal) arguments */ struct sieve_default_argument { const struct sieve_argument_def *arg_def; const struct sieve_extension *ext; struct sieve_default_argument *overrides; }; /* * Validator extension */ struct sieve_validator_extension_reg { const struct sieve_validator_extension *valext; const struct sieve_extension *ext; struct sieve_ast_argument *arg; void *context; bool loaded:1; bool required:1; }; /* * Validator */ struct sieve_validator { pool_t pool; struct sieve_instance *svinst; struct sieve_ast *ast; struct sieve_script *script; enum sieve_compile_flags flags; struct sieve_error_handler *ehandler; bool finished_require; /* Registries */ HASH_TABLE(const char *, struct sieve_command_registration *) commands; ARRAY(struct sieve_validator_extension_reg) extensions; /* This is currently a wee bit ugly and needs more thought */ struct sieve_default_argument default_arguments[SAT_COUNT]; /* Default argument processing state (FIXME: ugly) */ struct sieve_default_argument *current_defarg; enum sieve_argument_type current_defarg_type; bool current_defarg_constant; }; /* * Validator object */ struct sieve_validator * sieve_validator_create(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags) { pool_t pool; struct sieve_validator *valdtr; const struct sieve_extension *const *ext_preloaded; unsigned int i, ext_count; pool = pool_alloconly_create("sieve_validator", 16384); valdtr = p_new(pool, struct sieve_validator, 1); valdtr->pool = pool; valdtr->ehandler = ehandler; sieve_error_handler_ref(ehandler); valdtr->ast = ast; sieve_ast_ref(ast); valdtr->script = sieve_ast_script(ast); valdtr->svinst = sieve_script_svinst(valdtr->script); valdtr->flags = flags; /* Setup default arguments */ valdtr->default_arguments[SAT_NUMBER].arg_def = &number_argument; valdtr->default_arguments[SAT_NUMBER].ext = NULL; valdtr->default_arguments[SAT_VAR_STRING].arg_def = &string_argument; valdtr->default_arguments[SAT_VAR_STRING].ext = NULL; valdtr->default_arguments[SAT_CONST_STRING].arg_def = &string_argument; valdtr->default_arguments[SAT_CONST_STRING].ext = NULL; valdtr->default_arguments[SAT_STRING_LIST].arg_def = &string_list_argument; valdtr->default_arguments[SAT_STRING_LIST].ext = NULL; /* Setup storage for extension contexts */ p_array_init(&valdtr->extensions, pool, sieve_extensions_get_count(valdtr->svinst)); /* Setup command registry */ hash_table_create(&valdtr->commands, pool, 0, strcase_hash, strcasecmp); sieve_validator_register_core_commands(valdtr); sieve_validator_register_core_tests(valdtr); /* Pre-load core language features implemented as 'extensions' */ ext_preloaded = sieve_extensions_get_preloaded(valdtr->svinst, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_extension_def *ext_def = ext_preloaded[i]->def; if (ext_def != NULL && ext_def->validator_load != NULL) (void)ext_def->validator_load(ext_preloaded[i], valdtr); } return valdtr; } void sieve_validator_free(struct sieve_validator **valdtr) { const struct sieve_validator_extension_reg *extrs; unsigned int ext_count, i; hash_table_destroy(&(*valdtr)->commands); sieve_ast_unref(&(*valdtr)->ast); sieve_error_handler_unref(&(*valdtr)->ehandler); /* Signal registered extensions that the validator is being destroyed */ extrs = array_get(&(*valdtr)->extensions, &ext_count); for (i = 0; i < ext_count; i++) { if (extrs[i].valext != NULL && extrs[i].valext->free != NULL) extrs[i].valext->free(extrs[i].ext, *valdtr, extrs[i].context); } pool_unref(&(*valdtr)->pool); *valdtr = NULL; } /* * Accessors */ // FIXME: build validate environment pool_t sieve_validator_pool(struct sieve_validator *valdtr) { return valdtr->pool; } struct sieve_error_handler * sieve_validator_error_handler(struct sieve_validator *valdtr) { return valdtr->ehandler; } struct sieve_ast *sieve_validator_ast(struct sieve_validator *valdtr) { return valdtr->ast; } struct sieve_script *sieve_validator_script(struct sieve_validator *valdtr) { return valdtr->script; } const char *sieve_validator_script_cause(struct sieve_validator *valdtr) { return sieve_script_cause(valdtr->script); } struct sieve_instance *sieve_validator_svinst(struct sieve_validator *valdtr) { return valdtr->svinst; } enum sieve_compile_flags sieve_validator_compile_flags(struct sieve_validator *valdtr) { return valdtr->flags; } /* * Command registry */ /* Dummy command object to mark unknown commands in the registry */ static bool _cmd_unknown_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd ATTR_UNUSED) { i_unreached(); } static const struct sieve_command_def unknown_command = { .identifier = "", .type = SCT_NONE, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = _cmd_unknown_validate }; /* Registration of the core commands of the language */ static void sieve_validator_register_core_tests(struct sieve_validator *valdtr) { unsigned int i; for (i = 0; i < sieve_core_tests_count; i++) { sieve_validator_register_command(valdtr, NULL, sieve_core_tests[i]); } } static void sieve_validator_register_core_commands(struct sieve_validator *valdtr) { unsigned int i; for (i = 0; i < sieve_core_commands_count; i++) { sieve_validator_register_command(valdtr, NULL, sieve_core_commands[i]); } } /* Registry functions */ static struct sieve_command_registration * sieve_validator_find_command_registration(struct sieve_validator *valdtr, const char *command) { return hash_table_lookup(valdtr->commands, command); } static struct sieve_command_registration * _sieve_validator_register_command(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_command_def *cmd_def, const char *identifier) { struct sieve_command_registration *cmd_reg = p_new(valdtr->pool, struct sieve_command_registration, 1); cmd_reg->cmd_def = cmd_def; cmd_reg->ext = ext; hash_table_insert(valdtr->commands, identifier, cmd_reg); return cmd_reg; } void sieve_validator_register_command(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_command_def *cmd_def) { struct sieve_command_registration *cmd_reg = sieve_validator_find_command_registration( valdtr, cmd_def->identifier); if (cmd_reg == NULL) { cmd_reg = _sieve_validator_register_command( valdtr, ext, cmd_def, cmd_def->identifier); } else { cmd_reg->cmd_def = cmd_def; cmd_reg->ext = ext; } if (cmd_def->registered != NULL) cmd_def->registered(valdtr, ext, cmd_reg); } static void sieve_validator_register_unknown_command(struct sieve_validator *valdtr, const char *command) { struct sieve_command_registration *cmd_reg = sieve_validator_find_command_registration(valdtr, command); if (cmd_reg == NULL) { (void)_sieve_validator_register_command( valdtr, NULL, &unknown_command, command); } else { i_assert(cmd_reg->cmd_def == NULL); cmd_reg->cmd_def = &unknown_command; } } /*const struct sieve_command *sieve_validator_find_command (struct sieve_validator *valdtr, const char *command) { struct sieve_command_registration *cmd_reg = sieve_validator_find_command_registration(valdtr, command); return ( record == NULL ? NULL : record->command ); }*/ /* * Per-command tagged argument registry */ /* Dummy argument object to mark unknown arguments in the registry */ static bool _unknown_tag_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg ATTR_UNUSED, struct sieve_command *tst ATTR_UNUSED) { i_unreached(); } static const struct sieve_argument_def _unknown_tag = { .identifier = "", .validate = _unknown_tag_validate, }; static inline bool _tag_registration_is_unknown(struct sieve_tag_registration *tag_reg) { return (tag_reg != NULL && tag_reg->tag_def == &_unknown_tag); } /* Registry functions */ static void _sieve_validator_register_tag(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, const char *identifier, int id_code) { struct sieve_tag_registration *reg; reg = p_new(valdtr->pool, struct sieve_tag_registration, 1); reg->ext = ext; reg->tag_def = tag_def; reg->id_code = id_code; if (identifier == NULL) reg->identifier = tag_def->identifier; else reg->identifier = p_strdup(valdtr->pool, identifier); if (!array_is_created(&cmd_reg->normal_tags)) p_array_init(&cmd_reg->normal_tags, valdtr->pool, 4); array_append(&cmd_reg->normal_tags, ®, 1); } void sieve_validator_register_persistent_tag( struct sieve_validator *valdtr, const char *command, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def) { /* Add the tag to the persistent tags list if necessary */ if (tag_def->validate_persistent != NULL) { struct sieve_command_registration *cmd_reg = sieve_validator_find_command_registration( valdtr, command); if (cmd_reg == NULL) { cmd_reg = _sieve_validator_register_command( valdtr, NULL, NULL, command); } struct sieve_tag_registration *reg; if (!array_is_created(&cmd_reg->persistent_tags)) { p_array_init(&cmd_reg->persistent_tags, valdtr->pool, 4); } else { struct sieve_tag_registration *reg_idx; /* Avoid dupplicate registration */ array_foreach_elem(&cmd_reg->persistent_tags, reg_idx) { if (reg_idx->tag_def == tag_def) return; } } reg = p_new(valdtr->pool, struct sieve_tag_registration, 1); reg->ext = ext; reg->tag_def = tag_def; reg->id_code = -1; array_append(&cmd_reg->persistent_tags, ®, 1); } } void sieve_validator_register_external_tag( struct sieve_validator *valdtr, const char *command, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, int id_code) { struct sieve_command_registration *cmd_reg = sieve_validator_find_command_registration(valdtr, command); if (cmd_reg == NULL) { cmd_reg = _sieve_validator_register_command( valdtr, NULL, NULL, command); } _sieve_validator_register_tag(valdtr, cmd_reg, ext, tag_def, NULL, id_code); } void sieve_validator_register_tag( struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, int id_code) { if (tag_def->is_instance_of == NULL) { _sieve_validator_register_tag(valdtr, cmd_reg, ext, tag_def, NULL, id_code); } else { struct sieve_tag_registration *reg = p_new(valdtr->pool, struct sieve_tag_registration, 1); reg->ext = ext; reg->tag_def = tag_def; reg->id_code = id_code; if (!array_is_created(&cmd_reg->instanced_tags)) p_array_init(&cmd_reg->instanced_tags, valdtr->pool, 4); array_append(&cmd_reg->instanced_tags, ®, 1); } } static void sieve_validator_register_unknown_tag(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, const char *tag) { _sieve_validator_register_tag(valdtr, cmd_reg, NULL, &_unknown_tag, tag, 0); } static struct sieve_tag_registration * _sieve_validator_command_tag_get(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *tag, void **data) { struct sieve_command_registration *cmd_reg = cmd->reg; struct sieve_tag_registration *const *regs; unsigned int i, reg_count; /* First check normal tags */ if (array_is_created(&cmd_reg->normal_tags)) { regs = array_get(&cmd_reg->normal_tags, ®_count); for (i = 0; i < reg_count; i++) { if (regs[i]->tag_def != NULL && strcasecmp(regs[i]->identifier, tag) == 0) { return regs[i]; } } } /* Not found so far, try the instanced tags */ if (array_is_created(&cmd_reg->instanced_tags)) { regs = array_get(&cmd_reg->instanced_tags, ®_count); for (i = 0; i < reg_count; i++) { if (regs[i]->tag_def != NULL) { if (regs[i]->tag_def->is_instance_of( valdtr, cmd, regs[i]->ext, tag, data)) return regs[i]; } } } return NULL; } static bool sieve_validator_command_tag_exists(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *tag) { return (_sieve_validator_command_tag_get(valdtr, cmd, tag, NULL) != NULL); } static struct sieve_tag_registration * sieve_validator_command_tag_get(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, void **data) { const char *tag = sieve_ast_argument_tag(arg); return _sieve_validator_command_tag_get(valdtr, cmd, tag, data); } /* * Extension support */ static bool sieve_validator_extensions_check_conficts(struct sieve_validator *valdtr, struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext) { struct sieve_validator_extension_reg *ext_reg; struct sieve_validator_extension_reg *regs; unsigned int count, i; if (ext->id < 0) return TRUE; ext_reg = array_idx_get_space(&valdtr->extensions, (unsigned int) ext->id); regs = array_get_modifiable(&valdtr->extensions, &count); for (i = 0; i < count; i++) { bool required = ext_reg->required && regs[i].required; if (regs[i].ext == NULL) continue; if (regs[i].ext == ext) continue; if (!regs[i].loaded) continue; /* Check this extension vs other extension */ if (ext_reg->valext != NULL && ext_reg->valext->check_conflict != NULL) { struct sieve_ast_argument *this_ext_arg = (ext_arg == NULL ? regs[i].arg : ext_arg); if (!ext_reg->valext->check_conflict( ext, valdtr, ext_reg->context, this_ext_arg, regs[i].ext, required)) return FALSE; } /* Check other extension vs this extension */ if (regs[i].valext != NULL && regs[i].valext->check_conflict != NULL) { if (!regs[i].valext->check_conflict( regs[i].ext, valdtr, regs[i].context, regs[i].arg, ext, required)) return FALSE; } } return TRUE; } bool sieve_validator_extension_load(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext, bool required) { const struct sieve_extension_def *extdef = ext->def; struct sieve_validator_extension_reg *reg = NULL; if (ext->global && (valdtr->flags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0) { const char *cmd_prefix = (cmd == NULL ? "" : t_strdup_printf("%s %s: ", sieve_command_identifier(cmd), sieve_command_type_name(cmd))); sieve_argument_validate_error( valdtr, ext_arg, "%sfailed to load Sieve capability '%s': " "its use is restricted to global scripts", cmd_prefix, sieve_extension_name(ext)); return FALSE; } /* Register extension no matter what and store the * AST argument registering it */ if (ext->id >= 0) { reg = array_idx_get_space(&valdtr->extensions, (unsigned int)ext->id); i_assert(reg->ext == NULL || reg->ext == ext); reg->ext = ext; reg->required = reg->required || required; if (reg->arg == NULL) reg->arg = ext_arg; } if (extdef->validator_load != NULL && !extdef->validator_load(ext, valdtr)) { const char *cmd_prefix = (cmd == NULL ? "" : t_strdup_printf("%s %s: ", sieve_command_identifier(cmd), sieve_command_type_name(cmd))); sieve_argument_validate_error( valdtr, ext_arg, "%sfailed to load Sieve capability '%s'", cmd_prefix, sieve_extension_name(ext)); return FALSE; } /* Check conflicts with other extensions */ if (!sieve_validator_extensions_check_conficts(valdtr, ext_arg, ext)) return FALSE; /* Link extension to AST for use at code generation */ if (reg != NULL) { sieve_ast_extension_link(valdtr->ast, ext, reg->required); reg->loaded = TRUE; } return TRUE; } const struct sieve_extension * sieve_validator_extension_load_by_name(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, const char *ext_name) { const struct sieve_extension *ext; ext = sieve_extension_get_by_name(valdtr->svinst, ext_name); if (ext == NULL || ext->def == NULL || !ext->enabled) { unsigned int i; bool core_test = FALSE; bool core_command = FALSE; for (i = 0; !core_command && i < sieve_core_commands_count; i++) { if (strcasecmp(sieve_core_commands[i]->identifier, ext_name) == 0) core_command = TRUE; } for (i = 0; !core_test && i < sieve_core_tests_count; i++) { if (strcasecmp(sieve_core_tests[i]->identifier, ext_name) == 0) core_test = TRUE; } if (core_test || core_command) { sieve_argument_validate_error( valdtr, ext_arg, "%s %s: '%s' is not known as a Sieve capability, " "but it is known as a Sieve %s that is always available", sieve_command_identifier(cmd), sieve_command_type_name(cmd), str_sanitize(ext_name, 128), (core_test ? "test" : "command")); } else { sieve_argument_validate_error( valdtr, ext_arg, "%s %s: unknown Sieve capability '%s'", sieve_command_identifier(cmd), sieve_command_type_name(cmd), str_sanitize(ext_name, 128)); } return NULL; } if (!sieve_validator_extension_load(valdtr, cmd, ext_arg, ext, TRUE)) return NULL; return ext; } const struct sieve_extension * sieve_validator_extension_load_implicit(struct sieve_validator *valdtr, const char *ext_name) { const struct sieve_extension *ext; ext = sieve_extension_get_by_name(valdtr->svinst, ext_name); if (ext == NULL || ext->def == NULL) return NULL; if (!sieve_validator_extension_load(valdtr, NULL, NULL, ext, TRUE)) return NULL; return ext; } void sieve_validator_extension_register( struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_validator_extension *valext, void *context) { struct sieve_validator_extension_reg *reg; if (ext->id < 0) return; reg = array_idx_get_space(&valdtr->extensions, (unsigned int) ext->id); i_assert(reg->ext == NULL || reg->ext == ext); reg->ext = ext; reg->valext = valext; reg->context = context; } bool sieve_validator_extension_loaded(struct sieve_validator *valdtr, const struct sieve_extension *ext) { const struct sieve_validator_extension_reg *reg; if (ext->id < 0 || ext->id >= (int) array_count(&valdtr->extensions)) return FALSE; reg = array_idx(&valdtr->extensions, (unsigned int) ext->id); return (reg->loaded); } void sieve_validator_extension_set_context(struct sieve_validator *valdtr, const struct sieve_extension *ext, void *context) { struct sieve_validator_extension_reg *reg; if (ext->id < 0) return; reg = array_idx_get_space(&valdtr->extensions, (unsigned int) ext->id); reg->context = context; } void *sieve_validator_extension_get_context(struct sieve_validator *valdtr, const struct sieve_extension *ext) { const struct sieve_validator_extension_reg *reg; if (ext->id < 0 || ext->id >= (int) array_count(&valdtr->extensions)) return NULL; reg = array_idx(&valdtr->extensions, (unsigned int) ext->id); return reg->context; } /* * Overriding the default literal arguments */ void sieve_validator_argument_override(struct sieve_validator *valdtr, enum sieve_argument_type type, const struct sieve_extension *ext, const struct sieve_argument_def *arg_def) { struct sieve_default_argument *arg; if (valdtr->default_arguments[type].arg_def != NULL) { arg = p_new(valdtr->pool, struct sieve_default_argument, 1); *arg = valdtr->default_arguments[type]; valdtr->default_arguments[type].overrides = arg; } valdtr->default_arguments[type].arg_def = arg_def; valdtr->default_arguments[type].ext = ext; } static bool sieve_validator_argument_default_activate(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_default_argument *defarg, struct sieve_ast_argument *arg) { bool result = TRUE; struct sieve_default_argument *prev_defarg; prev_defarg = valdtr->current_defarg; valdtr->current_defarg = defarg; if (arg->argument == NULL) { arg->argument = sieve_argument_create(arg->ast, defarg->arg_def, defarg->ext, 0); } else { arg->argument->def = defarg->arg_def; arg->argument->ext = defarg->ext; } if (defarg->arg_def != NULL && defarg->arg_def->validate != NULL) result = defarg->arg_def->validate(valdtr, &arg, cmd); valdtr->current_defarg = prev_defarg; return result; } bool sieve_validator_argument_activate_super(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant ATTR_UNUSED) { struct sieve_default_argument *defarg; if (valdtr->current_defarg == NULL || valdtr->current_defarg->overrides == NULL) return FALSE; if (valdtr->current_defarg->overrides->arg_def == &string_argument) { switch (valdtr->current_defarg_type) { case SAT_CONST_STRING: if (!valdtr->current_defarg_constant) { valdtr->current_defarg_type = SAT_VAR_STRING; defarg = &valdtr->default_arguments[SAT_VAR_STRING]; } else { defarg = valdtr->current_defarg->overrides; } break; case SAT_VAR_STRING: defarg = valdtr->current_defarg->overrides; break; default: return FALSE; } } else { defarg = valdtr->current_defarg->overrides; } return sieve_validator_argument_default_activate(valdtr, cmd, defarg, arg); } /* * Argument Validation API */ bool sieve_validator_argument_activate(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant) { struct sieve_default_argument *defarg; switch (sieve_ast_argument_type(arg)) { case SAAT_NUMBER: valdtr->current_defarg_type = SAT_NUMBER; break; case SAAT_STRING: valdtr->current_defarg_type = SAT_CONST_STRING; break; case SAAT_STRING_LIST: valdtr->current_defarg_type = SAT_STRING_LIST; break; default: return FALSE; } valdtr->current_defarg_constant = constant; defarg = &valdtr->default_arguments[valdtr->current_defarg_type]; if (!constant && defarg->arg_def == &string_argument) { valdtr->current_defarg_type = SAT_VAR_STRING; defarg = &valdtr->default_arguments[SAT_VAR_STRING]; } return sieve_validator_argument_default_activate(valdtr, cmd, defarg, arg); } bool sieve_validate_positional_argument(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos, enum sieve_ast_argument_type req_type) { i_assert(arg != NULL); if (sieve_ast_argument_type(arg) != req_type && (sieve_ast_argument_type(arg) != SAAT_STRING || req_type != SAAT_STRING_LIST)) { sieve_argument_validate_error( valdtr, arg, "the %s %s expects %s as argument %d (%s), " "but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_type_name(req_type), arg_pos, arg_name, sieve_ast_argument_name(arg)); return FALSE; } return TRUE; } bool sieve_validate_tag_parameter(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *tag, struct sieve_ast_argument *param, const char *arg_name, unsigned int arg_pos, enum sieve_ast_argument_type req_type, bool constant) { i_assert(tag != NULL); if (param == NULL) { const char *position = (arg_pos == 0 ? "" : t_strdup_printf(" %d (%s)", arg_pos, arg_name)); sieve_argument_validate_error( valdtr, tag, "the :%s tag for the %s %s requires %s as parameter%s, " "but no parameters were found", sieve_ast_argument_tag(tag), sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_type_name(req_type), position); return FALSE; } if (sieve_ast_argument_type(param) != req_type && (sieve_ast_argument_type(param) != SAAT_STRING || req_type != SAAT_STRING_LIST)) { const char *position = (arg_pos == 0 ? "" : t_strdup_printf(" %d (%s)", arg_pos, arg_name)); sieve_argument_validate_error( valdtr, param, "the :%s tag for the %s %s requires %s as parameter%s, " "but %s was found", sieve_ast_argument_tag(tag), sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_type_name(req_type), position, sieve_ast_argument_name(param)); return FALSE; } if (!sieve_validator_argument_activate(valdtr, cmd, param, constant)) return FALSE; param->argument->id_code = tag->argument->id_code; return TRUE; } /* * Command argument validation */ static bool sieve_validate_command_arguments(struct sieve_validator *valdtr, struct sieve_command *cmd) { int arg_count = cmd->def->positional_args; int real_count = 0; struct sieve_ast_argument *arg; struct sieve_command_registration *cmd_reg = cmd->reg; /* Resolve tagged arguments */ arg = sieve_ast_argument_first(cmd->ast_node); while (arg != NULL) { void *arg_data = NULL; struct sieve_tag_registration *tag_reg; const struct sieve_argument_def *tag_def; if (sieve_ast_argument_type(arg) != SAAT_TAG) { arg = sieve_ast_argument_next(arg); continue; } tag_reg = sieve_validator_command_tag_get(valdtr, cmd, arg, &arg_data); if (tag_reg == NULL) { sieve_argument_validate_error( valdtr, arg, "unknown tagged argument ':%s' for the %s %s " "(reported only once at first occurrence)", sieve_ast_argument_tag(arg), sieve_command_identifier(cmd), sieve_command_type_name(cmd)); sieve_validator_register_unknown_tag( valdtr, cmd_reg, sieve_ast_argument_tag(arg)); return FALSE; } /* Check whether previously tagged as unknown */ if (_tag_registration_is_unknown(tag_reg)) return FALSE; tag_def = tag_reg->tag_def; /* Assign the tagged argument type to the ast for later reference */ arg->argument = sieve_argument_create( arg->ast, tag_def, tag_reg->ext, tag_reg->id_code); arg->argument->data = arg_data; arg = sieve_ast_argument_next(arg); } /* Validate tagged arguments */ arg = sieve_ast_argument_first(cmd->ast_node); while (arg != NULL && sieve_ast_argument_type(arg) == SAAT_TAG) { const struct sieve_argument_def *tag_def = arg->argument->def; struct sieve_ast_argument *parg; /* Scan backwards for any duplicates */ if ((tag_def->flags & SIEVE_ARGUMENT_FLAG_MULTIPLE) == 0) { parg = sieve_ast_argument_prev(arg); while (parg != NULL) { if ((sieve_ast_argument_type(parg) == SAAT_TAG && parg->argument->def == tag_def) || (arg->argument->id_code > 0 && parg->argument != NULL && parg->argument->id_code == arg->argument->id_code)) { const char *tag_id = sieve_ast_argument_tag(arg); const char *tag_desc = strcmp(tag_def->identifier, tag_id) != 0 ? t_strdup_printf("%s argument (:%s)", tag_def->identifier, tag_id) : t_strdup_printf(":%s argument", tag_def->identifier); sieve_argument_validate_error( valdtr, arg, "encountered duplicate %s for the %s %s", tag_desc, sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } parg = sieve_ast_argument_prev(parg); } } /* Call the validation function for the tag (if present) Fail if the validation fails: Let's not whine multiple times about a single command having multiple bad arguments... */ if (tag_def->validate != NULL) { if (!tag_def->validate(valdtr, &arg, cmd)) return FALSE; } else { arg = sieve_ast_argument_next(arg); } } /* Remaining arguments should be positional (tags are not allowed here) */ cmd->first_positional = arg; while (arg != NULL) { if (sieve_ast_argument_type(arg) == SAAT_TAG) { sieve_argument_validate_error( valdtr, arg, "encountered an unexpected tagged argument ':%s' " "while validating positional arguments for the %s %s", sieve_ast_argument_tag(arg), sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } real_count++; arg = sieve_ast_argument_next(arg); } /* Check the required count versus the real number of arguments */ if (arg_count >= 0 && real_count != arg_count) { sieve_command_validate_error( valdtr, cmd, "the %s %s requires %d positional argument(s), " "but %d is/are specified", sieve_command_identifier(cmd), sieve_command_type_name(cmd), arg_count, real_count); return FALSE; } /* Call initial validation for persistent arguments */ if (array_is_created(&cmd_reg->persistent_tags)) { struct sieve_tag_registration *const *regs; unsigned int i, reg_count; regs = array_get(&cmd_reg->persistent_tags, ®_count); for (i = 0; i < reg_count; i++) { const struct sieve_argument_def *tag_def = regs[i]->tag_def; if (tag_def != NULL && tag_def->validate_persistent != NULL) { /* To be sure */ if (!tag_def->validate_persistent( valdtr, cmd, regs[i]->ext)) return FALSE; } } } return TRUE; } static bool sieve_validate_arguments_context(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = sieve_command_first_argument(cmd); while (arg != NULL) { const struct sieve_argument *argument = arg->argument; if (argument != NULL && argument->def != NULL && argument->def->validate_context != NULL) { if (!argument->def->validate_context(valdtr, arg, cmd)) return FALSE; } arg = sieve_ast_argument_next(arg); } return TRUE; } /* * Command Validation API */ static bool sieve_validate_command_subtests(struct sieve_validator *valdtr, struct sieve_command *cmd, const unsigned int count) { switch (count) { case 0: if (sieve_ast_test_count(cmd->ast_node) > 0) { /* Unexpected command specified */ enum sieve_command_type ctype = SCT_NONE; struct sieve_command_registration *cmd_reg; struct sieve_ast_node *test = sieve_ast_test_first(cmd->ast_node); cmd_reg = sieve_validator_find_command_registration( valdtr, test->identifier); /* First check what we are dealing with */ if (cmd_reg != NULL && cmd_reg->cmd_def != NULL) ctype = cmd_reg->cmd_def->type; switch (ctype) { case SCT_TEST: /* Spurious test */ case SCT_HYBRID: sieve_command_validate_error( valdtr, cmd, "the %s %s accepts no sub-tests, " "but tests are specified", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); break; case SCT_NONE: /* Unknown command */ /* Is it perhaps a tag for which the ':' was omitted ? */ if (sieve_validator_command_tag_exists( valdtr, cmd, test->identifier)) { sieve_command_validate_error( valdtr, cmd, "missing colon ':' before ':%s' tag in %s %s", test->identifier, sieve_command_identifier(cmd), sieve_command_type_name(cmd)); break; } /* Fall through */ case SCT_COMMAND: sieve_command_validate_error( valdtr, cmd, "missing semicolon ';' after %s %s", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); break; } return FALSE; } break; case 1: if (sieve_ast_test_count(cmd->ast_node) == 0) { sieve_command_validate_error( valdtr, cmd, "the %s %s requires one sub-test, " "but none is specified", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } else if (sieve_ast_test_count(cmd->ast_node) > 1 || cmd->ast_node->test_list) { sieve_command_validate_error( valdtr, cmd, "the %s %s requires one sub-test, " "but a list of tests is specified", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } break; default: if (sieve_ast_test_count(cmd->ast_node) == 0) { sieve_command_validate_error( valdtr, cmd, "the %s %s requires a list of sub-tests, " "but none is specified", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } else if (sieve_ast_test_count(cmd->ast_node) == 1 && !cmd->ast_node->test_list) { sieve_command_validate_error( valdtr, cmd, "the %s %s requires a list of sub-tests, " "but a single test is specified", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } break; } return TRUE; } static bool sieve_validate_command_block(struct sieve_validator *valdtr, struct sieve_command *cmd, bool block_allowed, bool block_required) { i_assert(cmd->ast_node->type == SAT_COMMAND); if (block_required) { if (!cmd->ast_node->block) { sieve_command_validate_error( valdtr, cmd, "the %s command requires a command block, " "but it is missing", sieve_command_identifier(cmd)); return FALSE; } } else if (!block_allowed && cmd->ast_node->block) { sieve_command_validate_error( valdtr, cmd, "the %s command does not accept a command block, " "but one is specified anyway", sieve_command_identifier(cmd)); return FALSE; } return TRUE; } /* * AST Validation */ static bool sieve_validate_test_list(struct sieve_validator *valdtr, struct sieve_ast_node *test_list, int *const_r); static bool sieve_validate_block(struct sieve_validator *valdtr, struct sieve_ast_node *block); static bool sieve_validate_command(struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node, int *const_r); static bool sieve_validate_command_context(struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node) { enum sieve_ast_type ast_type = sieve_ast_node_type(cmd_node); struct sieve_command_registration *cmd_reg; i_assert(ast_type == SAT_TEST || ast_type == SAT_COMMAND); /* Verify the command specified by this node */ cmd_reg = sieve_validator_find_command_registration( valdtr, cmd_node->identifier); if (cmd_reg != NULL && cmd_reg->cmd_def != NULL) { const struct sieve_command_def *cmd_def = cmd_reg->cmd_def; /* Identifier = "" when the command was previously marked as unknown */ if (*(cmd_def->identifier) != '\0') { if ((cmd_def->type == SCT_COMMAND && ast_type == SAT_TEST) || (cmd_def->type == SCT_TEST && ast_type == SAT_COMMAND)) { sieve_validator_error( valdtr, cmd_node->source_line, "attempted to use %s '%s' as %s", sieve_command_def_type_name(cmd_def), cmd_node->identifier, sieve_ast_type_name(ast_type)); return FALSE; } cmd_node->command = sieve_command_create( cmd_node, cmd_reg->ext, cmd_def, cmd_reg); } else { return FALSE; } } else { sieve_validator_error( valdtr, cmd_node->source_line, "unknown %s '%s' (only reported once at first occurrence)", sieve_ast_type_name(ast_type), cmd_node->identifier); sieve_validator_register_unknown_command( valdtr, cmd_node->identifier); return FALSE; } return TRUE; } static bool sieve_validate_command(struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node, int *const_r) { enum sieve_ast_type ast_type = sieve_ast_node_type(cmd_node); struct sieve_command *cmd = (cmd_node == NULL ? NULL : cmd_node->command); const struct sieve_command_def *cmd_def = (cmd != NULL ? cmd->def : NULL); bool result = TRUE; i_assert(ast_type == SAT_TEST || ast_type == SAT_COMMAND); if (cmd_def != NULL && *(cmd_def->identifier) != '\0') { if (cmd_def->pre_validate == NULL || cmd_def->pre_validate(valdtr, cmd)) { /* Check argument syntax */ if (!sieve_validate_command_arguments(valdtr, cmd)) { result = FALSE; /* A missing ':' causes a tag to become a test. This can be the cause of the arguments validation failing. Therefore we must produce an error for the sub-tests as well if appropriate. */ (void)sieve_validate_command_subtests( valdtr, cmd, cmd_def->subtests); } else if (!sieve_validate_command_subtests( valdtr, cmd, cmd_def->subtests) || (ast_type == SAT_COMMAND && !sieve_validate_command_block( valdtr, cmd, cmd_def->block_allowed, cmd_def->block_required))) { result = FALSE; } else { /* Call command validation function if specified */ if (cmd_def->validate != NULL) { result = cmd_def->validate(valdtr, cmd) && result; } } } else { /* If pre-validation fails, don't bother to validate further as context might be missing and doing so is not very useful for further error reporting anyway */ return FALSE; } result = result && sieve_validate_arguments_context(valdtr, cmd); } /* * Descend further into the AST */ if (cmd_def != NULL) { /* Tests */ if (cmd_def->subtests > 0) { if (result || sieve_errors_more_allowed(valdtr->ehandler)) { result = sieve_validate_test_list( valdtr, cmd_node, const_r) && result; } } else if (result) { if (cmd_def->validate_const != NULL) { (void)cmd_def->validate_const( valdtr, cmd, const_r, -1); } else { *const_r = -1; } } /* Skip block if result of test is const FALSE */ if (result && *const_r == 0) return TRUE; /* Command block */ if (cmd_def->block_allowed && ast_type == SAT_COMMAND && (result || sieve_errors_more_allowed(valdtr->ehandler))) { result = sieve_validate_block(valdtr, cmd_node) && result; } } return result; } static bool sieve_validate_test_list(struct sieve_validator *valdtr, struct sieve_ast_node *test_node, int *const_r) { struct sieve_command *tst = test_node->command; const struct sieve_command_def *tst_def = (tst != NULL ? tst->def : NULL); struct sieve_ast_node *test; bool result = TRUE; if (tst_def != NULL && tst_def->validate_const != NULL) { if (!tst_def->validate_const(valdtr, tst, const_r, -2)) return TRUE; } test = sieve_ast_test_first(test_node); while (test != NULL && (result || sieve_errors_more_allowed(valdtr->ehandler))) { int const_value = -2; result = sieve_validate_command_context(valdtr, test) && sieve_validate_command(valdtr, test, &const_value) && result; if (result) { if (tst_def != NULL && tst_def->validate_const != NULL) { if (!tst_def->validate_const( valdtr, tst, const_r, const_value)) return TRUE; } else { *const_r = -1; } } if (result && const_value >= 0) test = sieve_ast_node_detach(test); else test = sieve_ast_test_next(test); } return result; } static bool sieve_validate_block(struct sieve_validator *valdtr, struct sieve_ast_node *block) { bool result = TRUE, fatal = FALSE; struct sieve_ast_node *cmd_node, *next; T_BEGIN { cmd_node = sieve_ast_command_first(block); while (!fatal && cmd_node != NULL && (result || sieve_errors_more_allowed(valdtr->ehandler))) { bool command_success; int const_value = -2; next = sieve_ast_command_next(cmd_node); /* Check if this is the first non-require command */ if (sieve_ast_node_type(block) == SAT_ROOT && !valdtr->finished_require && strcasecmp(cmd_node->identifier, cmd_require.identifier) != 0) { const struct sieve_validator_extension_reg *extrs; const struct sieve_extension *const *exts; unsigned int ext_count, i; valdtr->finished_require = TRUE; /* Load implicit extensions */ exts = sieve_extensions_get_all(valdtr->svinst, &ext_count); for (i = 0; i < ext_count; i++) { if (exts[i]->implicit) { (void)sieve_validator_extension_load( valdtr, NULL, NULL, exts[i], TRUE); } } /* Validate all 'require'd extensions */ extrs = array_get(&valdtr->extensions, &ext_count); for (i = 0; i < ext_count; i++) { if (extrs[i].loaded && extrs[i].valext != NULL && extrs[i].valext->validate != NULL) { if (!extrs[i].valext->validate( extrs[i].ext, valdtr, extrs[i].context, extrs[i].arg, extrs[i].required)) { fatal = TRUE; break; } } } } command_success = sieve_validate_command_context(valdtr, cmd_node); result = command_success && result; result = !fatal && sieve_validate_command(valdtr, cmd_node, &const_value) && result; cmd_node = next; } } T_END; return result && !fatal; } bool sieve_validator_run(struct sieve_validator *valdtr) { return sieve_validate_block(valdtr, sieve_ast_root(valdtr->ast)); } /* * Validator object registry */ struct sieve_validator_object_reg { const struct sieve_object_def *obj_def; const struct sieve_extension *ext; }; struct sieve_validator_object_registry { struct sieve_validator *valdtr; ARRAY(struct sieve_validator_object_reg) registrations; }; struct sieve_validator_object_registry * sieve_validator_object_registry_get(struct sieve_validator *valdtr, const struct sieve_extension *ext) { return (struct sieve_validator_object_registry *) sieve_validator_extension_get_context(valdtr, ext); } void sieve_validator_object_registry_add( struct sieve_validator_object_registry *regs, const struct sieve_extension *ext, const struct sieve_object_def *obj_def) { struct sieve_validator_object_reg *reg; reg = array_append_space(®s->registrations); reg->ext = ext; reg->obj_def = obj_def; } bool sieve_validator_object_registry_find( struct sieve_validator_object_registry *regs, const char *identifier, struct sieve_object *obj) { unsigned int i; for (i = 0; i < array_count(®s->registrations); i++) { const struct sieve_validator_object_reg *reg = array_idx(®s->registrations, i); if (strcasecmp(reg->obj_def->identifier, identifier) == 0) { if (obj != NULL) { obj->def = reg->obj_def; obj->ext = reg->ext; } return TRUE; } } return FALSE; } struct sieve_validator_object_registry * sieve_validator_object_registry_create(struct sieve_validator *valdtr) { pool_t pool = valdtr->pool; struct sieve_validator_object_registry *regs = p_new(pool, struct sieve_validator_object_registry, 1); /* Setup registry */ p_array_init(®s->registrations, valdtr->pool, 4); regs->valdtr = valdtr; return regs; } struct sieve_validator_object_registry * sieve_validator_object_registry_init(struct sieve_validator *valdtr, const struct sieve_extension *ext) { struct sieve_validator_object_registry *regs = sieve_validator_object_registry_create(valdtr); sieve_validator_extension_set_context(valdtr, ext, regs); return regs; } /* * Error handling */ #undef sieve_validator_error void sieve_validator_error(struct sieve_validator *valdtr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; params.location = sieve_error_script_location(valdtr->script, source_line); va_start(args, fmt); sieve_logv(valdtr->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_validator_warning void sieve_validator_warning(struct sieve_validator *valdtr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; params.location = sieve_error_script_location(valdtr->script, source_line); va_start(args, fmt); sieve_logv(valdtr->ehandler, ¶ms, fmt, args); va_end(args); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-match-types.h0000644000175100001700000001422515100335616025171 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_MATCH_TYPES_H #define SIEVE_MATCH_TYPES_H #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-objects.h" /* * Types */ struct sieve_match_type_context; /* * Core match types */ enum sieve_match_type_code { SIEVE_MATCH_TYPE_IS, SIEVE_MATCH_TYPE_CONTAINS, SIEVE_MATCH_TYPE_MATCHES, SIEVE_MATCH_TYPE_CUSTOM }; extern const struct sieve_match_type_def is_match_type; extern const struct sieve_match_type_def contains_match_type; extern const struct sieve_match_type_def matches_match_type; /* * Match type definition */ struct sieve_match_type_def { struct sieve_object_def obj_def; bool (*validate)(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_match_type_context *ctx); bool (*validate_context)(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); /* * Matching */ /* Custom implementation */ int (*match)(struct sieve_match_context *mctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list); /* Default match loop */ void (*match_init)(struct sieve_match_context *mctx); int (*match_keys)(struct sieve_match_context *mctx, const char *val, size_t val_size, struct sieve_stringlist *key_list); int (*match_key)(struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size); void (*match_deinit)(struct sieve_match_context *mctx); }; /* * Match type instance */ struct sieve_match_type { struct sieve_object object; const struct sieve_match_type_def *def; }; #define SIEVE_MATCH_TYPE_DEFAULT(definition) \ { SIEVE_OBJECT_DEFAULT(definition), &(definition) } #define sieve_match_type_name(mcht) \ ( (mcht)->object.def->identifier ) #define sieve_match_type_is(mcht, definition) \ ( (mcht)->def == &(definition) ) static inline const struct sieve_match_type * sieve_match_type_copy(pool_t pool, const struct sieve_match_type *cmp_orig) { struct sieve_match_type *cmp = p_new(pool, struct sieve_match_type, 1); *cmp = *cmp_orig; return cmp; } /* * Match type context */ struct sieve_match_type_context { struct sieve_command *command; struct sieve_ast_argument *argument; const struct sieve_match_type *match_type; /* Only filled in when match_type->validate_context() is called */ const struct sieve_comparator *comparator; bool comparator_specified; /* Context data could be used in the future to pass data between validator and generator in match types that use extra parameters. Currently not necessary, not even for the relational extension. */ void *ctx_data; }; /* * Match type registration */ void sieve_match_type_register(struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_match_type_def *mcht); /* * Match values */ struct sieve_match_values; bool sieve_match_values_set_enabled(const struct sieve_runtime_env *renv, bool enable); bool sieve_match_values_are_enabled(const struct sieve_runtime_env *renv); struct sieve_match_values * sieve_match_values_start(const struct sieve_runtime_env *renv); void sieve_match_values_set(struct sieve_match_values *mvalues, unsigned int index, string_t *value); void sieve_match_values_add(struct sieve_match_values *mvalues, string_t *value); void sieve_match_values_add_cstr(struct sieve_match_values *mvalues, const char *value); void sieve_match_values_add_char(struct sieve_match_values *mvalues, char c); void sieve_match_values_skip(struct sieve_match_values *mvalues, int num); void sieve_match_values_commit(const struct sieve_runtime_env *renv, struct sieve_match_values **mvalues); void sieve_match_values_abort(struct sieve_match_values **mvalues); void sieve_match_values_get(const struct sieve_runtime_env *renv, unsigned int index, string_t **value_r); /* * Match type tagged argument */ extern const struct sieve_argument_def match_type_tag; static inline bool sieve_argument_is_match_type(struct sieve_ast_argument *arg) { return ( arg->argument->def == &match_type_tag ); } void sieve_match_types_link_tags(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code); /* * Validation */ bool sieve_match_type_validate(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *key_arg, const struct sieve_match_type *mcht_default, const struct sieve_comparator *cmp_default); void sieve_match_type_arguments_remove(struct sieve_validator *valdtr, struct sieve_command *cmd); /* * Match type operand */ extern const struct sieve_operand_def match_type_operand; extern const struct sieve_operand_class sieve_match_type_operand_class; #define SIEVE_EXT_DEFINE_MATCH_TYPE(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_MATCH_TYPES(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) static inline bool sieve_operand_is_match_type(const struct sieve_operand *operand) { return (operand != NULL && operand->def != NULL && operand->def->class == &sieve_match_type_operand_class); } static inline void sieve_opr_match_type_emit(struct sieve_binary_block *sblock, const struct sieve_match_type *mcht) { sieve_opr_object_emit(sblock, mcht->object.ext, mcht->object.def); } static inline bool sieve_opr_match_type_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { return sieve_opr_object_dump(denv, &sieve_match_type_operand_class, address, NULL); } static inline int sieve_opr_match_type_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_match_type *mcht) { if (!sieve_opr_object_read(renv, &sieve_match_type_operand_class, address, &mcht->object)) return SIEVE_EXEC_BIN_CORRUPT; mcht->def = (const struct sieve_match_type_def *)mcht->object.def; return SIEVE_EXEC_OK; } /* Common validation implementation */ bool sieve_match_substring_validate_context( struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-smtp.h0000644000175100001700000000144215100335616023713 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_SMTP_H #define SIEVE_SMTP_H #include "sieve-common.h" bool sieve_smtp_available (const struct sieve_script_env *senv); struct sieve_smtp_context; struct sieve_smtp_context *sieve_smtp_start (const struct sieve_script_env *senv, const struct smtp_address *mail_from); void sieve_smtp_add_rcpt (struct sieve_smtp_context *sctx, const struct smtp_address *rcpt_to); struct ostream *sieve_smtp_send (struct sieve_smtp_context *sctx); struct sieve_smtp_context *sieve_smtp_start_single (const struct sieve_script_env *senv, const struct smtp_address *rcpt_to, const struct smtp_address *mail_from, struct ostream **output_r); void sieve_smtp_abort (struct sieve_smtp_context *sctx); int sieve_smtp_finish (struct sieve_smtp_context *sctx, const char **error_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/Makefile.in0000644000175100001700000014131115100335630023507 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginc_lib_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = 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)$(dovecot_pkglibdir)" \ "$(DESTDIR)$(pkginc_libdir)" LTLIBRARIES = $(dovecot_pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(strgdir)/data/libsieve_storage_data.la \ $(strgdir)/file/libsieve_storage_file.la \ $(strgdir)/dict/libsieve_storage_dict.la \ $(strgdir)/ldap/libsieve_storage_ldap.la $(am__DEPENDENCIES_1) am__DEPENDENCIES_3 = $(extdir)/vacation/libsieve_ext_vacation.la \ $(extdir)/subaddress/libsieve_ext_subaddress.la \ $(extdir)/comparator-i-ascii-numeric/libsieve_ext_comparator-i-ascii-numeric.la \ $(extdir)/relational/libsieve_ext_relational.la \ $(extdir)/regex/libsieve_ext_regex.la \ $(extdir)/copy/libsieve_ext_copy.la \ $(extdir)/imap4flags/libsieve_ext_imap4flags.la \ $(extdir)/include/libsieve_ext_include.la \ $(extdir)/body/libsieve_ext_body.la \ $(extdir)/variables/libsieve_ext_variables.la \ $(extdir)/enotify/libsieve_ext_enotify.la \ $(extdir)/environment/libsieve_ext_environment.la \ $(extdir)/mailbox/libsieve_ext_mailbox.la \ $(extdir)/date/libsieve_ext_date.la \ $(extdir)/spamvirustest/libsieve_ext_spamvirustest.la \ $(extdir)/ihave/libsieve_ext_ihave.la \ $(extdir)/editheader/libsieve_ext_editheader.la \ $(extdir)/duplicate/libsieve_ext_duplicate.la \ $(extdir)/index/libsieve_ext_index.la \ $(extdir)/metadata/libsieve_ext_metadata.la \ $(extdir)/mime/libsieve_ext_mime.la \ $(extdir)/special-use/libsieve_ext_special_use.la \ $(extdir)/extlists/libsieve_ext_extlists.la \ $(extdir)/vnd.dovecot/debug/libsieve_ext_debug.la \ $(extdir)/vnd.dovecot/environment/libsieve_ext_vnd_environment.la \ $(extdir)/vnd.dovecot/report/libsieve_ext_vnd_report.la \ $(am__DEPENDENCIES_1) am__objects_1 = cmp-i-octet.lo cmp-i-ascii-casemap.lo \ cmp-i-unicode-casemap.lo am__objects_2 = mcht-is.lo mcht-contains.lo mcht-matches.lo am__objects_3 = tst-truefalse.lo tst-not.lo tst-anyof.lo tst-allof.lo \ tst-address.lo tst-header.lo tst-exists.lo tst-size.lo am__objects_4 = cmd-require.lo cmd-stop.lo cmd-if.lo cmd-keep.lo \ cmd-redirect.lo cmd-discard.lo am__objects_5 = ext-fileinto.lo ext-reject.lo ext-envelope.lo \ ext-encoded-character.lo am_libdovecot_sieve_la_OBJECTS = sieve-settings.lo sieve-message.lo \ sieve-smtp.lo sieve-lexer.lo sieve-script.lo sieve-storage.lo \ sieve-storage-settings.lo sieve-storage-sync.lo sieve-ast.lo \ sieve-binary.lo sieve-binary-file.lo sieve-binary-code.lo \ sieve-binary-debug.lo sieve-parser.lo sieve-address.lo \ sieve-validator.lo sieve-generator.lo sieve-execute.lo \ sieve-interpreter.lo sieve-runtime-trace.lo \ sieve-code-dumper.lo sieve-binary-dumper.lo sieve-result.lo \ sieve-error.lo sieve-objects.lo sieve-stringlist.lo \ sieve-comparators.lo sieve-match-types.lo \ sieve-address-parts.lo sieve-address-source.lo sieve-match.lo \ sieve-commands.lo sieve-code.lo sieve-actions.lo \ sieve-extensions.lo sieve-plugins.lo $(am__objects_1) \ $(am__objects_2) $(am__objects_3) $(am__objects_4) \ $(am__objects_5) sieve.lo libdovecot_sieve_la_OBJECTS = $(am_libdovecot_sieve_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-discard.Plo \ ./$(DEPDIR)/cmd-if.Plo ./$(DEPDIR)/cmd-keep.Plo \ ./$(DEPDIR)/cmd-redirect.Plo ./$(DEPDIR)/cmd-require.Plo \ ./$(DEPDIR)/cmd-stop.Plo ./$(DEPDIR)/cmp-i-ascii-casemap.Plo \ ./$(DEPDIR)/cmp-i-octet.Plo \ ./$(DEPDIR)/cmp-i-unicode-casemap.Plo \ ./$(DEPDIR)/ext-encoded-character.Plo \ ./$(DEPDIR)/ext-envelope.Plo ./$(DEPDIR)/ext-fileinto.Plo \ ./$(DEPDIR)/ext-reject.Plo ./$(DEPDIR)/mcht-contains.Plo \ ./$(DEPDIR)/mcht-is.Plo ./$(DEPDIR)/mcht-matches.Plo \ ./$(DEPDIR)/sieve-actions.Plo \ ./$(DEPDIR)/sieve-address-parts.Plo \ ./$(DEPDIR)/sieve-address-source.Plo \ ./$(DEPDIR)/sieve-address.Plo ./$(DEPDIR)/sieve-ast.Plo \ ./$(DEPDIR)/sieve-binary-code.Plo \ ./$(DEPDIR)/sieve-binary-debug.Plo \ ./$(DEPDIR)/sieve-binary-dumper.Plo \ ./$(DEPDIR)/sieve-binary-file.Plo ./$(DEPDIR)/sieve-binary.Plo \ ./$(DEPDIR)/sieve-code-dumper.Plo ./$(DEPDIR)/sieve-code.Plo \ ./$(DEPDIR)/sieve-commands.Plo \ ./$(DEPDIR)/sieve-comparators.Plo ./$(DEPDIR)/sieve-error.Plo \ ./$(DEPDIR)/sieve-execute.Plo ./$(DEPDIR)/sieve-extensions.Plo \ ./$(DEPDIR)/sieve-generator.Plo \ ./$(DEPDIR)/sieve-interpreter.Plo ./$(DEPDIR)/sieve-lexer.Plo \ ./$(DEPDIR)/sieve-match-types.Plo ./$(DEPDIR)/sieve-match.Plo \ ./$(DEPDIR)/sieve-message.Plo ./$(DEPDIR)/sieve-objects.Plo \ ./$(DEPDIR)/sieve-parser.Plo ./$(DEPDIR)/sieve-plugins.Plo \ ./$(DEPDIR)/sieve-result.Plo \ ./$(DEPDIR)/sieve-runtime-trace.Plo \ ./$(DEPDIR)/sieve-script.Plo ./$(DEPDIR)/sieve-settings.Plo \ ./$(DEPDIR)/sieve-smtp.Plo \ ./$(DEPDIR)/sieve-storage-settings.Plo \ ./$(DEPDIR)/sieve-storage-sync.Plo \ ./$(DEPDIR)/sieve-storage.Plo ./$(DEPDIR)/sieve-stringlist.Plo \ ./$(DEPDIR)/sieve-validator.Plo ./$(DEPDIR)/sieve.Plo \ ./$(DEPDIR)/tst-address.Plo ./$(DEPDIR)/tst-allof.Plo \ ./$(DEPDIR)/tst-anyof.Plo ./$(DEPDIR)/tst-exists.Plo \ ./$(DEPDIR)/tst-header.Plo ./$(DEPDIR)/tst-not.Plo \ ./$(DEPDIR)/tst-size.Plo ./$(DEPDIR)/tst-truefalse.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libdovecot_sieve_la_SOURCES) DIST_SOURCES = $(libdovecot_sieve_la_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 HEADERS = $(pkginc_lib_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 distdir-am 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)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp 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_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = util storage plugins dovecot_pkglib_LTLIBRARIES = libdovecot-sieve.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) \ -I$(top_srcdir)/src/lib-sieve/util \ -DMODULEDIR=\""$(dovecot_moduledir)"\" tests = \ tst-truefalse.c \ tst-not.c \ tst-anyof.c \ tst-allof.c \ tst-address.c \ tst-header.c \ tst-exists.c \ tst-size.c commands = \ cmd-require.c \ cmd-stop.c \ cmd-if.c \ cmd-keep.c \ cmd-redirect.c \ cmd-discard.c extensions = \ ext-fileinto.c \ ext-reject.c \ ext-envelope.c \ ext-encoded-character.c match_types = \ mcht-is.c \ mcht-contains.c \ mcht-matches.c comparators = \ cmp-i-octet.c \ cmp-i-ascii-casemap.c \ cmp-i-unicode-casemap.c @BUILD_UNFINISHED_TRUE@unfinished_storages = @BUILD_UNFINISHED_TRUE@unfinished_plugins = strgdir = $(top_builddir)/src/lib-sieve/storage storages = \ $(strgdir)/data/libsieve_storage_data.la \ $(strgdir)/file/libsieve_storage_file.la \ $(strgdir)/dict/libsieve_storage_dict.la \ $(strgdir)/ldap/libsieve_storage_ldap.la \ $(unfinished_storages) extdir = $(top_builddir)/src/lib-sieve/plugins plugins = \ $(extdir)/vacation/libsieve_ext_vacation.la \ $(extdir)/subaddress/libsieve_ext_subaddress.la \ $(extdir)/comparator-i-ascii-numeric/libsieve_ext_comparator-i-ascii-numeric.la \ $(extdir)/relational/libsieve_ext_relational.la \ $(extdir)/regex/libsieve_ext_regex.la \ $(extdir)/copy/libsieve_ext_copy.la \ $(extdir)/imap4flags/libsieve_ext_imap4flags.la \ $(extdir)/include/libsieve_ext_include.la \ $(extdir)/body/libsieve_ext_body.la \ $(extdir)/variables/libsieve_ext_variables.la \ $(extdir)/enotify/libsieve_ext_enotify.la \ $(extdir)/environment/libsieve_ext_environment.la \ $(extdir)/mailbox/libsieve_ext_mailbox.la \ $(extdir)/date/libsieve_ext_date.la \ $(extdir)/spamvirustest/libsieve_ext_spamvirustest.la \ $(extdir)/ihave/libsieve_ext_ihave.la \ $(extdir)/editheader/libsieve_ext_editheader.la \ $(extdir)/duplicate/libsieve_ext_duplicate.la \ $(extdir)/index/libsieve_ext_index.la \ $(extdir)/metadata/libsieve_ext_metadata.la \ $(extdir)/mime/libsieve_ext_mime.la \ $(extdir)/special-use/libsieve_ext_special_use.la \ $(extdir)/extlists/libsieve_ext_extlists.la \ $(extdir)/vnd.dovecot/debug/libsieve_ext_debug.la \ $(extdir)/vnd.dovecot/environment/libsieve_ext_vnd_environment.la \ $(extdir)/vnd.dovecot/report/libsieve_ext_vnd_report.la \ $(unfinished_plugins) libdovecot_sieve_la_DEPENDENCIES = \ $(storages) \ $(plugins) \ $(top_builddir)/src/lib-sieve/util/libsieve_util.la \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) libdovecot_sieve_la_LIBADD = \ $(storages) \ $(plugins) \ $(top_builddir)/src/lib-sieve/util/libsieve_util.la \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) libdovecot_sieve_la_SOURCES = \ sieve-settings.c \ sieve-message.c \ sieve-smtp.c \ sieve-lexer.c \ sieve-script.c \ sieve-storage.c \ sieve-storage-settings.c \ sieve-storage-sync.c \ sieve-ast.c \ sieve-binary.c \ sieve-binary-file.c \ sieve-binary-code.c \ sieve-binary-debug.c \ sieve-parser.c \ sieve-address.c \ sieve-validator.c \ sieve-generator.c \ sieve-execute.c \ sieve-interpreter.c \ sieve-runtime-trace.c \ sieve-code-dumper.c \ sieve-binary-dumper.c \ sieve-result.c \ sieve-error.c \ sieve-objects.c \ sieve-stringlist.c \ sieve-comparators.c \ sieve-match-types.c \ sieve-address-parts.c \ sieve-address-source.c \ sieve-match.c \ sieve-commands.c \ sieve-code.c \ sieve-actions.c \ sieve-extensions.c \ sieve-plugins.c \ $(comparators) \ $(match_types) \ $(tests) \ $(commands) \ $(extensions) \ sieve.c headers = \ sieve-config.h \ sieve-types.h \ sieve-common.h \ sieve-limits.h \ sieve-settings.h \ sieve-message.h \ sieve-smtp.h \ sieve-lexer.h \ sieve-script.h \ sieve-script-private.h \ sieve-storage.h \ sieve-storage-private.h \ sieve-storage-settings.h \ sieve-ast.h \ sieve-binary.h \ sieve-binary-private.h \ sieve-parser.h \ sieve-address.h \ sieve-validator.h \ sieve-generator.h \ sieve-execute.h \ sieve-interpreter.h \ sieve-runtime-trace.h \ sieve-runtime.h \ sieve-code-dumper.h \ sieve-binary-dumper.h \ sieve-dump.h \ sieve-result.h \ sieve-error.h \ sieve-error-private.h \ sieve-objects.h \ sieve-stringlist.h \ sieve-match.h \ sieve-comparators.h \ sieve-match-types.h \ sieve-address-parts.h \ sieve-address-source.h \ sieve-commands.h \ sieve-code.h \ sieve-actions.h \ sieve-extensions.h \ sieve-plugins.h \ sieve.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(headers) all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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-dovecot_pkglibLTLIBRARIES: $(dovecot_pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(dovecot_pkglib_LTLIBRARIES)'; test -n "$(dovecot_pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(dovecot_pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dovecot_pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(dovecot_pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(dovecot_pkglibdir)"; \ } uninstall-dovecot_pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(dovecot_pkglib_LTLIBRARIES)'; test -n "$(dovecot_pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(dovecot_pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(dovecot_pkglibdir)/$$f"; \ done clean-dovecot_pkglibLTLIBRARIES: -test -z "$(dovecot_pkglib_LTLIBRARIES)" || rm -f $(dovecot_pkglib_LTLIBRARIES) @list='$(dovecot_pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdovecot-sieve.la: $(libdovecot_sieve_la_OBJECTS) $(libdovecot_sieve_la_DEPENDENCIES) $(EXTRA_libdovecot_sieve_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) -rpath $(dovecot_pkglibdir) $(libdovecot_sieve_la_OBJECTS) $(libdovecot_sieve_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-discard.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-if.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-keep.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-redirect.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-require.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-stop.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp-i-ascii-casemap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp-i-octet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp-i-unicode-casemap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-encoded-character.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-envelope.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-fileinto.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-reject.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-contains.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-is.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-matches.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-actions.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-address-parts.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-address-source.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-address.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-ast.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary-code.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary-debug.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary-dumper.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary-file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-code-dumper.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-code.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-commands.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-comparators.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-execute.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-extensions.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-generator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-interpreter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-lexer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-match-types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-match.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-message.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-objects.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-plugins.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-result.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-runtime-trace.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-smtp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-storage-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-storage-sync.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-storage.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-stringlist.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-validator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-address.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-allof.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-anyof.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-exists.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-header.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-not.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-size.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-truefalse.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(dovecot_pkglibdir)" "$(DESTDIR)$(pkginc_libdir)"; 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-dovecot_pkglibLTLIBRARIES clean-generic clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/cmd-discard.Plo -rm -f ./$(DEPDIR)/cmd-if.Plo -rm -f ./$(DEPDIR)/cmd-keep.Plo -rm -f ./$(DEPDIR)/cmd-redirect.Plo -rm -f ./$(DEPDIR)/cmd-require.Plo -rm -f ./$(DEPDIR)/cmd-stop.Plo -rm -f ./$(DEPDIR)/cmp-i-ascii-casemap.Plo -rm -f ./$(DEPDIR)/cmp-i-octet.Plo -rm -f ./$(DEPDIR)/cmp-i-unicode-casemap.Plo -rm -f ./$(DEPDIR)/ext-encoded-character.Plo -rm -f ./$(DEPDIR)/ext-envelope.Plo -rm -f ./$(DEPDIR)/ext-fileinto.Plo -rm -f ./$(DEPDIR)/ext-reject.Plo -rm -f ./$(DEPDIR)/mcht-contains.Plo -rm -f ./$(DEPDIR)/mcht-is.Plo -rm -f ./$(DEPDIR)/mcht-matches.Plo -rm -f ./$(DEPDIR)/sieve-actions.Plo -rm -f ./$(DEPDIR)/sieve-address-parts.Plo -rm -f ./$(DEPDIR)/sieve-address-source.Plo -rm -f ./$(DEPDIR)/sieve-address.Plo -rm -f ./$(DEPDIR)/sieve-ast.Plo -rm -f ./$(DEPDIR)/sieve-binary-code.Plo -rm -f ./$(DEPDIR)/sieve-binary-debug.Plo -rm -f ./$(DEPDIR)/sieve-binary-dumper.Plo -rm -f ./$(DEPDIR)/sieve-binary-file.Plo -rm -f ./$(DEPDIR)/sieve-binary.Plo -rm -f ./$(DEPDIR)/sieve-code-dumper.Plo -rm -f ./$(DEPDIR)/sieve-code.Plo -rm -f ./$(DEPDIR)/sieve-commands.Plo -rm -f ./$(DEPDIR)/sieve-comparators.Plo -rm -f ./$(DEPDIR)/sieve-error.Plo -rm -f ./$(DEPDIR)/sieve-execute.Plo -rm -f ./$(DEPDIR)/sieve-extensions.Plo -rm -f ./$(DEPDIR)/sieve-generator.Plo -rm -f ./$(DEPDIR)/sieve-interpreter.Plo -rm -f ./$(DEPDIR)/sieve-lexer.Plo -rm -f ./$(DEPDIR)/sieve-match-types.Plo -rm -f ./$(DEPDIR)/sieve-match.Plo -rm -f ./$(DEPDIR)/sieve-message.Plo -rm -f ./$(DEPDIR)/sieve-objects.Plo -rm -f ./$(DEPDIR)/sieve-parser.Plo -rm -f ./$(DEPDIR)/sieve-plugins.Plo -rm -f ./$(DEPDIR)/sieve-result.Plo -rm -f ./$(DEPDIR)/sieve-runtime-trace.Plo -rm -f ./$(DEPDIR)/sieve-script.Plo -rm -f ./$(DEPDIR)/sieve-settings.Plo -rm -f ./$(DEPDIR)/sieve-smtp.Plo -rm -f ./$(DEPDIR)/sieve-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-storage-sync.Plo -rm -f ./$(DEPDIR)/sieve-storage.Plo -rm -f ./$(DEPDIR)/sieve-stringlist.Plo -rm -f ./$(DEPDIR)/sieve-validator.Plo -rm -f ./$(DEPDIR)/sieve.Plo -rm -f ./$(DEPDIR)/tst-address.Plo -rm -f ./$(DEPDIR)/tst-allof.Plo -rm -f ./$(DEPDIR)/tst-anyof.Plo -rm -f ./$(DEPDIR)/tst-exists.Plo -rm -f ./$(DEPDIR)/tst-header.Plo -rm -f ./$(DEPDIR)/tst-not.Plo -rm -f ./$(DEPDIR)/tst-size.Plo -rm -f ./$(DEPDIR)/tst-truefalse.Plo -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-dovecot_pkglibLTLIBRARIES \ install-pkginc_libHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: 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 ./$(DEPDIR)/cmd-discard.Plo -rm -f ./$(DEPDIR)/cmd-if.Plo -rm -f ./$(DEPDIR)/cmd-keep.Plo -rm -f ./$(DEPDIR)/cmd-redirect.Plo -rm -f ./$(DEPDIR)/cmd-require.Plo -rm -f ./$(DEPDIR)/cmd-stop.Plo -rm -f ./$(DEPDIR)/cmp-i-ascii-casemap.Plo -rm -f ./$(DEPDIR)/cmp-i-octet.Plo -rm -f ./$(DEPDIR)/cmp-i-unicode-casemap.Plo -rm -f ./$(DEPDIR)/ext-encoded-character.Plo -rm -f ./$(DEPDIR)/ext-envelope.Plo -rm -f ./$(DEPDIR)/ext-fileinto.Plo -rm -f ./$(DEPDIR)/ext-reject.Plo -rm -f ./$(DEPDIR)/mcht-contains.Plo -rm -f ./$(DEPDIR)/mcht-is.Plo -rm -f ./$(DEPDIR)/mcht-matches.Plo -rm -f ./$(DEPDIR)/sieve-actions.Plo -rm -f ./$(DEPDIR)/sieve-address-parts.Plo -rm -f ./$(DEPDIR)/sieve-address-source.Plo -rm -f ./$(DEPDIR)/sieve-address.Plo -rm -f ./$(DEPDIR)/sieve-ast.Plo -rm -f ./$(DEPDIR)/sieve-binary-code.Plo -rm -f ./$(DEPDIR)/sieve-binary-debug.Plo -rm -f ./$(DEPDIR)/sieve-binary-dumper.Plo -rm -f ./$(DEPDIR)/sieve-binary-file.Plo -rm -f ./$(DEPDIR)/sieve-binary.Plo -rm -f ./$(DEPDIR)/sieve-code-dumper.Plo -rm -f ./$(DEPDIR)/sieve-code.Plo -rm -f ./$(DEPDIR)/sieve-commands.Plo -rm -f ./$(DEPDIR)/sieve-comparators.Plo -rm -f ./$(DEPDIR)/sieve-error.Plo -rm -f ./$(DEPDIR)/sieve-execute.Plo -rm -f ./$(DEPDIR)/sieve-extensions.Plo -rm -f ./$(DEPDIR)/sieve-generator.Plo -rm -f ./$(DEPDIR)/sieve-interpreter.Plo -rm -f ./$(DEPDIR)/sieve-lexer.Plo -rm -f ./$(DEPDIR)/sieve-match-types.Plo -rm -f ./$(DEPDIR)/sieve-match.Plo -rm -f ./$(DEPDIR)/sieve-message.Plo -rm -f ./$(DEPDIR)/sieve-objects.Plo -rm -f ./$(DEPDIR)/sieve-parser.Plo -rm -f ./$(DEPDIR)/sieve-plugins.Plo -rm -f ./$(DEPDIR)/sieve-result.Plo -rm -f ./$(DEPDIR)/sieve-runtime-trace.Plo -rm -f ./$(DEPDIR)/sieve-script.Plo -rm -f ./$(DEPDIR)/sieve-settings.Plo -rm -f ./$(DEPDIR)/sieve-smtp.Plo -rm -f ./$(DEPDIR)/sieve-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-storage-sync.Plo -rm -f ./$(DEPDIR)/sieve-storage.Plo -rm -f ./$(DEPDIR)/sieve-stringlist.Plo -rm -f ./$(DEPDIR)/sieve-validator.Plo -rm -f ./$(DEPDIR)/sieve.Plo -rm -f ./$(DEPDIR)/tst-address.Plo -rm -f ./$(DEPDIR)/tst-allof.Plo -rm -f ./$(DEPDIR)/tst-anyof.Plo -rm -f ./$(DEPDIR)/tst-exists.Plo -rm -f ./$(DEPDIR)/tst-header.Plo -rm -f ./$(DEPDIR)/tst-not.Plo -rm -f ./$(DEPDIR)/tst-size.Plo -rm -f ./$(DEPDIR)/tst-truefalse.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-dovecot_pkglibLTLIBRARIES \ uninstall-pkginc_libHEADERS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean \ clean-dovecot_pkglibLTLIBRARIES clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dovecot_pkglibLTLIBRARIES \ 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-pkginc_libHEADERS install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-dovecot_pkglibLTLIBRARIES \ uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-config.h0000644000175100001700000000057115100335616024177 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_CONFIG_H #define SIEVE_CONFIG_H #include "pigeonhole-config.h" #include "pigeonhole-version.h" #define SIEVE_IMPLEMENTATION PIGEONHOLE_NAME " Sieve " PIGEONHOLE_VERSION_FULL #define SIEVE_SCRIPT_FILEEXT "sieve" #define SIEVE_BINARY_FILEEXT "svbin" #define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON" #define DEFAULT_REDIRECT_DUPLICATE_PERIOD (3600 * 12) #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-runtime.h0000644000175100001700000000132615100335616024414 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_RUNTIME_H #define SIEVE_RUNTIME_H #include "sieve-common.h" #include "sieve-execute.h" /* * Runtime environment */ struct sieve_runtime_env { const struct sieve_execute_env *exec_env; struct event *event; /* Interpreter */ struct sieve_interpreter *interp; struct sieve_error_handler *ehandler; /* Executing script */ struct sieve_script *script; /* Executing binary */ struct sieve_binary *sbin; struct sieve_binary_block *sblock; /* Current code */ sieve_size_t pc; const struct sieve_operation *oprtn; /* Tested message */ struct sieve_message_context *msgctx; /* Filter result */ struct sieve_result *result; /* Runtime tracing */ struct sieve_runtime_trace *trace; }; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary.c0000644000175100001700000003425215100335616024214 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "mempool.h" #include "buffer.h" #include "hash.h" #include "array.h" #include "ostream.h" #include "eacces-error.h" #include "safe-mkstemp.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-script.h" #include "sieve-binary-private.h" /* * Forward declarations */ static inline struct sieve_binary_extension_reg * sieve_binary_extension_get_reg(struct sieve_binary *sbin, const struct sieve_extension *ext, bool create); static inline int sieve_binary_extension_register(struct sieve_binary *sbin, const struct sieve_extension *ext, struct sieve_binary_extension_reg **reg); /* * Binary object */ void sieve_binary_update_event(struct sieve_binary *sbin, const char *new_path) { if (new_path != NULL) { event_set_append_log_prefix( sbin->event, t_strdup_printf("binary %s: ", new_path)); } else if (sbin->path != NULL) { event_set_append_log_prefix( sbin->event, t_strdup_printf("binary %s: ", sbin->path)); } else if (sbin->script != NULL) { event_set_append_log_prefix( sbin->event, t_strdup_printf("binary %s: ", sieve_script_name(sbin->script))); } else { event_set_append_log_prefix(sbin->event, "binary: "); } } struct sieve_binary * sieve_binary_create(struct sieve_instance *svinst, struct sieve_script *script) { pool_t pool; struct sieve_binary *sbin; const struct sieve_extension *const *ext_preloaded; unsigned int i, ext_count; pool = pool_alloconly_create("sieve_binary", 16384); sbin = p_new(pool, struct sieve_binary, 1); sbin->pool = pool; sbin->refcount = 1; sbin->svinst = svinst; sbin->header.version_major = SIEVE_BINARY_VERSION_MAJOR; sbin->header.version_minor = SIEVE_BINARY_VERSION_MINOR; sbin->script = script; if (script != NULL) sieve_script_ref(script); sbin->event = event_create(svinst->event); ext_count = sieve_extensions_get_count(svinst); p_array_init(&sbin->linked_extensions, pool, ext_count); p_array_init(&sbin->extensions, pool, ext_count); p_array_init(&sbin->extension_index, pool, ext_count); p_array_init(&sbin->blocks, pool, 16); /* Pre-load core language features implemented as 'extensions' */ ext_preloaded = sieve_extensions_get_preloaded(svinst, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_extension_def *ext_def = ext_preloaded[i]->def; if (ext_def != NULL && ext_def->binary_load != NULL) (void)ext_def->binary_load(ext_preloaded[i], sbin); } return sbin; } struct sieve_binary *sieve_binary_create_new(struct sieve_script *script) { struct sieve_binary *sbin = sieve_binary_create(sieve_script_svinst(script), script); struct sieve_binary_block *sblock; unsigned int i; sieve_binary_update_event(sbin, NULL); /* Create script metadata block */ sblock = sieve_binary_block_create(sbin); sieve_script_binary_write_metadata(script, sblock); /* Create other system blocks */ for (i = 1; i < SBIN_SYSBLOCK_LAST; i++) (void)sieve_binary_block_create(sbin); return sbin; } void sieve_binary_ref(struct sieve_binary *sbin) { sbin->refcount++; } static inline void sieve_binary_extensions_free(struct sieve_binary *sbin) { struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; /* Cleanup binary extensions */ regs = array_get(&sbin->extensions, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_binary_extension *binext = regs[i]->binext; if (binext != NULL && binext->binary_free != NULL) { binext->binary_free(regs[i]->extension, sbin, regs[i]->context); } } } static void sieve_binary_update_resource_usage(struct sieve_binary *sbin) { enum sieve_error error_code; if (sbin->rusage_updated) { (void)sieve_binary_file_update_resource_usage( sbin, &error_code); } sbin->rusage_updated = FALSE; } void sieve_binary_unref(struct sieve_binary **_sbin) { struct sieve_binary *sbin = *_sbin; *_sbin = NULL; if (sbin == NULL) return; i_assert(sbin->refcount > 0); if (--sbin->refcount != 0) return; sieve_binary_file_close(&sbin->file); sieve_binary_update_resource_usage(sbin); sieve_binary_extensions_free(sbin); sieve_script_unref(&sbin->script); event_unref(&sbin->event); pool_unref(&sbin->pool); } void sieve_binary_close(struct sieve_binary **_sbin) { struct sieve_binary *sbin = *_sbin; *_sbin = NULL; if (sbin == NULL) return; sieve_binary_file_close(&sbin->file); sieve_binary_update_resource_usage(sbin); sieve_binary_unref(&sbin); } /* * Resource usage */ void sieve_binary_get_resource_usage(struct sieve_binary *sbin, struct sieve_resource_usage *rusage_r) { struct sieve_binary_header *header = &sbin->header; time_t update_time = header->resource_usage.update_time; unsigned int timeout = sbin->svinst->set->resource_usage_timeout; if (update_time != 0 && (ioloop_time - update_time) > (time_t)timeout) i_zero(&header->resource_usage); sieve_resource_usage_init(rusage_r); rusage_r->cpu_time_msecs = header->resource_usage.cpu_time_msecs; sieve_resource_usage_add(rusage_r, &sbin->rusage); } bool sieve_binary_check_resource_usage(struct sieve_binary *sbin) { struct sieve_binary_header *header = &sbin->header; struct sieve_resource_usage rusage; sieve_binary_get_resource_usage(sbin, &rusage); if (sieve_resource_usage_is_excessive(sbin->svinst, &rusage)) { header->flags |= SIEVE_BINARY_FLAG_RESOURCE_LIMIT; return FALSE; } return TRUE; } bool sieve_binary_record_resource_usage( struct sieve_binary *sbin, const struct sieve_resource_usage *rusage) { struct sieve_resource_usage rusage_total; if (sbin == NULL) return TRUE; if (!sieve_resource_usage_is_high(sbin->svinst, rusage)) return TRUE; sieve_resource_usage_add(&sbin->rusage, rusage); sbin->rusage_updated = TRUE; sieve_binary_get_resource_usage(sbin, &rusage_total); e_debug(sbin->event, "Updated cumulative resource usage: %s", sieve_resource_usage_get_summary(&rusage_total)); return sieve_binary_check_resource_usage(sbin); } void sieve_binary_set_resource_usage(struct sieve_binary *sbin, const struct sieve_resource_usage *rusage) { struct sieve_binary_header *header = &sbin->header; i_zero(&header->resource_usage); sbin->rusage = *rusage; sbin->rusage_updated = TRUE; (void)sieve_binary_check_resource_usage(sbin); } /* * Accessors */ pool_t sieve_binary_pool(struct sieve_binary *sbin) { return sbin->pool; } struct sieve_script *sieve_binary_script(struct sieve_binary *sbin) { return sbin->script; } const char *sieve_binary_path(struct sieve_binary *sbin) { return sbin->path; } bool sieve_binary_saved(struct sieve_binary *sbin) { return (sbin->path != NULL); } bool sieve_binary_loaded(struct sieve_binary *sbin) { return (sbin->file != NULL); } const char *sieve_binary_source(struct sieve_binary *sbin) { if (sbin->script != NULL && (sbin->path == NULL || sbin->file == NULL)) return sieve_script_label(sbin->script); return sbin->path; } struct sieve_instance *sieve_binary_svinst(struct sieve_binary *sbin) { return sbin->svinst; } time_t sieve_binary_mtime(struct sieve_binary *sbin) { i_assert(sbin->file != NULL); return sbin->file->st.st_mtime; } const struct stat *sieve_binary_stat(struct sieve_binary *sbin) { i_assert(sbin->file != NULL); return &sbin->file->st; } const char *sieve_binary_script_name(struct sieve_binary *sbin) { return (sbin->script == NULL ? NULL : sieve_script_name(sbin->script)); } const char *sieve_binary_script_location(struct sieve_binary *sbin) { return (sbin->script == NULL ? NULL : sieve_script_label(sbin->script)); } /* * Utility */ const char *sieve_binfile_from_name(const char *name) { return t_strconcat(name, "."SIEVE_BINARY_FILEEXT, NULL); } /* * Block management */ unsigned int sieve_binary_block_count(struct sieve_binary *sbin) { return array_count(&sbin->blocks); } struct sieve_binary_block *sieve_binary_block_create(struct sieve_binary *sbin) { unsigned int id = sieve_binary_block_count(sbin); struct sieve_binary_block *sblock; sblock = p_new(sbin->pool, struct sieve_binary_block, 1); sblock->data = buffer_create_dynamic(sbin->pool, 64); sblock->sbin = sbin; sblock->id = id; array_append(&sbin->blocks, &sblock, 1); return sblock; } struct sieve_binary_block * sieve_binary_block_create_id(struct sieve_binary *sbin, unsigned int id) { struct sieve_binary_block *sblock; sblock = p_new(sbin->pool, struct sieve_binary_block, 1); array_idx_set(&sbin->blocks, id, &sblock); sblock->data = NULL; sblock->sbin = sbin; sblock->id = id; return sblock; } static bool sieve_binary_block_fetch(struct sieve_binary_block *sblock) { struct sieve_binary *sbin = sblock->sbin; if (sbin->file != NULL) { /* Try to acces the block in the binary on disk (apparently we were lazy) */ if (!sieve_binary_load_block(sblock) || sblock->data == NULL) return FALSE; } else { sblock->data = buffer_create_dynamic(sbin->pool, 64); return TRUE; } return TRUE; } struct sieve_binary_block * sieve_binary_block_get(struct sieve_binary *sbin, unsigned int id) { struct sieve_binary_block *sblock = sieve_binary_block_index(sbin, id); if (sblock == NULL) return NULL; if (sblock->data == NULL && !sieve_binary_block_fetch(sblock)) return NULL; return sblock; } void sieve_binary_block_clear(struct sieve_binary_block *sblock) { buffer_set_used_size(sblock->data, 0); } buffer_t *sieve_binary_block_get_buffer(struct sieve_binary_block *sblock) { if (sblock->data == NULL && !sieve_binary_block_fetch(sblock)) return NULL; return sblock->data; } struct sieve_binary * sieve_binary_block_get_binary(const struct sieve_binary_block *sblock) { return sblock->sbin; } unsigned int sieve_binary_block_get_id(const struct sieve_binary_block *sblock) { return sblock->id; } size_t sieve_binary_block_get_size(const struct sieve_binary_block *sblock) { return _sieve_binary_block_get_size(sblock); } /* * Up-to-date checking */ bool sieve_binary_up_to_date(struct sieve_binary *sbin, enum sieve_compile_flags cpflags) { struct sieve_binary_extension_reg *const *regs; struct sieve_binary_block *sblock; sieve_size_t offset = 0; unsigned int ext_count, i; int ret; i_assert(sbin->file != NULL); sblock = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_SCRIPT_DATA); if (sblock == NULL || sbin->script == NULL) return FALSE; if ((ret = sieve_script_binary_read_metadata(sbin->script, sblock, &offset)) <= 0) { if (ret < 0) { e_debug(sbin->event, "up-to-date: " "failed to read script metadata from binary"); } else { e_debug(sbin->event, "up-to-date: " "script metadata indicates that binary is not up-to-date"); } return FALSE; } regs = array_get(&sbin->extensions, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_binary_extension *binext = regs[i]->binext; if (binext != NULL && binext->binary_up_to_date != NULL && !binext->binary_up_to_date(regs[i]->extension, sbin, regs[i]->context, cpflags)) { e_debug(sbin->event, "up-to-date: " "the %s extension indicates binary is not up-to-date", sieve_extension_name(regs[i]->extension)); return FALSE; } } return TRUE; } /* * Activate the binary (after code generation) */ void sieve_binary_activate(struct sieve_binary *sbin) { struct sieve_binary_extension_reg *const *regs; unsigned int i, ext_count; /* Load other extensions into binary */ regs = array_get(&sbin->linked_extensions, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_extension *ext = regs[i]->extension; if (ext != NULL && ext->def != NULL && ext->def->binary_load != NULL) ext->def->binary_load(ext, sbin); } } /* * Extension handling */ void sieve_binary_extension_set_context(struct sieve_binary *sbin, const struct sieve_extension *ext, void *context) { struct sieve_binary_extension_reg *ereg = sieve_binary_extension_get_reg(sbin, ext, TRUE); if (ereg != NULL) ereg->context = context; } const void * sieve_binary_extension_get_context(struct sieve_binary *sbin, const struct sieve_extension *ext) { struct sieve_binary_extension_reg *ereg = sieve_binary_extension_get_reg(sbin, ext, TRUE); if (ereg != NULL) return ereg->context; return NULL; } void sieve_binary_extension_set(struct sieve_binary *sbin, const struct sieve_extension *ext, const struct sieve_binary_extension *bext, void *context) { struct sieve_binary_extension_reg *ereg = sieve_binary_extension_get_reg(sbin, ext, TRUE); if (ereg != NULL) { ereg->binext = bext; if (context != NULL) ereg->context = context; } } struct sieve_binary_block * sieve_binary_extension_create_block(struct sieve_binary *sbin, const struct sieve_extension *ext) { struct sieve_binary_block *sblock; struct sieve_binary_extension_reg *ereg = sieve_binary_extension_get_reg(sbin, ext, TRUE); i_assert(ereg != NULL); sblock = sieve_binary_block_create(sbin); if (ereg->block_id < SBIN_SYSBLOCK_LAST) ereg->block_id = sblock->id; sblock->ext_index = ereg->index; return sblock; } struct sieve_binary_block * sieve_binary_extension_get_block(struct sieve_binary *sbin, const struct sieve_extension *ext) { struct sieve_binary_extension_reg *ereg = sieve_binary_extension_get_reg(sbin, ext, TRUE); i_assert(ereg != NULL); if (ereg->block_id < SBIN_SYSBLOCK_LAST) return NULL; return sieve_binary_block_get(sbin, ereg->block_id); } int sieve_binary_extension_link(struct sieve_binary *sbin, const struct sieve_extension *ext) { return sieve_binary_extension_register(sbin, ext, NULL); } const struct sieve_extension * sieve_binary_extension_get_by_index(struct sieve_binary *sbin, int index) { struct sieve_binary_extension_reg *const *ereg; if (index < (int)array_count(&sbin->extensions)) { ereg = array_idx(&sbin->extensions, (unsigned int)index); return (*ereg)->extension; } return NULL; } int sieve_binary_extension_get_index(struct sieve_binary *sbin, const struct sieve_extension *ext) { struct sieve_binary_extension_reg *ereg = sieve_binary_extension_get_reg(sbin, ext, FALSE); return (ereg == NULL ? -1 : ereg->index); } int sieve_binary_extensions_count(struct sieve_binary *sbin) { return (int)array_count(&sbin->extensions); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-objects.h0000644000175100001700000000267515100335616024372 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_OBJECTS_H #define SIEVE_OBJECTS_H /* * Object definition */ struct sieve_object_def { const char *identifier; const struct sieve_operand_def *operand; unsigned int code; }; #define SIEVE_OBJECT(_identifier, _operand, _code) \ .obj_def = { \ .identifier = (_identifier), \ .operand = (_operand), \ .code = (_code) \ } /* * Object instance */ struct sieve_object { const struct sieve_object_def *def; const struct sieve_extension *ext; }; #define SIEVE_OBJECT_DEFAULT(_obj) \ { &((_obj).obj_def), NULL } #define SIEVE_OBJECT_EXTENSION(_obj) \ (_obj->object.ext) #define SIEVE_OBJECT_SET_DEF(_obj, def_value) \ STMT_START { \ (_obj)->def = def_value; \ (_obj)->object.def = &(_obj)->def->obj_def; \ } STMT_END /* * Object coding */ void sieve_opr_object_emit (struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_object_def *obj_def); bool sieve_opr_object_read_data (struct sieve_binary_block *sblock, const struct sieve_operand *operand, const struct sieve_operand_class *opclass, sieve_size_t *address, struct sieve_object *obj); bool sieve_opr_object_read (const struct sieve_runtime_env *renv, const struct sieve_operand_class *opclass, sieve_size_t *address, struct sieve_object *obj); bool sieve_opr_object_dump (const struct sieve_dumptime_env *denv, const struct sieve_operand_class *opclass, sieve_size_t *address, struct sieve_object *obj); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-script-private.h0000644000175100001700000000601215100335616025702 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_SCRIPT_PRIVATE_H #define SIEVE_SCRIPT_PRIVATE_H #include "sieve-common.h" #include "sieve-script.h" /* * Script object */ struct sieve_script_vfuncs { void (*destroy)(struct sieve_script *script); int (*open)(struct sieve_script *script); int (*get_stream)(struct sieve_script *script, struct istream **stream_r); /* binary */ int (*binary_read_metadata)(struct sieve_script *_script, struct sieve_binary_block *sblock, sieve_size_t *offset); void (*binary_write_metadata)(struct sieve_script *script, struct sieve_binary_block *sblock); bool (*binary_dump_metadata)(struct sieve_script *script, struct sieve_dumptime_env *denv, struct sieve_binary_block *sblock, sieve_size_t *offset); int (*binary_load)(struct sieve_script *script, struct sieve_binary **sbin_r); int (*binary_save)(struct sieve_script *script, struct sieve_binary *sbin, bool update); const char *(*binary_get_prefix)(struct sieve_script *script); /* management */ int (*rename)(struct sieve_script *script, const char *newname); int (*delete)(struct sieve_script *script); int (*is_active)(struct sieve_script *script); int (*activate)(struct sieve_script *script); /* properties */ int (*get_size)(const struct sieve_script *script, uoff_t *size_r); /* matching */ int (*cmp)(const struct sieve_script *script1, const struct sieve_script *script2); }; struct sieve_script { pool_t pool; unsigned int refcount; struct sieve_storage *storage; struct event *event; const char *driver_name; const struct sieve_script *script_class; struct sieve_script_vfuncs v; const char *name; /* Stream */ struct istream *stream; bool open:1; }; void sieve_script_init(struct sieve_script *script, struct sieve_storage *storage, const struct sieve_script *script_class, const char *name); /* * Binary */ int sieve_script_binary_load_default(struct sieve_script *script, const char *path, struct sieve_binary **sbin_r); int sieve_script_binary_save_default(struct sieve_script *script, struct sieve_binary *sbin, const char *path, bool update, mode_t save_mode); /* * Built-in script drivers */ extern const struct sieve_script sieve_data_script; extern const struct sieve_script sieve_file_script; extern const struct sieve_script sieve_dict_script; extern const struct sieve_script sieve_ldap_script; /* * Error handling */ void sieve_script_set_error(struct sieve_script *script, enum sieve_error error_code, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_script_set_internal_error(struct sieve_script *script); void sieve_script_set_critical(struct sieve_script *script, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_script_set_not_found_error(struct sieve_script *script, const char *name); /* * Script sequence */ struct sieve_script_sequence { struct sieve_storage_sequence *storage_seq; struct sieve_storage *storage; void *storage_data; }; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-match.c0000644000175100001700000001565015100335616024025 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mempool.h" #include "hash.h" #include "array.h" #include "str-sanitize.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-runtime-trace.h" #include "sieve-match.h" /* * Matching implementation */ struct sieve_match_context * sieve_match_begin(const struct sieve_runtime_env *renv, const struct sieve_match_type *mcht, const struct sieve_comparator *cmp) { struct sieve_match_context *mctx; pool_t pool; /* Reject unimplemented match-type */ if (mcht->def == NULL || (mcht->def->match == NULL && mcht->def->match_keys == NULL && mcht->def->match_key == NULL)) return NULL; /* Create match context */ pool = pool_alloconly_create("sieve_match_context", 1024); mctx = p_new(pool, struct sieve_match_context, 1); mctx->pool = pool; mctx->runenv = renv; mctx->match_type = mcht; mctx->comparator = cmp; mctx->exec_status = SIEVE_EXEC_OK; mctx->trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); /* Trace */ if (mctx->trace) { sieve_runtime_trace_descend(renv); sieve_runtime_trace( renv, 0, "starting ':%s' match with '%s' comparator:", sieve_match_type_name(mcht), sieve_comparator_name(cmp)); } /* Initialize match type */ if (mcht->def != NULL && mcht->def->match_init != NULL) mcht->def->match_init(mctx); return mctx; } int sieve_match_value(struct sieve_match_context *mctx, const char *value, size_t value_size, struct sieve_stringlist *key_list) { const struct sieve_match_type *mcht = mctx->match_type; const struct sieve_runtime_env *renv = mctx->runenv; int match, ret; if (mctx->trace) { sieve_runtime_trace(renv, 0, "matching value '%s'", str_sanitize(value, 80)); } /* Match to key values */ sieve_stringlist_reset(key_list); if (mctx->trace) sieve_stringlist_set_trace(key_list, TRUE); sieve_runtime_trace_descend(renv); if (mcht->def->match_keys != NULL) { /* Call match-type's own key match handler */ match = mcht->def->match_keys(mctx, value, value_size, key_list); } else { string_t *key_item = NULL; /* Default key match loop */ match = 0; while (match == 0 && (ret = sieve_stringlist_next_item( key_list, &key_item)) > 0) T_BEGIN { match = mcht->def->match_key( mctx, value, value_size, str_c(key_item), str_len(key_item)); if (mctx->trace) { sieve_runtime_trace( renv, 0, "with key '%s' => %d", str_sanitize(str_c(key_item), 80), match); } } T_END; if (ret < 0) { mctx->exec_status = key_list->exec_status; match = -1; } } sieve_runtime_trace_ascend(renv); if (mctx->match_status < 0 || match < 0) mctx->match_status = -1; else { mctx->match_status = (mctx->match_status > match ? mctx->match_status : match); } return match; } int sieve_match_end(struct sieve_match_context **mctx, int *exec_status) { const struct sieve_match_type *mcht = (*mctx)->match_type; const struct sieve_runtime_env *renv = (*mctx)->runenv; int match = (*mctx)->match_status; if (mcht->def != NULL && mcht->def->match_deinit != NULL) mcht->def->match_deinit(*mctx); if (exec_status != NULL) *exec_status = (*mctx)->exec_status; pool_unref(&(*mctx)->pool); sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "finishing match with result: %s", (match > 0 ? "matched" : (match < 0 ? "error" : "not matched"))); sieve_runtime_trace_ascend(renv); return match; } int sieve_match(const struct sieve_runtime_env *renv, const struct sieve_match_type *mcht, const struct sieve_comparator *cmp, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list, int *exec_status) { struct sieve_match_context *mctx; string_t *value_item = NULL; int match, ret; if ((mctx = sieve_match_begin(renv, mcht, cmp)) == NULL) return 0; /* Match value to keys */ sieve_stringlist_reset(value_list); if (mctx->trace) sieve_stringlist_set_trace(value_list, TRUE); if (mcht->def->match != NULL) { /* Call match-type's match handler */ match = mctx->match_status = mcht->def->match(mctx, value_list, key_list); } else { /* Default value match loop */ match = 0; while (match == 0 && (ret = sieve_stringlist_next_item( value_list, &value_item)) > 0) { match = sieve_match_value( mctx, str_c(value_item), str_len(value_item), key_list); } if (ret < 0) { mctx->exec_status = value_list->exec_status; match = -1; } } (void)sieve_match_end(&mctx, exec_status); return match; } /* * Reading match operands */ int sieve_match_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, int *opt_code) { int _opt_code = 0; bool final = FALSE, opok = TRUE; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } while (opok) { int opt; if ((opt = sieve_opr_optional_dump(denv, address, opt_code)) <= 0) return opt; switch (*opt_code) { case SIEVE_MATCH_OPT_COMPARATOR: opok = sieve_opr_comparator_dump(denv, address); break; case SIEVE_MATCH_OPT_MATCH_TYPE: opok = sieve_opr_match_type_dump(denv, address); break; default: return (final ? -1 : 1); } } return -1; } int sieve_match_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code, int *exec_status, struct sieve_comparator *cmp, struct sieve_match_type *mcht) { int _opt_code = 0; bool final = FALSE; int status = SIEVE_EXEC_OK; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } if (exec_status != NULL) *exec_status = SIEVE_EXEC_OK; while (status == SIEVE_EXEC_OK) { int opt; if ((opt = sieve_opr_optional_read( renv, address, opt_code)) <= 0) { if (opt < 0 && exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return opt; } switch (*opt_code) { case SIEVE_MATCH_OPT_COMPARATOR: if (cmp == NULL) { sieve_runtime_trace_error( renv, "unexpected comparator operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } status = sieve_opr_comparator_read(renv, address, cmp); break; case SIEVE_MATCH_OPT_MATCH_TYPE: if (mcht == NULL) { sieve_runtime_trace_error( renv, "unexpected match-type operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } status = sieve_opr_match_type_read(renv, address, mcht); break; default: if (final) { sieve_runtime_trace_error( renv, "invalid optional operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } return 1; } } if (exec_status != NULL) *exec_status = status; return -1; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-execute.h0000644000175100001700000000217215100335616024373 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXECUTE_H #define SIEVE_EXECUTE_H #include "sieve-common.h" struct sieve_execute_state; struct sieve_execute_env { struct sieve_instance *svinst; pool_t pool; enum sieve_execute_flags flags; struct event *event; const struct sieve_message_data *msgdata; const struct sieve_script_env *scriptenv; struct sieve_execute_state *state; struct sieve_exec_status *exec_status; }; void sieve_execute_init(struct sieve_execute_env *eenv, struct sieve_instance *svinst, pool_t pool, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, enum sieve_execute_flags flags); void sieve_execute_finish(struct sieve_execute_env *eenv, int status); void sieve_execute_deinit(struct sieve_execute_env *eenv); /* * Checking for duplicates */ bool sieve_execute_duplicate_check_available( const struct sieve_execute_env *eenv); int sieve_execute_duplicate_check(const struct sieve_execute_env *eenv, const void *id, size_t id_size, bool *duplicate_r); void sieve_execute_duplicate_mark(const struct sieve_execute_env *eenv, const void *id, size_t id_size, time_t time); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary-dumper.h0000644000175100001700000000161015100335616025503 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_BINARY_DUMPER_H #define SIEVE_BINARY_DUMPER_H #include "sieve-common.h" /* * Binary dumper object */ struct sieve_binary_dumper; struct sieve_binary_dumper * sieve_binary_dumper_create(struct sieve_binary *sbin); void sieve_binary_dumper_free(struct sieve_binary_dumper **dumper); pool_t sieve_binary_dumper_pool(struct sieve_binary_dumper *dumper); /* * Formatted output */ void sieve_binary_dumpf(const struct sieve_dumptime_env *denv, const char *fmt, ...) ATTR_FORMAT(2, 3); void sieve_binary_dump_sectionf(const struct sieve_dumptime_env *denv, const char *fmt, ...) ATTR_FORMAT(2, 3); /* * Dumping the binary */ bool sieve_binary_dumper_run(struct sieve_binary_dumper *dumper, struct ostream *stream, bool verbose); /* * Hexdump production */ bool sieve_binary_dumper_hexdump(struct sieve_binary_dumper *dumper, struct ostream *stream); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-result.c0000644000175100001700000017355015100335616024253 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mempool.h" #include "ostream.h" #include "hash.h" #include "str.h" #include "llist.h" #include "strfuncs.h" #include "str-sanitize.h" #include "var-expand.h" #include "message-address.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-script.h" #include "sieve-error.h" #include "sieve-interpreter.h" #include "sieve-actions.h" #include "sieve-message.h" #include "sieve-result.h" #include struct event_category event_category_sieve_action = { .parent = &event_category_sieve, .name = "sieve-action", }; /* * Types */ enum sieve_action_execution_state { SIEVE_ACTION_EXECUTION_STATE_INIT = 0, SIEVE_ACTION_EXECUTION_STATE_STARTED, SIEVE_ACTION_EXECUTION_STATE_EXECUTED, SIEVE_ACTION_EXECUTION_STATE_FINALIZED, }; struct sieve_result_action { struct sieve_action action; struct sieve_side_effects_list *seffects; struct sieve_result_action *prev, *next; }; struct sieve_side_effects_list { struct sieve_result *result; struct sieve_result_side_effect *first_effect; struct sieve_result_side_effect *last_effect; }; struct sieve_result_side_effect { struct sieve_side_effect seffect; struct sieve_result_side_effect *prev, *next; }; struct sieve_result_action_context { const struct sieve_action_def *action; struct sieve_side_effects_list *seffects; }; /* * Result object */ struct sieve_result { pool_t pool; int refcount; struct sieve_instance *svinst; struct event *event; /* Context data for extensions */ ARRAY(void *) ext_contexts; const struct sieve_execute_env *exec_env; struct sieve_error_handler *ehandler; struct sieve_message_context *msgctx; unsigned int exec_seq; struct sieve_result_execution *exec; struct sieve_action keep_action; struct sieve_action failure_action; unsigned int action_count; struct sieve_result_action *actions_head, *actions_tail; HASH_TABLE(const struct sieve_action_def *, struct sieve_result_action_context *) action_contexts; }; static const char * sieve_result_event_log_message(struct sieve_result *result, enum log_type log_type, const char *message) { const struct sieve_script_env *senv = result->exec_env->scriptenv; i_assert(senv->result_amend_log_message != NULL); return senv->result_amend_log_message(senv, log_type, message); } struct sieve_result * sieve_result_create(struct sieve_instance *svinst, pool_t pool, const struct sieve_execute_env *eenv) { const struct sieve_script_env *senv = eenv->scriptenv; const struct sieve_message_data *msgdata = eenv->msgdata; struct sieve_result *result; pool_ref(pool); result = p_new(pool, struct sieve_result, 1); result->refcount = 1; result->pool = pool; result->svinst = svinst; result->event = event_create(eenv->event); event_add_category(result->event, &event_category_sieve_action); if (senv->result_amend_log_message != NULL) { event_set_log_message_callback( result->event, sieve_result_event_log_message, result); } p_array_init(&result->ext_contexts, pool, 4); result->exec_env = eenv; result->msgctx = sieve_message_context_create(svinst, senv->user, msgdata); result->keep_action.def = &act_store; result->keep_action.ext = NULL; result->failure_action.def = &act_store; result->failure_action.ext = NULL; result->action_count = 0; result->actions_head = NULL; result->actions_tail = NULL; return result; } void sieve_result_ref(struct sieve_result *result) { i_assert(result->refcount > 0); result->refcount++; } static void sieve_result_action_deinit(struct sieve_result_action *ract) { event_unref(&ract->action.event); } void sieve_result_unref(struct sieve_result **_result) { struct sieve_result *result = *_result; struct sieve_result_action *ract; if (result == NULL) return; *_result = NULL; i_assert(result->refcount > 0); if (--result->refcount != 0) return; sieve_message_context_unref(&result->msgctx); hash_table_destroy(&result->action_contexts); ract = result->actions_head; while (ract != NULL) { sieve_result_action_deinit(ract); ract = ract->next; } event_unref(&result->event); pool_unref(&result->pool); } pool_t sieve_result_pool(struct sieve_result *result) { return result->pool; } /* * Getters/Setters */ const struct sieve_script_env * sieve_result_get_script_env(struct sieve_result *result) { return result->exec_env->scriptenv; } const struct sieve_message_data * sieve_result_get_message_data(struct sieve_result *result) { return result->exec_env->msgdata; } struct sieve_message_context * sieve_result_get_message_context(struct sieve_result *result) { return result->msgctx; } unsigned int sieve_result_get_exec_seq(struct sieve_result *result) { return result->exec_seq; } /* * Extension support */ void sieve_result_extension_set_context(struct sieve_result *result, const struct sieve_extension *ext, void *context) { if (ext->id < 0) return; array_idx_set(&result->ext_contexts, (unsigned int) ext->id, &context); } const void * sieve_result_extension_get_context(struct sieve_result *result, const struct sieve_extension *ext) { void *const *ctx; if (ext->id < 0 || ext->id >= (int) array_count(&result->ext_contexts)) return NULL; ctx = array_idx(&result->ext_contexts, (unsigned int) ext->id); return *ctx; } /* * Result composition */ static void sieve_result_init_action_event(struct sieve_result *result, struct sieve_action *action, bool add_prefix) { const char *name = sieve_action_name(action); if (action->event != NULL) return; action->event = event_create(result->event); if (add_prefix && name != NULL) { event_set_append_log_prefix( action->event, t_strconcat(name, " action: ", NULL)); } event_add_str(action->event, "action_name", name); event_add_str(action->event, "script_location", action->location); } void sieve_result_add_implicit_side_effect( struct sieve_result *result, const struct sieve_action_def *to_action, bool to_keep, const struct sieve_extension *ext, const struct sieve_side_effect_def *seff_def, void *context) { struct sieve_result_action_context *actctx = NULL; struct sieve_side_effect seffect; to_action = to_keep ? &act_store : to_action; if (!hash_table_is_created(result->action_contexts)) { hash_table_create_direct(&result->action_contexts, result->pool, 0); } else { actctx = hash_table_lookup(result->action_contexts, to_action); } if (actctx == NULL) { actctx = p_new(result->pool, struct sieve_result_action_context, 1); actctx->action = to_action; actctx->seffects = sieve_side_effects_list_create(result); hash_table_insert(result->action_contexts, to_action, actctx); } seffect.object.def = &seff_def->obj_def; seffect.object.ext = ext; seffect.def = seff_def; seffect.context = context; sieve_side_effects_list_add(actctx->seffects, &seffect); } static int sieve_result_side_effects_merge(const struct sieve_runtime_env *renv, const struct sieve_action *action, struct sieve_result_action *old_action, struct sieve_side_effects_list *new_seffects) { struct sieve_side_effects_list *old_seffects = old_action->seffects; int ret; struct sieve_result_side_effect *rsef, *nrsef; /* Allow side-effects to merge with existing copy */ /* Merge existing side effects */ rsef = old_seffects != NULL ? old_seffects->first_effect : NULL; while (rsef != NULL) { struct sieve_side_effect *seffect = &rsef->seffect; bool found = FALSE; i_assert(seffect->def != NULL); if (seffect->def->merge != NULL) { /* Try to find it among the new */ nrsef = (new_seffects != NULL ? new_seffects->first_effect : NULL); while (nrsef != NULL) { struct sieve_side_effect *nseffect = &nrsef->seffect; if (nseffect->def == seffect->def) { if (seffect->def->merge( renv, action, seffect, nseffect, &seffect->context) < 0) return -1; found = TRUE; break; } nrsef = nrsef->next; } /* Not found? */ if (!found && seffect->def->merge( renv, action, seffect, NULL, &rsef->seffect.context) < 0) return -1; } rsef = rsef->next; } /* Merge new Side effects */ nrsef = new_seffects != NULL ? new_seffects->first_effect : NULL; while (nrsef != NULL) { struct sieve_side_effect *nseffect = &nrsef->seffect; bool found = FALSE; i_assert(nseffect->def != NULL); if (nseffect->def->merge != NULL) { /* Try to find it among the exising */ rsef = (old_seffects != NULL ? old_seffects->first_effect : NULL); while (rsef != NULL) { if (rsef->seffect.def == nseffect->def) { found = TRUE; break; } rsef = rsef->next; } /* Not found? */ if (!found) { void *new_context = NULL; if ((ret = nseffect->def->merge( renv, action, nseffect, nseffect, &new_context)) < 0) return -1; if (ret != 0) { if (old_action->seffects == NULL) { old_action->seffects = old_seffects = sieve_side_effects_list_create(renv->result); } nseffect->context = new_context; /* Add side effect */ sieve_side_effects_list_add(old_seffects, nseffect); } } } nrsef = nrsef->next; } return 1; } static void sieve_result_action_detach(struct sieve_result *result, struct sieve_result_action *raction) { if (result->actions_head == raction) result->actions_head = raction->next; if (result->actions_tail == raction) result->actions_tail = raction->prev; if (raction->next != NULL) raction->next->prev = raction->prev; if (raction->prev != NULL) raction->prev->next = raction->next; raction->next = NULL; raction->prev = NULL; if (result->action_count > 0) result->action_count--; } static int _sieve_result_add_action(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, const char *name, const struct sieve_action_def *act_def, struct sieve_side_effects_list *seffects, void *context, unsigned int instance_limit, bool preserve_mail, bool keep) { int ret = 0; unsigned int instance_count = 0; struct sieve_instance *svinst = renv->exec_env->svinst; struct sieve_result *result = renv->result; struct sieve_result_action *raction = NULL, *kaction = NULL; struct sieve_action action; i_assert(name != NULL || act_def != NULL); action.name = name; action.def = act_def; action.ext = ext; action.location = sieve_runtime_get_full_command_location(renv); action.context = context; action.exec_seq = result->exec_seq; /* First, check for duplicates or conflicts */ raction = result->actions_head; while (raction != NULL) { const struct sieve_action *oact = &raction->action; bool oact_new = (oact->exec_seq == result->exec_seq); if (keep && raction->action.keep) { /* Duplicate keep */ if (oact->def == NULL || !oact_new) { /* Keep action from preceeding execution */ /* Detach existing keep action */ sieve_result_action_detach(result, raction); /* Merge existing side-effects with new keep action */ if (kaction == NULL) kaction = raction; if ((ret = sieve_result_side_effects_merge( renv, &action, kaction, seffects)) <= 0) return ret; } else { /* True duplicate */ return sieve_result_side_effects_merge( renv, &action, raction, seffects); } } else if ( act_def != NULL && raction->action.def == act_def ) { instance_count++; /* Possible duplicate */ if (act_def->check_duplicate != NULL) { if ((ret = act_def->check_duplicate( renv, &action, &raction->action)) < 0) return ret; /* Duplicate */ if (ret == 1) { if (keep && !oact->keep) { /* New keep has higher precedence than existing duplicate non-keep action. So, take over the result action object and transform it into a keep. */ if ((ret = sieve_result_side_effects_merge( renv, &action, raction, seffects)) < 0) return ret; if (kaction == NULL) { raction->action.context = NULL; raction->action.location = p_strdup(result->pool, action.location); /* Note that existing execution status is retained, making sure that keep is not executed multiple times. */ kaction = raction; } else { sieve_result_action_detach(result, raction); if ((ret = sieve_result_side_effects_merge( renv, &action, kaction, raction->seffects)) < 0) return ret; } } else { /* Merge side-effects, but don't add new action */ return sieve_result_side_effects_merge( renv, &action, raction, seffects); } } } } else { if (act_def != NULL && oact->def != NULL) { /* Check conflict */ if (act_def->check_conflict != NULL && (ret = act_def->check_conflict( renv, &action, &raction->action)) != 0) return ret; if (oact_new && oact->def->check_conflict != NULL && (ret = oact->def->check_conflict( renv, &raction->action, &action)) != 0) return ret; } } raction = raction->next; } if (kaction != NULL) { /* Use existing keep action to define new one */ raction = kaction; } else { /* Check policy limit on total number of actions */ if (svinst->set->max_actions > 0 && result->action_count >= svinst->set->max_actions) { sieve_runtime_error( renv, action.location, "total number of actions exceeds policy limit " "(%u > %u)", result->action_count+1, svinst->set->max_actions); return -1; } /* Check policy limit on number of this class of actions */ if (instance_limit > 0 && instance_count >= instance_limit) { sieve_runtime_error( renv, action.location, "number of %s actions exceeds policy limit " "(%u > %u)", act_def->name, instance_count+1, instance_limit); return -1; } /* Create new action object */ raction = p_new(result->pool, struct sieve_result_action, 1); raction->seffects = seffects; } raction->action.name = (action.name == NULL ? act_def->name : p_strdup(result->pool, action.name)); raction->action.context = context; raction->action.def = act_def; raction->action.ext = ext; raction->action.location = p_strdup(result->pool, action.location); raction->action.keep = keep; raction->action.exec_seq = result->exec_seq; if (raction->prev == NULL && raction != result->actions_head) { /* Add */ if (result->actions_head == NULL) { result->actions_head = raction; result->actions_tail = raction; raction->prev = NULL; raction->next = NULL; } else { result->actions_tail->next = raction; raction->prev = result->actions_tail; result->actions_tail = raction; raction->next = NULL; } result->action_count++; /* Apply any implicit side effects */ if (hash_table_is_created(result->action_contexts)) { struct sieve_result_action_context *actctx; /* Check for implicit side effects to this particular action */ actctx = hash_table_lookup( result->action_contexts, (keep ? &act_store : act_def)); if (actctx != NULL) { struct sieve_result_side_effect *iseff; /* Iterate through all implicit side effects and add those that are missing. */ iseff = actctx->seffects->first_effect; while (iseff != NULL) { struct sieve_result_side_effect *seff; bool exists = FALSE; /* Scan for presence */ if (seffects != NULL) { seff = seffects->first_effect; while (seff != NULL) { if (seff->seffect.def == iseff->seffect.def) { exists = TRUE; break; } seff = seff->next; } } else { raction->seffects = seffects = sieve_side_effects_list_create(result); } /* If not present, add it */ if (!exists) { sieve_side_effects_list_add(seffects, &iseff->seffect); } iseff = iseff->next; } } } } if (preserve_mail) { raction->action.mail = sieve_message_get_mail(renv->msgctx); sieve_message_snapshot(renv->msgctx); } else { raction->action.mail = NULL; } sieve_result_init_action_event(result, &raction->action, !keep); return 0; } int sieve_result_add_action(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, const char *name, const struct sieve_action_def *act_def, struct sieve_side_effects_list *seffects, void *context, unsigned int instance_limit, bool preserve_mail) { return _sieve_result_add_action(renv, ext, name, act_def, seffects, context, instance_limit, preserve_mail, FALSE); } int sieve_result_add_keep(const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects) { return _sieve_result_add_action(renv, renv->result->keep_action.ext, "keep", renv->result->keep_action.def, seffects, NULL, 0, TRUE, TRUE); } void sieve_result_set_keep_action(struct sieve_result *result, const struct sieve_extension *ext, const struct sieve_action_def *act_def) { result->keep_action.def = act_def; result->keep_action.ext = ext; } void sieve_result_set_failure_action(struct sieve_result *result, const struct sieve_extension *ext, const struct sieve_action_def *act_def) { result->failure_action.def = act_def; result->failure_action.ext = ext; } /* * Result printing */ void sieve_result_vprintf(const struct sieve_result_print_env *penv, const char *fmt, va_list args) { string_t *outbuf = t_str_new(128); str_vprintfa(outbuf, fmt, args); o_stream_nsend(penv->stream, str_data(outbuf), str_len(outbuf)); } void sieve_result_printf(const struct sieve_result_print_env *penv, const char *fmt, ...) { va_list args; va_start(args, fmt); sieve_result_vprintf(penv, fmt, args); va_end(args); } void sieve_result_action_printf(const struct sieve_result_print_env *penv, const char *fmt, ...) { string_t *outbuf = t_str_new(128); va_list args; va_start(args, fmt); str_append(outbuf, " * "); str_vprintfa(outbuf, fmt, args); str_append_c(outbuf, '\n'); va_end(args); o_stream_nsend(penv->stream, str_data(outbuf), str_len(outbuf)); } void sieve_result_seffect_printf(const struct sieve_result_print_env *penv, const char *fmt, ...) { string_t *outbuf = t_str_new(128); va_list args; va_start(args, fmt); str_append(outbuf, " + "); str_vprintfa(outbuf, fmt, args); str_append_c(outbuf, '\n'); va_end(args); o_stream_nsend(penv->stream, str_data(outbuf), str_len(outbuf)); } static void sieve_result_print_side_effects(struct sieve_result_print_env *rpenv, const struct sieve_action *action, struct sieve_side_effects_list *slist, bool *implicit_keep) { struct sieve_result_side_effect *rsef; /* Print side effects */ rsef = (slist != NULL ? slist->first_effect : NULL); while (rsef != NULL) { const struct sieve_side_effect *sef = &rsef->seffect; i_assert(sef->def != NULL); if (sef->def->print != NULL) { sef->def->print(sef, action, rpenv, implicit_keep); } rsef = rsef->next; } } static void sieve_result_print_implicit_side_effects(struct sieve_result_print_env *rpenv) { struct sieve_result *result = rpenv->result; bool dummy = TRUE; /* Print any implicit side effects if applicable */ if (hash_table_is_created(result->action_contexts)) { struct sieve_result_action_context *actctx; /* Check for implicit side effects to keep action */ actctx = hash_table_lookup(rpenv->result->action_contexts, &act_store); if (actctx != NULL && actctx->seffects != NULL) { sieve_result_print_side_effects( rpenv, &result->keep_action, actctx->seffects, &dummy); } } } bool sieve_result_print(struct sieve_result *result, const struct sieve_script_env *senv, struct ostream *stream, bool *keep) { struct sieve_action act_keep = result->keep_action; struct sieve_result_print_env penv; bool implicit_keep = TRUE, printed_any = FALSE; struct sieve_result_action *rac; if (keep != NULL) *keep = FALSE; /* Prepare environment */ penv.result = result; penv.stream = stream; penv.scriptenv = senv; sieve_result_printf(&penv, "\nPerformed actions:\n\n"); rac = result->actions_head; while (rac != NULL) { bool impl_keep = TRUE; const struct sieve_action *act = &rac->action; if (act->exec_seq < result->exec_seq) { rac = rac->next; continue; } if (rac->action.keep && keep != NULL) *keep = TRUE; if (act->def != NULL) { if (act->def->print != NULL) act->def->print(act, &penv, &impl_keep); else { sieve_result_action_printf( &penv, "%s", act->def->name); } } else { if (act->keep) { sieve_result_action_printf(&penv, "keep"); impl_keep = FALSE; } else { sieve_result_action_printf(&penv, "[NULL]"); } } printed_any = TRUE; /* Print side effects */ sieve_result_print_side_effects( &penv, &rac->action, rac->seffects, &impl_keep); implicit_keep = implicit_keep && impl_keep; rac = rac->next; } if (!printed_any) sieve_result_printf(&penv, " (none)\n"); if (implicit_keep && keep != NULL) *keep = TRUE; sieve_result_printf(&penv, "\nImplicit keep:\n\n"); if (implicit_keep) { bool dummy = TRUE; if (act_keep.def == NULL) { sieve_result_action_printf(&penv, "keep"); sieve_result_print_implicit_side_effects(&penv); } else { /* Scan for execution of keep-equal actions */ rac = result->actions_head; while (act_keep.def != NULL && rac != NULL) { if (rac->action.def == act_keep.def && act_keep.def->equals != NULL && act_keep.def->equals(senv, NULL, &rac->action) && sieve_action_is_executed(&rac->action, result)) act_keep.def = NULL; rac = rac->next; } if (act_keep.def == NULL) { sieve_result_printf(&penv, " (none; keep or equivalent action executed earlier)\n"); } else { act_keep.def->print(&act_keep, &penv, &dummy); sieve_result_print_implicit_side_effects(&penv); } } } else { sieve_result_printf(&penv, " (none)\n"); } sieve_result_printf(&penv, "\n"); return TRUE; } /* * Result execution */ struct sieve_side_effect_execution { struct sieve_result_side_effect *seffect; void *tr_context; struct sieve_side_effect_execution *prev, *next; }; struct sieve_action_execution { struct sieve_result_action *action; unsigned int exec_seq; struct sieve_action_execution *prev, *next; struct sieve_side_effect_execution *seffects_head, *seffects_tail; struct sieve_error_handler *ehandler; void *tr_context; enum sieve_action_execution_state state; int status; bool commit:1; }; struct sieve_result_execution { pool_t pool; struct sieve_action_exec_env action_env; struct sieve_error_handler *ehandler; struct event *event; int status; struct sieve_action_execution *actions_head, *actions_tail; struct sieve_result_action keep_action; struct sieve_action_execution keep; struct sieve_action_execution *keep_equiv_action; int keep_status; bool keep_success:1; bool keep_explicit:1; bool keep_implicit:1; bool keep_finalizing:1; bool seen_delivery:1; bool executed:1; bool executed_delivery:1; bool committed:1; }; void sieve_result_mark_executed(struct sieve_result *result) { result->exec_seq++; } /* Side effect */ static int sieve_result_side_effect_pre_execute(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, struct sieve_side_effect_execution *seexec) { struct sieve_result_side_effect *rsef = seexec->seffect; struct sieve_side_effect *sef = &rsef->seffect; i_assert(sef->def != NULL); if (sef->def->pre_execute == NULL) return SIEVE_EXEC_OK; return sef->def->pre_execute(sef, &rexec->action_env, aexec->tr_context, &seexec->tr_context); } static int sieve_result_side_effect_post_execute( struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, struct sieve_side_effect_execution *seexec, bool *impl_keep) { struct sieve_result_side_effect *rsef = seexec->seffect; struct sieve_side_effect *sef = &rsef->seffect; i_assert(sef->def != NULL); if (sef->def->post_execute == NULL) return SIEVE_EXEC_OK; return sef->def->post_execute(sef, &rexec->action_env, aexec->tr_context, seexec->tr_context, impl_keep); } static void sieve_result_side_effect_post_commit(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, struct sieve_side_effect_execution *seexec, int commit_status) { struct sieve_result_side_effect *rsef = seexec->seffect; struct sieve_side_effect *sef = &rsef->seffect; i_assert(sef->def != NULL); if (sef->def->post_commit == NULL) return; sef->def->post_commit(sef, &rexec->action_env, aexec->tr_context, seexec->tr_context, commit_status); } static void sieve_result_side_effect_rollback(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, struct sieve_side_effect_execution *seexec) { struct sieve_result_side_effect *rsef = seexec->seffect; struct sieve_side_effect *sef = &rsef->seffect; i_assert(sef->def != NULL); if (sef->def->rollback == NULL) return; sef->def->rollback(sef, &rexec->action_env, aexec->tr_context, seexec->tr_context, (aexec->status == SIEVE_EXEC_OK)); } static void sieve_action_execution_add_side_effect(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, struct sieve_result_side_effect *seffect) { struct sieve_side_effect_execution *seexec; seexec = aexec->seffects_head; while (seexec != NULL) { if (seexec->seffect == seffect) return; seexec = seexec->next; } seexec = p_new(rexec->pool, struct sieve_side_effect_execution, 1); seexec->seffect = seffect; DLLIST2_APPEND(&aexec->seffects_head, &aexec->seffects_tail, seexec); } static void sieve_action_execution_add_side_effects(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, struct sieve_result_action *rac) { struct sieve_result_side_effect *rsef; rsef = (rac->seffects == NULL ? NULL : rac->seffects->first_effect); while (rsef != NULL) { sieve_action_execution_add_side_effect(rexec, aexec, rsef); rsef = rsef->next; } } /* Action */ static void sieve_action_execution_pre(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec) { if (aexec->ehandler == NULL) aexec->ehandler = rexec->ehandler; rexec->action_env.action = &aexec->action->action; rexec->action_env.event = aexec->action->action.event; rexec->action_env.ehandler = aexec->ehandler; } static void sieve_action_execution_post(struct sieve_result_execution *rexec) { rexec->action_env.action = NULL; rexec->action_env.event = rexec->action_env.result->event; rexec->action_env.ehandler = NULL; } static int sieve_result_action_start(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; int status = SIEVE_EXEC_OK; /* Skip actions that are already started. */ if (aexec->state >= SIEVE_ACTION_EXECUTION_STATE_STARTED) return status; aexec->state = SIEVE_ACTION_EXECUTION_STATE_STARTED; aexec->status = status; /* Skip non-actions (inactive keep). */ if (act->def == NULL) return status; if (act->def->start != NULL) { sieve_action_execution_pre(rexec, aexec); status = act->def->start(&rexec->action_env, &aexec->tr_context); aexec->status = status; sieve_action_execution_post(rexec); } return status; } static int sieve_result_action_execute(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, int start_status) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; struct sieve_side_effect_execution *seexec; int status = start_status; bool impl_keep = TRUE; /* Skip actions that are already executed. */ if (aexec->state >= SIEVE_ACTION_EXECUTION_STATE_EXECUTED) return status; aexec->state = SIEVE_ACTION_EXECUTION_STATE_EXECUTED; /* Record explicit keep when it is not the final implicit keep */ if (act->keep && aexec != &rexec->keep) rexec->keep_explicit = TRUE; /* Skip non-actions (inactive keep) */ if (act->def == NULL) { i_assert(aexec != &rexec->keep); if (act->keep) e_debug(rexec->event, "Executed explicit keep"); return status; } /* Don't execute if others already failed */ if (status != SIEVE_EXEC_OK) return status; if (aexec == &rexec->keep) e_debug(rexec->event, "Executing implicit keep action"); else { e_debug(rexec->event, "Executing %s action%s", sieve_action_name(act), (act->keep ? " (explicit keep)" : "")); } sieve_action_execution_pre(rexec, aexec); /* Execute pre-execute event of side effects */ seexec = aexec->seffects_head; while (status == SIEVE_EXEC_OK && seexec != NULL) { status = sieve_result_side_effect_pre_execute( rexec, aexec, seexec); seexec = seexec->next; } /* Execute the action itself */ if (status == SIEVE_EXEC_OK && act->def != NULL && act->def->execute != NULL) { status = act->def->execute(&rexec->action_env, aexec->tr_context, &impl_keep); if (status == SIEVE_EXEC_OK) rexec->executed = TRUE; } /* Execute post-execute event of side effects */ seexec = aexec->seffects_head; while (status == SIEVE_EXEC_OK && seexec != NULL) { status = sieve_result_side_effect_post_execute( rexec, aexec, seexec, &impl_keep); seexec = seexec->next; } if (aexec == &rexec->keep) { e_debug(rexec->event, "Finished executing implicit keep action (status=%s)", sieve_execution_exitcode_to_str(status)); } else { e_debug(rexec->event, "Finished executing %s action " "(status=%s, keep=%s)", sieve_action_name(act), sieve_execution_exitcode_to_str(status), (act->keep ? "explicit" : (impl_keep && rexec->keep_implicit ? "implicit" : "canceled"))); } if (status == SIEVE_EXEC_OK && act->def != NULL && (act->def->flags & SIEVE_ACTFLAG_TRIES_DELIVER) != 0) rexec->seen_delivery = TRUE; /* Update implicit keep status (but only when we're not running the implicit keep right now). */ if (aexec != &rexec->keep) rexec->keep_implicit = rexec->keep_implicit && impl_keep; sieve_action_execution_post(rexec); aexec->status = status; return status; } static int sieve_result_action_commit(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; struct sieve_side_effect_execution *seexec; int cstatus = SIEVE_EXEC_OK; if (aexec == &rexec->keep) { e_debug(rexec->event, "Commit implicit keep action"); } else { e_debug(rexec->event, "Commit %s action%s", sieve_action_name(act), (act->keep ? " (explicit keep)" : "")); } sieve_action_execution_pre(rexec, aexec); if (act->def->commit != NULL) { cstatus = act->def->commit(&rexec->action_env, aexec->tr_context); if (cstatus == SIEVE_EXEC_OK) rexec->committed = TRUE; } /* Execute post_commit event of side effects */ seexec = aexec->seffects_head; while (seexec != NULL) { sieve_result_side_effect_post_commit( rexec, aexec, seexec, cstatus); seexec = seexec->next; } sieve_action_execution_post(rexec); return cstatus; } static void sieve_result_action_rollback(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; struct sieve_side_effect_execution *seexec; if (aexec == &rexec->keep) { e_debug(rexec->event, "Roll back implicit keep action"); } else { e_debug(rexec->event, "Roll back %s action%s", sieve_action_name(act), (act->keep ? " (explicit keep)" : "")); } sieve_action_execution_pre(rexec, aexec); if (act->def->rollback != NULL) { act->def->rollback(&rexec->action_env, aexec->tr_context, (aexec->status == SIEVE_EXEC_OK)); } /* Rollback side effects */ seexec = aexec->seffects_head; while (seexec != NULL) { sieve_result_side_effect_rollback(rexec, aexec, seexec); seexec = seexec->next; } sieve_action_execution_post(rexec); } static int sieve_result_action_commit_or_rollback(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, int status, int *commit_status) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; const struct sieve_execute_env *exec_env = rexec->action_env.exec_env; /* Skip actions that are already finalized. */ if (aexec->state >= SIEVE_ACTION_EXECUTION_STATE_FINALIZED) return status; aexec->state = SIEVE_ACTION_EXECUTION_STATE_FINALIZED; if (aexec == &rexec->keep) { e_debug(rexec->event, "Finalize implicit keep action" "(status=%s, action_status=%s, commit_status=%s)", sieve_execution_exitcode_to_str(status), sieve_execution_exitcode_to_str(aexec->status), sieve_execution_exitcode_to_str(*commit_status)); } else { e_debug(rexec->event, "Finalize %s action " "(%sstatus=%s, action_status=%s, commit_status=%s, " "pre-commit=%s)", sieve_action_name(act), (act->keep ? "explicit keep, " : ""), sieve_execution_exitcode_to_str(status), sieve_execution_exitcode_to_str(aexec->status), sieve_execution_exitcode_to_str(*commit_status), (aexec->commit ? "yes" : "no")); } /* Skip non-actions (inactive keep) */ if (act->def == NULL) return status; if (aexec->status == SIEVE_EXEC_OK && (status == SIEVE_EXEC_OK || (aexec->commit && *commit_status == SIEVE_EXEC_OK))) { int cstatus = SIEVE_EXEC_OK; cstatus = sieve_result_action_commit(rexec, aexec); if (cstatus != SIEVE_EXEC_OK) { /* This is bad; try to salvage as much as possible */ if (*commit_status == SIEVE_EXEC_OK) { *commit_status = cstatus; if (!rexec->committed || exec_env->exec_status->store_failed) { /* We haven't executed anything yet, or storing mail locally failed; continue as rollback. We generally don't want to fail entirely, e.g. a failed mail forward shouldn't cause duplicate local deliveries. */ status = cstatus; } } } } else { sieve_result_action_rollback(rexec, aexec); } if (act->keep) { if (status == SIEVE_EXEC_FAILURE) status = SIEVE_EXEC_KEEP_FAILED; if (*commit_status == SIEVE_EXEC_FAILURE) *commit_status = SIEVE_EXEC_KEEP_FAILED; } return status; } static void sieve_result_action_finish(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec, int status) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; /* Skip non-actions (inactive keep) */ if (act->def == NULL) return; if (aexec == &rexec->keep) { e_debug(rexec->event, "Finish implicit keep action"); } else { e_debug(rexec->event, "Finish %s action%s", sieve_action_name(act), (act->keep ? " (explicit keep)" : "")); } if (act->def->finish != NULL) { sieve_action_execution_pre(rexec, aexec); act->def->finish(&rexec->action_env, aexec->tr_context, status); sieve_action_execution_post(rexec); } } static void sieve_result_action_abort(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec) { if (aexec->state > SIEVE_ACTION_EXECUTION_STATE_INIT && aexec->state < SIEVE_ACTION_EXECUTION_STATE_FINALIZED) sieve_result_action_rollback(rexec, aexec); DLLIST2_REMOVE(&rexec->actions_head, &rexec->actions_tail, aexec); } static void sieve_action_execution_update(struct sieve_result_execution *rexec, struct sieve_action_execution *aexec) { const struct sieve_action_exec_env *aenv = &rexec->action_env; struct sieve_result *result = aenv->result; struct sieve_result_action *rac; rac = result->actions_head; while (rac != NULL) { if (aexec->action == rac) break; rac = rac->next; } if (rac == NULL) { /* Action was removed; abort it. */ sieve_result_action_abort(rexec, aexec); return; } if (aexec->exec_seq != rac->action.exec_seq) { i_assert(rac->action.keep); /* Recycled keep */ aexec->exec_seq = rac->action.exec_seq; aexec->state = SIEVE_ACTION_EXECUTION_STATE_INIT; } sieve_action_execution_add_side_effects(rexec, aexec, rac); } static void sieve_result_execution_add_action(struct sieve_result_execution *rexec, struct sieve_result_action *rac) { struct sieve_action_execution *aexec; aexec = rexec->actions_head; while (aexec != NULL) { if (aexec->action == rac) return; aexec = aexec->next; } aexec = p_new(rexec->pool, struct sieve_action_execution, 1); aexec->action = rac; aexec->exec_seq = rac->action.exec_seq; aexec->ehandler = rexec->ehandler; DLLIST2_APPEND(&rexec->actions_head, &rexec->actions_tail, aexec); sieve_action_execution_add_side_effects(rexec, aexec, rac); } /* Result */ struct sieve_result_execution * sieve_result_execution_create(struct sieve_result *result, pool_t pool) { struct sieve_result_execution *rexec; pool_ref(pool); rexec = p_new(pool, struct sieve_result_execution, 1); rexec->pool = pool; rexec->event = result->event; rexec->action_env.result = result; rexec->action_env.event = result->event; rexec->action_env.exec_env = result->exec_env; rexec->action_env.msgctx = result->msgctx; rexec->status = SIEVE_EXEC_OK; rexec->keep_success = TRUE; rexec->keep_status = SIEVE_EXEC_OK; rexec->keep_explicit = FALSE; rexec->keep_implicit = TRUE; sieve_result_ref(result); result->exec = rexec; return rexec; } void sieve_result_execution_destroy(struct sieve_result_execution **_rexec) { struct sieve_result_execution *rexec = *_rexec; *_rexec = NULL; if (rexec == NULL) return; rexec->action_env.result->exec = NULL; sieve_result_unref(&rexec->action_env.result); pool_unref(&rexec->pool); } static void sieve_result_implicit_keep_execute(struct sieve_result_execution *rexec) { const struct sieve_action_exec_env *aenv = &rexec->action_env; struct sieve_result *result = aenv->result; const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_action_execution *aexec; int status = SIEVE_EXEC_OK; struct sieve_action_execution *aexec_keep = &rexec->keep; struct sieve_result_action *ract_keep = &rexec->keep_action; struct sieve_action *act_keep = &ract_keep->action; bool success = FALSE; switch (rexec->status) { case SIEVE_EXEC_OK: success = TRUE; break; case SIEVE_EXEC_TEMP_FAILURE: case SIEVE_EXEC_RESOURCE_LIMIT: if (rexec->committed) { e_debug(rexec->event, "Temporary failure occurred (status=%s), " "but other actions were already committed: " "execute failure implicit keep", sieve_execution_exitcode_to_str(rexec->status)); break; } if (rexec->keep_finalizing) break; e_debug(rexec->event, "Skip implicit keep for temporary failure " "(state=execute, status=%s)", sieve_execution_exitcode_to_str(rexec->status)); return; default: break; } if (rexec->keep_equiv_action != NULL) { e_debug(rexec->event, "No implicit keep needed " "(equivalent action already executed)"); return; } rexec->keep.action = &rexec->keep_action; rexec->keep.ehandler = rexec->ehandler; rexec->keep_success = success; rexec->keep_status = status; if ((eenv->flags & SIEVE_EXECUTE_FLAG_DEFER_KEEP) != 0) { e_debug(rexec->event, "Execution of implicit keep is deferred"); return; } if (!success) *act_keep = result->failure_action; else *act_keep = result->keep_action; act_keep->name = "keep"; act_keep->mail = NULL; act_keep->keep = TRUE; /* If keep is a non-action, return right away */ if (act_keep->def == NULL) { e_debug(rexec->event, "Keep is not defined yet"); return; } /* Scan for execution of keep-equal actions */ aexec = rexec->actions_head; while (aexec != NULL) { struct sieve_result_action *rac = aexec->action; if (rac->action.def == act_keep->def && act_keep->def->equals != NULL && act_keep->def->equals(eenv->scriptenv, NULL, &rac->action) && aexec->state >= SIEVE_ACTION_EXECUTION_STATE_EXECUTED) { e_debug(rexec->event, "No implicit keep needed " "(equivalent %s action already executed)", sieve_action_name(&rac->action)); rexec->keep_equiv_action = aexec; return; } aexec = aexec->next; } /* Scan for deferred keep */ aexec = rexec->actions_tail; while (aexec != NULL) { struct sieve_result_action *rac = aexec->action; if (aexec->state < SIEVE_ACTION_EXECUTION_STATE_EXECUTED) { aexec = NULL; break; } if (rac->action.keep && rac->action.def == NULL) break; aexec = aexec->prev; } if (aexec == NULL) { if (success) act_keep->mail = sieve_message_get_mail(aenv->msgctx); } else { e_debug(rexec->event, "Found deferred keep action"); if (success) { act_keep->location = aexec->action->action.location; act_keep->mail = aexec->action->action.mail; ract_keep->seffects = aexec->action->seffects; } aexec->state = SIEVE_ACTION_EXECUTION_STATE_FINALIZED; } if (ract_keep->seffects == NULL) { /* Apply any implicit side effects if applicable */ if (success && hash_table_is_created(result->action_contexts)) { struct sieve_result_action_context *actctx; /* Check for implicit side effects to keep action */ actctx = hash_table_lookup(result->action_contexts, act_keep->def); if (actctx != NULL) ract_keep->seffects = actctx->seffects; } } e_debug(rexec->event, "Execute implicit keep (status=%s)", sieve_execution_exitcode_to_str(rexec->status)); /* Initialize side effects */ sieve_action_execution_add_side_effects(rexec, aexec_keep, ract_keep); /* Initialize keep action event */ sieve_result_init_action_event(result, act_keep, FALSE); /* Start keep action */ status = sieve_result_action_start(rexec, aexec_keep); /* Execute keep action */ if (status == SIEVE_EXEC_OK) status = sieve_result_action_execute(rexec, aexec_keep, status); if (status == SIEVE_EXEC_OK) aexec_keep->commit = TRUE; rexec->executed_delivery = rexec->seen_delivery; rexec->keep_status = status; sieve_action_execution_post(rexec); } static int sieve_result_implicit_keep_finalize(struct sieve_result_execution *rexec) { const struct sieve_action_exec_env *aenv = &rexec->action_env; const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_action_execution *aexec_keep = &rexec->keep; struct sieve_result_action *ract_keep = &rexec->keep_action; struct sieve_action *act_keep = &ract_keep->action; int commit_status = SIEVE_EXEC_OK; bool success = FALSE, temp_failure = FALSE; switch (rexec->status) { case SIEVE_EXEC_OK: success = TRUE; break; case SIEVE_EXEC_TEMP_FAILURE: case SIEVE_EXEC_RESOURCE_LIMIT: if (rexec->committed) { e_debug(rexec->event, "Temporary failure occurred (status=%s), " "but other actions were already committed: " "commit failure implicit keep", sieve_execution_exitcode_to_str(rexec->status)); break; } if (aexec_keep->state != SIEVE_ACTION_EXECUTION_STATE_EXECUTED) { e_debug(rexec->event, "Skip implicit keep for temporary failure " "(state=commit, status=%s)", sieve_execution_exitcode_to_str(rexec->status)); return rexec->status; } /* Roll back for temporary failure when no other action is committed. */ commit_status = rexec->status; temp_failure = TRUE; break; default: break; } if ((eenv->flags & SIEVE_EXECUTE_FLAG_DEFER_KEEP) != 0) { e_debug(rexec->event, "Execution of implicit keep is deferred"); return rexec->keep_status; } rexec->keep_finalizing = TRUE; /* Start keep if necessary */ if (temp_failure) { rexec->keep_status = rexec->status; } else if (act_keep->def == NULL || aexec_keep->state != SIEVE_ACTION_EXECUTION_STATE_EXECUTED) { sieve_result_implicit_keep_execute(rexec); /* Switch to failure keep if necessary. */ } else if (rexec->keep_success && !success){ e_debug(rexec->event, "Switch to failure implicit keep"); /* Failed transaction, rollback success keep action. */ sieve_result_action_rollback(rexec, aexec_keep); event_unref(&act_keep->event); i_zero(aexec_keep); /* Start failure keep action. */ sieve_result_implicit_keep_execute(rexec); } if (act_keep->def == NULL) return rexec->keep_status; if (rexec->keep_equiv_action != NULL) { struct sieve_action_execution *ke_aexec = rexec->keep_equiv_action; i_assert(ke_aexec->state >= SIEVE_ACTION_EXECUTION_STATE_FINALIZED); e_debug(rexec->event, "No implicit keep needed " "(equivalent %s action already finalized)", sieve_action_name(&ke_aexec->action->action)); return ke_aexec->status; } e_debug(rexec->event, "Finalize implicit keep (status=%s)", sieve_execution_exitcode_to_str(rexec->status)); i_assert(aexec_keep->state == SIEVE_ACTION_EXECUTION_STATE_EXECUTED); /* Finalize keep action */ rexec->keep_status = sieve_result_action_commit_or_rollback( rexec, aexec_keep, rexec->keep_status, &commit_status); /* Finish keep action */ sieve_result_action_finish(rexec, aexec_keep, rexec->keep_status); sieve_action_execution_post(rexec); event_unref(&act_keep->event); if (rexec->keep_status == SIEVE_EXEC_FAILURE) rexec->keep_status = SIEVE_EXEC_KEEP_FAILED; return rexec->keep_status; } bool sieve_result_executed(struct sieve_result_execution *rexec) { return rexec->executed; } bool sieve_result_committed(struct sieve_result_execution *rexec) { return rexec->committed; } bool sieve_result_executed_delivery(struct sieve_result_execution *rexec) { return rexec->executed_delivery; } static int sieve_result_transaction_start(struct sieve_result_execution *rexec) { struct sieve_action_execution *aexec; int status = SIEVE_EXEC_OK; e_debug(rexec->event, "Starting execution of actions"); aexec = rexec->actions_head; while (status == SIEVE_EXEC_OK && aexec != NULL) { status = sieve_result_action_start(rexec, aexec); aexec = aexec->next; } sieve_action_execution_post(rexec); return status; } static int sieve_result_transaction_execute(struct sieve_result_execution *rexec, int start_status) { struct sieve_action_execution *aexec; int status = SIEVE_EXEC_OK; e_debug(rexec->event, "Executing actions"); rexec->seen_delivery = FALSE; aexec = rexec->actions_head; while (status == SIEVE_EXEC_OK && aexec != NULL) { status = sieve_result_action_execute(rexec, aexec, start_status); aexec = aexec->next; } sieve_action_execution_post(rexec); if (status == SIEVE_EXEC_OK) { /* Since this execution series is successful so far, mark all actions in it to be committed. */ aexec = rexec->actions_head; while (aexec != NULL) { aexec->commit = TRUE; aexec = aexec->next; } rexec->executed_delivery = rexec->executed_delivery || rexec->seen_delivery; } e_debug(rexec->event, "Finished executing actions " "(status=%s, keep=%s, executed=%s)", sieve_execution_exitcode_to_str(status), (rexec->keep_explicit ? "explicit" : (rexec->keep_implicit ? "implicit" : "none")), (rexec->executed ? "yes" : "no")); return status; } static int sieve_result_transaction_commit_or_rollback( struct sieve_result_execution *rexec, int status) { struct sieve_action_execution *aexec; int commit_status = SIEVE_EXEC_OK; switch (status) { case SIEVE_EXEC_TEMP_FAILURE: /* Roll back all actions */ commit_status = status; break; default: break; } e_debug(rexec->event, "Finalizing actions"); /* First commit/rollback all storage actions */ aexec = rexec->actions_head; while (aexec != NULL) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; if (act->def == NULL || (act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) == 0) { aexec = aexec->next; continue; } status = sieve_result_action_commit_or_rollback( rexec, aexec, status, &commit_status); aexec = aexec->next; } /* Then commit/rollback all other actions */ aexec = rexec->actions_head; while (aexec != NULL) { struct sieve_result_action *rac = aexec->action; struct sieve_action *act = &rac->action; if (act->def != NULL && (act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) != 0) { aexec = aexec->next; continue; } status = sieve_result_action_commit_or_rollback( rexec, aexec, status, &commit_status); aexec = aexec->next; } e_debug(rexec->event, "Finished finalizing actions " "(status=%s, keep=%s, committed=%s)", sieve_execution_exitcode_to_str(status), (rexec->keep_explicit ? "explicit" : (rexec->keep_implicit ? "implicit" : "none")), (rexec->committed ? "yes" : "no")); return commit_status; } static void sieve_result_transaction_finish(struct sieve_result_execution *rexec, int status) { struct sieve_action_execution *aexec; e_debug(rexec->event, "Finishing actions"); aexec = rexec->actions_head; while (aexec != NULL) { sieve_result_action_finish(rexec, aexec, status); aexec = aexec->next; } sieve_action_execution_post(rexec); } static void sieve_result_execute_update_status(struct sieve_result_execution *rexec, int status) { switch (status) { case SIEVE_EXEC_OK: break; case SIEVE_EXEC_TEMP_FAILURE: rexec->status = status; break; case SIEVE_EXEC_BIN_CORRUPT: i_unreached(); case SIEVE_EXEC_FAILURE: case SIEVE_EXEC_KEEP_FAILED: if (rexec->status == SIEVE_EXEC_OK) rexec->status = status; break; case SIEVE_EXEC_RESOURCE_LIMIT: if (rexec->status != SIEVE_EXEC_TEMP_FAILURE) rexec->status = status; break; } } static void sieve_result_execution_update(struct sieve_result_execution *rexec) { const struct sieve_action_exec_env *aenv = &rexec->action_env; struct sieve_result *result = aenv->result; struct sieve_action_execution *aexec; struct sieve_result_action *rac; aexec = rexec->actions_head; while (aexec != NULL) { struct sieve_action_execution *aexec_next = aexec->next; sieve_action_execution_update(rexec, aexec); aexec = aexec_next; } rac = result->actions_head; while (rac != NULL) { sieve_result_execution_add_action(rexec, rac); rac = rac->next; } } int sieve_result_execute(struct sieve_result_execution *rexec, int status, bool commit, struct sieve_error_handler *ehandler, bool *keep_r) { const struct sieve_action_exec_env *aenv = &rexec->action_env; struct sieve_result *result = aenv->result; int result_status, ret; e_debug(rexec->event, "Executing result (status=%s, commit=%s)", sieve_execution_exitcode_to_str(status), (commit ? "yes" : "no")); if (keep_r != NULL) *keep_r = FALSE; sieve_result_mark_executed(result); /* Prepare environment */ rexec->ehandler = ehandler; /* Update actions in execution from result */ sieve_result_execution_update(rexec); /* Transaction start and execute */ if (status != SIEVE_EXEC_OK) { sieve_result_execute_update_status(rexec, status); } else if (rexec->status == SIEVE_EXEC_OK) { /* Transaction start */ status = sieve_result_transaction_start(rexec); /* Transaction execute */ status = sieve_result_transaction_execute(rexec, status); sieve_result_execute_update_status(rexec, status); } if (!commit) { sieve_action_execution_post(rexec); rexec->ehandler = NULL; /* Merge explicit keep status into implicit keep for the next execution round. */ rexec->keep_implicit = (rexec->keep_explicit || rexec->keep_implicit); rexec->keep_explicit = FALSE; e_debug(rexec->event, "Finished executing result " "(no commit, status=%s, keep=%s)", sieve_execution_exitcode_to_str(rexec->status), (rexec->keep_implicit ? "yes" : "no")); if (keep_r != NULL) *keep_r = rexec->keep_implicit; return rexec->status; } /* Execute implicit keep if the transaction failed or when the implicit keep was not canceled during transaction. */ if (rexec->status != SIEVE_EXEC_OK || rexec->keep_implicit) sieve_result_implicit_keep_execute(rexec); /* Transaction commit/rollback */ status = sieve_result_transaction_commit_or_rollback(rexec, status); sieve_result_execute_update_status(rexec, status); /* Commit implicit keep if necessary */ result_status = rexec->status; /* Commit implicit keep if the transaction failed or when the implicit keep was not canceled during transaction. */ if (rexec->status != SIEVE_EXEC_OK || rexec->keep_implicit) { ret = sieve_result_implicit_keep_finalize(rexec); switch (ret) { case SIEVE_EXEC_OK: if (result_status == SIEVE_EXEC_TEMP_FAILURE) result_status = SIEVE_EXEC_FAILURE; break; case SIEVE_EXEC_TEMP_FAILURE: case SIEVE_EXEC_RESOURCE_LIMIT: if (!rexec->committed) { result_status = ret; break; } /* fall through */ default: result_status = SIEVE_EXEC_KEEP_FAILED; } } if (rexec->status == SIEVE_EXEC_OK) rexec->status = result_status; /* Finish execution */ sieve_result_transaction_finish(rexec, rexec->status); sieve_action_execution_post(rexec); rexec->ehandler = NULL; rexec->status = result_status; /* Merge explicit keep status into implicit keep (in this case only for completeness). */ rexec->keep_implicit = (rexec->keep_explicit || rexec->keep_implicit); rexec->keep_explicit = FALSE; e_debug(rexec->event, "Finished executing result " "(final, status=%s, keep=%s)", sieve_execution_exitcode_to_str(result_status), (rexec->keep_implicit ? "yes" : "no")); if (keep_r != NULL) *keep_r = rexec->keep_implicit; return result_status; } /* * Result evaluation */ struct sieve_result_iterate_context { struct sieve_result *result; struct sieve_result_action *current_action; struct sieve_result_action *next_action; }; struct sieve_result_iterate_context * sieve_result_iterate_init(struct sieve_result *result) { struct sieve_result_iterate_context *rictx = t_new(struct sieve_result_iterate_context, 1); rictx->result = result; rictx->current_action = NULL; rictx->next_action = result->actions_head; return rictx; } const struct sieve_action * sieve_result_iterate_next(struct sieve_result_iterate_context *rictx, bool *keep) { struct sieve_result_action *rac; if (rictx == NULL) return NULL; rac = rictx->current_action = rictx->next_action; if (rac != NULL) { rictx->next_action = rac->next; if (keep != NULL) *keep = rac->action.keep; return &rac->action; } return NULL; } void sieve_result_iterate_delete(struct sieve_result_iterate_context *rictx) { struct sieve_result *result; struct sieve_result_action *rac; if (rictx == NULL || rictx->current_action == NULL) return; result = rictx->result; rac = rictx->current_action; /* Delete action */ if (rac->prev == NULL) result->actions_head = rac->next; else rac->prev->next = rac->next; if (rac->next == NULL) result->actions_tail = rac->prev; else rac->next->prev = rac->prev; sieve_result_action_deinit(rac); /* Skip to next action in iteration */ rictx->current_action = NULL; } /* * Side effects list */ struct sieve_side_effects_list * sieve_side_effects_list_create(struct sieve_result *result) { struct sieve_side_effects_list *list = p_new(result->pool, struct sieve_side_effects_list, 1); list->result = result; list->first_effect = NULL; list->last_effect = NULL; return list; } void sieve_side_effects_list_add(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect) { struct sieve_result_side_effect *reffect, *reffect_pos; /* Prevent duplicates */ reffect = list->first_effect; reffect_pos = NULL; while (reffect != NULL) { const struct sieve_side_effect_def *ref_def = reffect->seffect.def; const struct sieve_side_effect_def *sef_def = seffect->def; i_assert(ref_def != NULL); i_assert(sef_def != NULL); if (sef_def == ref_def) { /* already listed */ i_assert(reffect_pos == NULL); return; } if (sef_def->precedence > ref_def->precedence) { /* insert it before this position */ reffect_pos = reffect; } reffect = reffect->next; } /* Create new side effect object */ reffect = p_new(list->result->pool, struct sieve_result_side_effect, 1); reffect->seffect = *seffect; if (reffect_pos != NULL) { /* Insert */ reffect->next = reffect_pos; reffect_pos->prev = reffect; if (list->first_effect == reffect_pos) list->first_effect = reffect; } else { /* Add */ if ( list->first_effect == NULL ) { list->first_effect = reffect; list->last_effect = reffect; reffect->prev = NULL; reffect->next = NULL; } else { list->last_effect->next = reffect; reffect->prev = list->last_effect; list->last_effect = reffect; reffect->next = NULL; } } } /* * Error handling */ #undef sieve_result_error void sieve_result_error(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_logv(aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_global_error void sieve_result_global_error(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_global_logv(eenv->svinst, aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_warning void sieve_result_warning(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_logv(aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_global_warning void sieve_result_global_warning(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_global_logv(eenv->svinst, aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_log void sieve_result_log(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = (HAS_ALL_BITS(eenv->flags, SIEVE_EXECUTE_FLAG_LOG_RESULT) ? LOG_TYPE_INFO : LOG_TYPE_DEBUG), .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_logv(aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_global_log void sieve_result_global_log(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = (HAS_ALL_BITS(eenv->flags, SIEVE_EXECUTE_FLAG_LOG_RESULT) ? LOG_TYPE_INFO : LOG_TYPE_DEBUG), .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_global_logv(eenv->svinst, aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_global_log_error void sieve_result_global_log_error(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_global_info_logv(eenv->svinst, aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_global_log_warning void sieve_result_global_log_warning(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_global_info_logv(eenv->svinst, aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_event_log void sieve_result_event_log(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, struct event *event, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = (HAS_ALL_BITS(eenv->flags, SIEVE_EXECUTE_FLAG_LOG_RESULT) ? LOG_TYPE_INFO : LOG_TYPE_DEBUG), .event = event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); sieve_global_logv(eenv->svinst, aenv->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_result_critical void sieve_result_critical(const struct sieve_action_exec_env *aenv, const char *csrc_filename, unsigned int csrc_linenum, const char *user_prefix, const char *fmt, ...) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .event = aenv->event, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); T_BEGIN { sieve_criticalv(eenv->svinst, aenv->ehandler, ¶ms, user_prefix, fmt, args); } T_END; va_end(args); } #undef sieve_result_mail_error int sieve_result_mail_error(const struct sieve_action_exec_env *aenv, struct mail *mail, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const char *error_msg, *user_prefix; va_list args; error_msg = mailbox_get_last_internal_error(mail->box, NULL); va_start(args, fmt); user_prefix = t_strdup_vprintf(fmt, args); sieve_result_critical(aenv, csrc_filename, csrc_linenum, user_prefix, "%s: %s", user_prefix, error_msg); va_end(args); return SIEVE_EXEC_TEMP_FAILURE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/cmd-require.c0000644000175100001700000000423315100335616024030 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-extensions.h" #include "sieve-validator.h" #include "sieve-generator.h" /* * Require command * * Syntax * Syntax: require */ static bool cmd_require_validate (struct sieve_validator *valdtr, struct sieve_command *cmd); const struct sieve_command_def cmd_require = { .identifier = "require", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_require_validate }; /* * Validation */ static bool cmd_require_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { bool result = TRUE; struct sieve_ast_argument *arg; struct sieve_command *prev = sieve_command_prev(cmd); /* Check valid command placement */ if ( !sieve_command_is_toplevel(cmd) || ( !sieve_command_is_first(cmd) && prev != NULL && !sieve_command_is(prev, cmd_require) ) ) { sieve_command_validate_error(valdtr, cmd, "require commands can only be placed at top level " "at the beginning of the file"); return FALSE; } /* Check argument and load specified extension(s) */ arg = cmd->first_positional; if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { /* Single string */ const struct sieve_extension *ext = sieve_validator_extension_load_by_name (valdtr, cmd, arg, sieve_ast_argument_strc(arg)); if ( ext == NULL ) result = FALSE; } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { /* String list */ struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); while ( stritem != NULL ) { const struct sieve_extension *ext = sieve_validator_extension_load_by_name (valdtr, cmd, stritem, sieve_ast_strlist_strc(stritem)); if ( ext == NULL ) result = FALSE; stritem = sieve_ast_strlist_next(stritem); } } else { /* Something else */ sieve_argument_validate_error(valdtr, arg, "the require command accepts a single string or string list argument, " "but %s was found", sieve_ast_argument_name(arg)); return FALSE; } return result; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-storage-private.h0000644000175100001700000001761215100335616026052 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_STORAGE_PRIVATE_H #define SIEVE_STORAGE_PRIVATE_H #include "sieve.h" #include "sieve-error-private.h" #include "sieve-storage.h" #include "sieve-storage-settings.h" #define MAILBOX_ATTRIBUTE_PREFIX_SIEVE \ MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER"sieve/" #define MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES \ MAILBOX_ATTRIBUTE_PREFIX_SIEVE"files/" #define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT \ MAILBOX_ATTRIBUTE_PREFIX_SIEVE"default" #define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK 'L' #define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT 'S' struct sieve_storage; ARRAY_DEFINE_TYPE(sieve_storage_class, const struct sieve_storage *); struct sieve_storage_vfuncs { struct sieve_storage *(*alloc)(void); void (*destroy)(struct sieve_storage *storage); int (*init)(struct sieve_storage *storage); int (*autodetect)(struct sieve_instance *svinst, struct event *event, const char *cause, const struct sieve_storage_settings *storage_set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r); int (*get_last_change)(struct sieve_storage *storage, time_t *last_change_r); void (*set_modified)(struct sieve_storage *storage, time_t mtime); int (*is_singular)(struct sieve_storage *storage); /* script access */ int (*get_script)(struct sieve_storage *storage, const char *name, struct sieve_script **script_r); /* script sequence */ int (*script_sequence_init)(struct sieve_script_sequence *sseq); int (*script_sequence_next)(struct sieve_script_sequence *sseq, struct sieve_script **script_r); void (*script_sequence_destroy)(struct sieve_script_sequence *sseq); /* active script */ int (*active_script_get_name)(struct sieve_storage *storage, const char **name_r); int (*active_script_open)(struct sieve_storage *storage, struct sieve_script **script_r); int (*deactivate)(struct sieve_storage *storage); int (*active_script_get_last_change)(struct sieve_storage *storage, time_t *last_change_r); /* listing scripts */ int (*list_init)(struct sieve_storage *storage, struct sieve_storage_list_context **lctx_r); const char *(*list_next)(struct sieve_storage_list_context *lctx, bool *active_r); int (*list_deinit)(struct sieve_storage_list_context *lctx); /* saving scripts */ // FIXME: simplify this API; reduce this mostly to a single save function struct sieve_storage_save_context *(*save_alloc)( struct sieve_storage *storage); int (*save_init)(struct sieve_storage_save_context *sctx, const char *scriptname, struct istream *input); int (*save_continue)(struct sieve_storage_save_context *sctx); int (*save_finish)(struct sieve_storage_save_context *sctx); struct sieve_script *(*save_get_tempscript)( struct sieve_storage_save_context *sctx); void (*save_cancel)(struct sieve_storage_save_context *sctx); int (*save_commit)(struct sieve_storage_save_context *sctx); int (*save_as)(struct sieve_storage *storage, struct istream *input, const char *name); int (*save_as_active)(struct sieve_storage *storage, struct istream *input, time_t mtime); /* checking quota */ int (*quota_havespace)(struct sieve_storage *storage, const char *scriptname, size_t size, enum sieve_storage_quota *quota_r, uint64_t *limit_r); }; struct sieve_storage { pool_t pool; unsigned int refcount; struct sieve_instance *svinst; struct event *event; const char *driver_name; unsigned int version; const struct sieve_storage *storage_class; struct sieve_storage_vfuncs v; const char *name; const char *cause; const char *type; const char *script_name; const char *bin_path; uoff_t max_storage; unsigned int max_scripts; char *error; enum sieve_error error_code; struct sieve_storage *default_storage, *default_storage_for; struct mail_namespace *sync_inbox_ns; enum sieve_storage_flags flags; bool allows_synchronization:1; bool is_default:1; }; int sieve_storage_alloc(struct sieve_instance *svinst, struct event *event_parent, const struct sieve_storage *storage_class, const char *cause, const char *script_type, const char *storage_name, const char *script_name, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r); int sieve_storage_alloc_with_settings(struct sieve_instance *svinst, struct event *event_parent, const struct sieve_storage *storage_class, const char *cause, const struct sieve_storage_settings *set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r); /* * Utility */ int sieve_storage_get_full_path(struct sieve_storage *storage, const char *path, const char **path_r); /* * Binary */ int sieve_storage_setup_bin_path(struct sieve_storage *storage, mode_t mode); /* * Comparison */ int sieve_storage_cmp(const struct sieve_storage *storage1, const struct sieve_storage *storage2); unsigned int sieve_storage_hash(const struct sieve_storage *storage); /* * Active script */ int sieve_storage_active_script_is_default(struct sieve_storage *storage); /* * Listing scripts */ struct sieve_storage_list_context { struct sieve_storage *storage; struct sieve_storage *def_storage; bool seen_active:1; // Just present for assertions bool seen_default:1; }; /* * Saving scripts */ struct sieve_storage_save_context { pool_t pool; struct sieve_storage *storage; struct event *event; const char *scriptname, *active_scriptname; struct sieve_script *scriptobject; struct istream *input; time_t mtime; bool failed:1; bool finished:1; }; /* * Storage sequence */ struct sieve_storage_sequence { struct sieve_instance *svinst; struct event *event_parent; char *cause; char *type; const struct sieve_storage_settings *storage_set; const char **storage_names; unsigned int storage_count, storage_index; }; /* * Storage class */ struct sieve_storage_class_registry; void sieve_storages_init(struct sieve_instance *svinst); void sieve_storages_deinit(struct sieve_instance *svinst); void sieve_storage_class_register(struct sieve_instance *svinst, const struct sieve_storage *storage_class); void sieve_storage_class_unregister(struct sieve_instance *svinst, const struct sieve_storage *storage_class); const struct sieve_storage * sieve_storage_class_find(struct sieve_instance *svinst, const char *name); /* * Built-in storage drivers */ /* data (currently only for internal use) */ #define SIEVE_DATA_STORAGE_DRIVER_NAME "data" extern const struct sieve_storage sieve_data_storage; /* file */ #define SIEVE_FILE_STORAGE_DRIVER_NAME "file" extern const struct sieve_storage sieve_file_storage; /* dict */ #define SIEVE_DICT_STORAGE_DRIVER_NAME "dict" extern const struct sieve_storage sieve_dict_storage; /* ldap */ #define SIEVE_LDAP_STORAGE_DRIVER_NAME "ldap" extern const struct sieve_storage sieve_ldap_storage; /* * Error handling */ void sieve_storage_set_internal_error(struct sieve_storage *storage); void sieve_storage_set_not_found_error(struct sieve_storage *storage, const char *name); void sieve_storage_copy_error(struct sieve_storage *storage, const struct sieve_storage *source); /* * Synchronization */ int sieve_storage_sync_init(struct sieve_storage *storage, struct mail_user *user); void sieve_storage_sync_deinit(struct sieve_storage *storage); int sieve_storage_sync_script_save(struct sieve_storage *storage, const char *name); int sieve_storage_sync_script_rename(struct sieve_storage *storage, const char *oldname, const char *newname); int sieve_storage_sync_script_delete(struct sieve_storage *storage, const char *name); int sieve_storage_sync_script_activate(struct sieve_storage *storage); int sieve_storage_sync_deactivate(struct sieve_storage *storage); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-match.h0000644000175100001700000000311215100335616024020 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_MATCH_H #define SIEVE_MATCH_H #include "sieve-common.h" /* * Matching context */ struct sieve_match_context { pool_t pool; const struct sieve_runtime_env *runenv; const struct sieve_match_type *match_type; const struct sieve_comparator *comparator; void *data; int match_status; int exec_status; bool trace:1; }; /* * Matching implementation */ /* Manual value iteration (for when multiple matches are allowed) */ struct sieve_match_context * sieve_match_begin(const struct sieve_runtime_env *renv, const struct sieve_match_type *mcht, const struct sieve_comparator *cmp); int sieve_match_value(struct sieve_match_context *mctx, const char *value, size_t value_size, struct sieve_stringlist *key_list); int sieve_match_end(struct sieve_match_context **mctx, int *exec_status); /* Default matching operation */ int sieve_match(const struct sieve_runtime_env *renv, const struct sieve_match_type *mcht, const struct sieve_comparator *cmp, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list, int *exec_status); /* * Read matching operands */ enum sieve_match_opt_operand { SIEVE_MATCH_OPT_END, SIEVE_MATCH_OPT_COMPARATOR, SIEVE_MATCH_OPT_MATCH_TYPE, SIEVE_MATCH_OPT_LAST }; int sieve_match_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, int *opt_code); int sieve_match_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code, int *exec_status, struct sieve_comparator *cmp, struct sieve_match_type *mcht); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/0000755000175100001700000000000015100335670023111 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/Makefile.am0000644000175100001700000000005215100335616025142 0ustar00buildbotbuildbot00000000000000SUBDIRS = \ data \ file \ dict \ ldap dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/data/0000755000175100001700000000000015100335667024030 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/data/sieve-data-script.c0000644000175100001700000000376015100335616027520 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "strfuncs.h" #include "istream.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-data-storage.h" /* * Script data implementation */ static struct sieve_data_script *sieve_data_script_alloc(void) { struct sieve_data_script *dscript; pool_t pool; pool = pool_alloconly_create("sieve_data_script", 1024); dscript = p_new(pool, struct sieve_data_script, 1); dscript->script = sieve_data_script; dscript->script.pool = pool; return dscript; } struct sieve_script * sieve_data_script_create_from_input(struct sieve_instance *svinst, const char *cause, const char *name, struct istream *input) { struct sieve_storage *storage; struct sieve_data_script *dscript = NULL; int ret; ret = sieve_storage_alloc(svinst, svinst->event, &sieve_data_storage, cause, "data", "data", "data", 0, &storage, NULL, NULL); i_assert(ret >= 0); dscript = sieve_data_script_alloc(); sieve_script_init(&dscript->script, storage, &sieve_data_script, name); dscript->data = input; i_stream_ref(dscript->data); sieve_storage_unref(&storage); dscript->script.open = TRUE; return &dscript->script; } static void sieve_data_script_destroy(struct sieve_script *script) { struct sieve_data_script *dscript = container_of(script, struct sieve_data_script, script); i_stream_unref(&dscript->data); } static int sieve_data_script_get_stream(struct sieve_script *script, struct istream **stream_r) { struct sieve_data_script *dscript = container_of(script, struct sieve_data_script, script); i_stream_ref(dscript->data); i_stream_seek(dscript->data, 0); *stream_r = dscript->data; return 0; } const struct sieve_script sieve_data_script = { .driver_name = SIEVE_DATA_STORAGE_DRIVER_NAME, .v = { .destroy = sieve_data_script_destroy, .get_stream = sieve_data_script_get_stream, }, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/data/sieve-data-storage.c0000644000175100001700000000154315100335616027655 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-data-storage.h" /* * Storage class */ static struct sieve_storage *sieve_data_storage_alloc(void) { struct sieve_data_storage *dstorage; pool_t pool; pool = pool_alloconly_create("sieve_data_storage", 1024); dstorage = p_new(pool, struct sieve_data_storage, 1); dstorage->storage = sieve_data_storage; dstorage->storage.pool = pool; return &dstorage->storage; } static int sieve_data_storage_init(struct sieve_storage *storage ATTR_UNUSED) { return 0; } /* * Driver definition */ const struct sieve_storage sieve_data_storage = { .driver_name = SIEVE_DATA_STORAGE_DRIVER_NAME, .version = 0, .v = { .alloc = sieve_data_storage_alloc, .init = sieve_data_storage_init, }, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/data/Makefile.am0000644000175100001700000000040715100335616026057 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_storage_data.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve libsieve_storage_data_la_SOURCES = \ sieve-data-script.c \ sieve-data-storage.c noinst_HEADERS = \ sieve-data-storage.h dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/data/sieve-data-storage.h0000644000175100001700000000100615100335616027654 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_DATA_STORAGE_H #define SIEVE_DATA_STORAGE_H #include "sieve.h" #include "sieve-script-private.h" #include "sieve-storage-private.h" /* * Storage class */ struct sieve_data_storage { struct sieve_storage storage; }; /* * Script class */ struct sieve_data_script { struct sieve_script script; struct istream *data; }; struct sieve_script * sieve_data_script_create_from_input(struct sieve_instance *svinst, const char *cause, const char *name, struct istream *input); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/data/Makefile.in0000644000175100001700000005406415100335630026074 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/storage/data ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_storage_data_la_LIBADD = am_libsieve_storage_data_la_OBJECTS = sieve-data-script.lo \ sieve-data-storage.lo libsieve_storage_data_la_OBJECTS = \ $(am_libsieve_storage_data_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/sieve-data-script.Plo \ ./$(DEPDIR)/sieve-data-storage.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_storage_data_la_SOURCES) DIST_SOURCES = $(libsieve_storage_data_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_storage_data.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve libsieve_storage_data_la_SOURCES = \ sieve-data-script.c \ sieve-data-storage.c noinst_HEADERS = \ sieve-data-storage.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/storage/data/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/storage/data/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_storage_data.la: $(libsieve_storage_data_la_OBJECTS) $(libsieve_storage_data_la_DEPENDENCIES) $(EXTRA_libsieve_storage_data_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_storage_data_la_OBJECTS) $(libsieve_storage_data_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-data-script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-data-storage.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/sieve-data-script.Plo -rm -f ./$(DEPDIR)/sieve-data-storage.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/sieve-data-script.Plo -rm -f ./$(DEPDIR)/sieve-data-storage.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/Makefile.in0000644000175100001700000005400615100335630025157 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/storage ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = 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 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 distdir-am 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)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in 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_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = \ data \ file \ dict \ ldap all: all-recursive .SUFFIXES: $(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) --foreign src/lib-sieve/storage/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/storage/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 installdirs: installdirs-recursive installdirs-am: 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 clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am 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 mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/0000755000175100001700000000000015100335670024030 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage-settings.c0000644000175100001700000000201315100335616031520 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "sieve-script.h" #include "sieve-file-storage-settings.h" #undef DEF #define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \ "sieve_"#name, name, \ struct sieve_file_storage_settings) static const struct setting_define sieve_file_storage_setting_defines[] = { DEF(STR, script_path), DEF(STR, script_active_path), SETTING_DEFINE_LIST_END, }; static const struct sieve_file_storage_settings sieve_file_storage_default_settings = { .script_path = "", .script_active_path = "", }; const struct setting_parser_info sieve_file_storage_setting_parser_info = { .name = "sieve_file_storage", .defines = sieve_file_storage_setting_defines, .defaults = &sieve_file_storage_default_settings, .struct_size = sizeof(struct sieve_file_storage_settings), .pool_offset1 = 1 + offsetof(struct sieve_file_storage_settings, pool), }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage-active.c0000644000175100001700000002456115100335616031147 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "path-util.h" #include "ioloop.h" #include "hostpid.h" #include "file-copy.h" #include "time-util.h" #include "sieve-file-storage.h" #include /* * Symlink manipulation */ static int sieve_file_storage_active_read_link(struct sieve_file_storage *fstorage, const char **link_r) { struct sieve_storage *storage = &fstorage->storage; const char *error = NULL; int ret; if (fstorage->is_file) { /* The storage is in fact a single script file. There is no concept of an active script in this storage. */ return 0; } ret = t_readlink(fstorage->active_path, link_r, &error); if (ret < 0) { *link_r = NULL; if (errno == EINVAL) { /* Our symlink is no symlink. Report 'no active script'. Activating a script will automatically resolve this, so there is no need to panic on this one. */ if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 && (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0) { e_warning(storage->event, "Active sieve script symlink %s is no symlink.", fstorage->active_path); } return 0; } if (errno == ENOENT) { /* Symlink not found */ return 0; } /* We do need to panic otherwise */ sieve_storage_set_critical(storage, "Performing t_readlink() on active sieve symlink '%s' failed: %s", fstorage->active_path, error); return -1; } /* ret is now assured to be valid, i.e. > 0 */ return 1; } static const char * sieve_file_storage_active_parse_link(struct sieve_file_storage *fstorage, const char *link, const char **scriptname_r) { struct sieve_storage *storage = &fstorage->storage; const char *fname, *scriptname, *scriptpath, *link_dir; /* Split off directory from link path */ fname = strrchr(fstorage->active_path, '/'); if (fname == NULL) link_dir = ""; else link_dir = t_strdup_until(fstorage->active_path, fname+1); /* Split link into path and filename */ fname = strrchr(link, '/'); if (fname != NULL) { scriptpath = t_strdup_until(link, fname+1); fname++; } else { scriptpath = ""; fname = link; } /* Check the script name */ scriptname = sieve_script_file_get_scriptname(fname); /* Warn if link is deemed to be invalid */ if (scriptname == NULL) { e_warning(storage->event, "Active Sieve script symlink %s is broken: " "Invalid scriptname (points to %s).", fstorage->active_path, link); return NULL; } /* Check whether the path is any good */ const char *error = NULL; if (t_normpath_to(scriptpath, link_dir, &scriptpath, &error) < 0) { e_warning(storage->event, "Failed to check active Sieve script symlink %s: " "Failed to normalize path (points to %s): %s", fstorage->active_path, scriptpath, error); return NULL; } if (strcmp(scriptpath, fstorage->path) != 0) { e_warning(storage->event, "Active sieve script symlink %s is broken: " "Invalid/unknown path to storage " "(points to %s, expected %s)", fstorage->active_path, scriptpath, fstorage->path); return NULL; } if (scriptname_r != NULL) *scriptname_r = scriptname; return fname; } int sieve_file_storage_active_replace_link(struct sieve_file_storage *fstorage, const char *link_path) { struct sieve_storage *storage = &fstorage->storage; const char *active_path_new; struct timeval *tv, tv_now; int ret = 0; tv = &ioloop_timeval; for (;;) { /* First the new symlink is created with a different filename */ active_path_new = t_strdup_printf( "%s-new.%s.P%sM%s.%s", fstorage->active_path, dec2str(tv->tv_sec), my_pid, dec2str(tv->tv_usec), my_hostname); ret = symlink(link_path, active_path_new); if (ret < 0) { /* If link exists we try again later */ if (errno == EEXIST) { /* Wait and try again - very unlikely */ sleep(2); tv = &tv_now; i_gettimeofday(&tv_now); continue; } /* Other error, critical */ sieve_storage_set_critical(storage, "Creating symlink() %s to %s failed: %m", active_path_new, link_path); return -1; } /* Link created */ break; } /* Replace the existing link. This activates the new script */ ret = rename(active_path_new, fstorage->active_path); if (ret < 0) { /* Failed; created symlink must be deleted */ i_unlink(active_path_new); sieve_storage_set_critical(storage, "Performing rename() %s to %s failed: %m", active_path_new, fstorage->active_path); return -1; } return 1; } /* * Active script properties */ int sieve_file_storage_active_script_get_file( struct sieve_file_storage *fstorage, const char **file_r) { const char *link, *scriptfile; int ret; *file_r = NULL; /* Read the active link */ ret = sieve_file_storage_active_read_link(fstorage, &link); if (ret <= 0) return ret; /* Parse the link */ scriptfile = sieve_file_storage_active_parse_link(fstorage, link, NULL); if (scriptfile == NULL) { /* Obviously, someone has been playing with our symlink: ignore this situation and report 'no active script'. Activation should fix this situation. */ return 0; } *file_r = scriptfile; return 1; } int sieve_file_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); const char *link; int ret; *name_r = NULL; /* Read the active link */ ret = sieve_file_storage_active_read_link(fstorage, &link); if (ret <= 0) return ret; if (sieve_file_storage_active_parse_link(fstorage, link, name_r) == NULL) { /* Obviously, someone has been playing with our symlink: ignore this situation and report 'no active script'. Activation should fix this situation. */ return 0; } return 1; } /* * Active script */ int sieve_file_storage_active_script_open(struct sieve_storage *storage, struct sieve_script **script_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_script *fscript; const char *scriptfile, *link; int ret; *script_r = NULL; sieve_storage_clear_error(storage); /* Read the active link */ ret = sieve_file_storage_active_read_link(fstorage, &link); if (ret <= 0) { if (ret < 0) return -1; /* Try to open the active_path as a regular file */ if (S_ISDIR(fstorage->st.st_mode)) { ret = sieve_file_script_open_from_path( fstorage, fstorage->active_path, NULL, &fscript); } else { ret = sieve_file_script_open_from_name(fstorage, NULL, &fscript); } if (ret < 0) { if (storage->error_code != SIEVE_ERROR_NOT_FOUND) { sieve_storage_set_critical( storage, "Failed to open active path '%s' as regular file: %s", fstorage->active_path, storage->error); } return -1; } *script_r = &fscript->script; return 0; } /* Parse the link */ scriptfile = sieve_file_storage_active_parse_link(fstorage, link, NULL); if (scriptfile == NULL) { /* Obviously someone has been playing with our symlink, ignore this situation and report 'no active script'. Activation should fix this situation. */ sieve_storage_set_error(storage, SIEVE_ERROR_NOT_FOUND, "Active script is invalid"); return -1; } ret = sieve_file_script_open_from_path( fstorage, fstorage->active_path, sieve_script_file_get_scriptname(scriptfile), &fscript); if (ret < 0 && storage->error_code == SIEVE_ERROR_NOT_FOUND) { e_warning(storage->event, "Active sieve script symlink %s points to non-existent script " "(points to %s).", fstorage->active_path, link); } if (ret < 0) return -1; *script_r = &fscript->script; return 0; } int sieve_file_storage_active_script_get_last_change( struct sieve_storage *storage, time_t *last_change_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct stat st; /* Try direct lstat first */ if (lstat(fstorage->active_path, &st) == 0) { if (!S_ISLNK(st.st_mode)) { *last_change_r = st.st_mtime; return 0; } } /* Check error */ else if (errno != ENOENT) { sieve_storage_set_critical(storage, "lstat(%s) failed: %m", fstorage->active_path); } /* Fall back to statting storage directory */ return sieve_storage_get_last_change(storage, last_change_r); } bool sieve_file_storage_active_rescue_regular( struct sieve_file_storage *fstorage) { struct sieve_storage *storage = &fstorage->storage; struct stat st; /* Stat the file */ if (lstat(fstorage->active_path, &st) != 0) { if (errno != ENOENT) { sieve_storage_set_critical(storage, "Failed to stat active sieve script symlink (%s): %m.", fstorage->active_path); return FALSE; } return TRUE; } if (S_ISLNK(st.st_mode)) { e_debug(storage->event, "Nothing to rescue %s.", fstorage->active_path); return TRUE; /* Nothing to rescue */ } /* Only regular files can be rescued */ if (S_ISREG(st.st_mode)) { const char *dstpath; bool result = TRUE; T_BEGIN { dstpath = t_strconcat( fstorage->path, "/", sieve_script_file_from_name("dovecot.orig"), NULL); if (file_copy(fstorage->active_path, dstpath, TRUE) < 1) { sieve_storage_set_critical(storage, "Active sieve script file '%s' is a regular file " "and copying it to the script storage as '%s' failed. " "This needs to be fixed manually.", fstorage->active_path, dstpath); result = FALSE; } else { e_info(storage->event, "Moved active sieve script file '%s' " "to script storage as '%s'.", fstorage->active_path, dstpath); } } T_END; return result; } sieve_storage_set_critical(storage, "Active sieve script file '%s' is no symlink nor a regular file. " "This needs to be fixed manually.", fstorage->active_path); return FALSE; } int sieve_file_storage_deactivate(struct sieve_storage *storage) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); int ret; if (sieve_file_storage_pre_modify(storage) < 0) return -1; if (!sieve_file_storage_active_rescue_regular(fstorage)) return -1; /* Delete the symlink, so no script is active */ ret = unlink(fstorage->active_path); if (ret < 0) { if (errno != ENOENT) { sieve_storage_set_critical(storage, "Failed to deactivate Sieve: " "unlink(%s) failed: %m", fstorage->active_path); return -1; } else { return 0; } } return 1; } dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage-list.c0000644000175100001700000000662515100335616030650 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "eacces-error.h" #include "sieve-common.h" #include "sieve-script-private.h" #include "sieve-file-storage.h" #include #include struct sieve_file_list_context { struct sieve_storage_list_context context; pool_t pool; const char *active; const char *dir; DIR *dirp; }; int sieve_file_storage_list_init(struct sieve_storage *storage, struct sieve_storage_list_context **lctx_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_list_context *flctx; const char *active = NULL; pool_t pool; DIR *dirp; /* Open the directory */ dirp = opendir(fstorage->path); if (dirp == NULL) { switch (errno) { case ENOENT: sieve_storage_set_error( storage, SIEVE_ERROR_NOT_FOUND, "Script storage not found"); break; case EACCES: sieve_storage_set_error( storage, SIEVE_ERROR_NO_PERMISSION, "Script storage not accessible"); e_error(storage->event, "Failed to list scripts: %s", eacces_error_get("opendir", fstorage->path)); break; default: sieve_storage_set_critical( storage, "Failed to list scripts: " "opendir(%s) failed: %m", fstorage->path); break; } return -1; } T_BEGIN { /* Get the name of the active script */ if (sieve_file_storage_active_script_get_file( fstorage, &active) < 0) { flctx = NULL; } else { pool = pool_alloconly_create("sieve_file_list_context", 1024); flctx = p_new(pool, struct sieve_file_list_context, 1); flctx->pool = pool; flctx->dirp = dirp; flctx->active = (active != NULL ? p_strdup(pool, active) : NULL); } } T_END; if (flctx == NULL) { if (closedir(dirp) < 0) { e_error(storage->event, "closedir(%s) failed: %m", fstorage->path); } return -1; } *lctx_r = &flctx->context; return 0; } const char * sieve_file_storage_list_next(struct sieve_storage_list_context *lctx, bool *active) { struct sieve_file_list_context *flctx = container_of(lctx, struct sieve_file_list_context, context); const struct sieve_file_storage *fstorage = container_of(lctx->storage, struct sieve_file_storage, storage); struct dirent *dp; const char *scriptname; *active = FALSE; for (;;) { if ((dp = readdir(flctx->dirp)) == NULL) return NULL; scriptname = sieve_script_file_get_scriptname(dp->d_name); if (scriptname != NULL) { /* Don't list our active sieve script link if the link resides in the script dir (generally a bad idea). */ i_assert( fstorage->link_path != NULL ); if (*(fstorage->link_path) == '\0' && strcmp(fstorage->active_fname, dp->d_name) == 0) continue; break; } } if (flctx->active != NULL && strcmp(dp->d_name, flctx->active) == 0) { *active = TRUE; flctx->active = NULL; } return scriptname; } int sieve_file_storage_list_deinit(struct sieve_storage_list_context *lctx) { struct sieve_file_list_context *flctx = container_of(lctx, struct sieve_file_list_context, context); const struct sieve_file_storage *fstorage = container_of(lctx->storage, struct sieve_file_storage, storage); if (closedir(flctx->dirp) < 0) { e_error(lctx->storage->event, "closedir(%s) failed: %m", fstorage->path); } pool_unref(&flctx->pool); // FIXME: return error here if something went wrong during listing return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/Makefile.am0000644000175100001700000000100615100335616026061 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_storage_file.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve \ -I$(top_srcdir)/src/lib-sieve/util libsieve_storage_file_la_SOURCES = \ sieve-file-script.c \ sieve-file-script-sequence.c \ sieve-file-storage-settings.c \ sieve-file-storage-active.c \ sieve-file-storage-save.c \ sieve-file-storage-list.c \ sieve-file-storage-quota.c \ sieve-file-storage.c noinst_HEADERS = \ sieve-file-storage-settings.h \ sieve-file-storage.h dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage.c0000644000175100001700000006130515100335616027673 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "path-util.h" #include "home-expand.h" #include "ioloop.h" #include "mkdir-parents.h" #include "eacces-error.h" #include "unlink-old-files.h" #include "settings.h" #include "mail-storage-private.h" #include "sieve.h" #include "sieve-common.h" #include "sieve-error-private.h" #include "sieve-file-storage.h" #include #include #include #include #include #define MAX_DIR_CREATE_MODE 0770 /* * Utility */ const char * sieve_file_storage_path_extend(struct sieve_file_storage *fstorage, const char *filename) { const char *path = fstorage->path; if (path[strlen(path)-1] == '/') return t_strconcat(path, filename, NULL); return t_strconcat(path, "/", filename , NULL); } /* * */ static int sieve_file_storage_stat(struct sieve_file_storage *fstorage, const char *path) { struct sieve_storage *storage = &fstorage->storage; struct stat st; const char *abspath, *error; if (lstat(path, &st) == 0) { fstorage->lnk_st = st; if (!S_ISLNK(st.st_mode) || stat(path, &st) == 0) { fstorage->st = st; return 0; } } switch (errno) { case ENOENT: if (t_abspath(path, &abspath, &error) < 0) { sieve_storage_set_critical( storage, "t_abspath(%s) failed: %s", path, error); break; } e_debug(storage->event, "Storage path '%s' not found", abspath); sieve_storage_set_internal_error(storage); // should be overriden storage->error_code = SIEVE_ERROR_NOT_FOUND; break; case EACCES: sieve_storage_set_critical( storage, "Failed to stat sieve storage path: %s", eacces_error_get("stat", path)); storage->error_code = SIEVE_ERROR_NO_PERMISSION; break; default: sieve_storage_set_critical( storage, "Failed to stat sieve storage path: " "stat(%s) failed: %m", path); break; } return -1; } static const char * sieve_storage_get_relative_link_path(const char *active_path, const char *storage_dir) { const char *link_path, *p; size_t pathlen; /* Determine to what extent the sieve storage and active script paths match up. This enables the managed symlink to be short and the sieve storages can be moved around without trouble (if the active script path is common to the script storage). */ p = strrchr(active_path, '/'); if (p == NULL) { link_path = storage_dir; } else { pathlen = p - active_path; if (strncmp(storage_dir, active_path, pathlen) == 0 && (storage_dir[pathlen] == '/' || storage_dir[pathlen] == '\0')) { if (storage_dir[pathlen] == '\0') link_path = ""; else link_path = storage_dir + pathlen + 1; } else { link_path = storage_dir; } } /* Add trailing '/' when link path is not empty */ pathlen = strlen(link_path); if (pathlen != 0 && link_path[pathlen-1] != '/') return t_strconcat(link_path, "/", NULL); return t_strdup(link_path); } static int mkdir_verify(struct sieve_storage *storage, const char *dir, mode_t mode, gid_t gid, const char *gid_origin) { struct stat st; if (stat(dir, &st) == 0) return 0; if (errno == EACCES) { sieve_storage_set_critical( storage, "mkdir_verify: %s", eacces_error_get("stat", dir)); return -1; } else if (errno != ENOENT) { sieve_storage_set_critical( storage, "mkdir_verify: " "stat(%s) failed: %m", dir); return -1; } if (mkdir_parents_chgrp(dir, mode, gid, gid_origin) == 0) { e_debug(storage->event, "Created storage directory %s", dir); return 0; } switch (errno) { case EEXIST: return 0; case ENOENT: sieve_storage_set_critical(storage, "Storage was deleted while it was being created"); break; case EACCES: sieve_storage_set_critical(storage, "%s", eacces_error_get_creating("mkdir_parents_chgrp", dir)); break; default: sieve_storage_set_critical(storage, "mkdir_parents_chgrp(%s) failed: %m", dir); break; } return -1; } static int check_tmp(struct sieve_storage *storage, const char *path) { struct stat st; /* If tmp/ directory exists, we need to clean it up once in a while */ if (stat(path, &st) < 0) { if (errno == ENOENT) return 0; if (errno == EACCES) { sieve_storage_set_critical(storage, "check_tmp: %s", eacces_error_get("stat", path)); return -1; } sieve_storage_set_critical(storage, "check_tmp: stat(%s) failed: %m", path); return -1; } if (st.st_atime > st.st_ctime + SIEVE_FILE_STORAGE_TMP_DELETE_SECS) { /* The directory should be empty. we won't do anything until ctime changes. */ } else if (st.st_atime < (ioloop_time - SIEVE_FILE_STORAGE_TMP_SCAN_SECS)) { /* Time to scan */ (void)unlink_old_files(path, "", (ioloop_time - SIEVE_FILE_STORAGE_TMP_DELETE_SECS)); } return 1; } static struct sieve_storage *sieve_file_storage_alloc(void) { struct sieve_file_storage *fstorage; pool_t pool; pool = pool_alloconly_create("sieve_file_storage", 2048); fstorage = p_new(pool, struct sieve_file_storage, 1); fstorage->storage = sieve_file_storage; fstorage->storage.pool = pool; return &fstorage->storage; } static int sieve_file_storage_get_full_path(struct sieve_file_storage *fstorage, const char **storage_path) { struct sieve_storage *storage = &fstorage->storage; const char *path = *storage_path; if (sieve_storage_get_full_path(storage, path, storage_path) < 0) { sieve_storage_set_critical( storage, "Sieve storage path '%s' is relative to home directory, " "but home directory is not available.", path); return -1; } return 0; } static int sieve_file_storage_get_full_active_path(struct sieve_file_storage *fstorage, const char **active_path) { struct sieve_storage *storage = &fstorage->storage; const char *path = *active_path; if (sieve_storage_get_full_path(storage, path, active_path) < 0) { sieve_storage_set_critical( storage, "Sieve storage active script path '%s' is relative to home directory, " "but home directory is not available.", path); return -1; } return 0; } static int sieve_file_storage_init_common(struct sieve_file_storage *fstorage, const char *active_path, const char *storage_path, bool exists) { struct sieve_storage *storage = &fstorage->storage; const char *tmp_dir, *link_path, *active_fname, *storage_dir, *error; int ret; i_assert(storage_path != NULL || active_path != NULL); fstorage->prev_mtime = (time_t)-1; /* Get active script path */ if (sieve_file_storage_get_full_active_path(fstorage, &active_path) < 0) return -1; /* Get the filename for the active script link */ active_fname = NULL; if (active_path != NULL && *active_path != '\0') { const char *active_dir; active_fname = strrchr(active_path, '/'); if (active_fname == NULL) { active_fname = active_path; active_dir = ""; } else { active_dir = t_strdup_until(active_path, active_fname); active_fname++; } if (*active_fname == '\0') { /* Link cannot be just a path ending in '/' */ sieve_storage_set_critical( storage, "Path to %sscript must include the filename (path=%s)", (storage_path != NULL ? "active link/" : ""), active_path); return -1; } if (t_realpath(active_dir, &active_dir, &error) < 0) { if (errno != ENOENT) { sieve_storage_set_critical(storage, "Failed to normalize active script directory " "(path=%s): %s", active_dir, error); return -1; } e_debug(storage->event, "Failed to normalize active script directory " "(path=%s): " "Part of the path does not exist (yet)", active_dir); } else { active_path = t_abspath_to(active_fname, active_dir); } e_debug(storage->event, "Using %sSieve script path: %s", (storage_path != NULL ? "active " : ""), active_path); fstorage->active_path = p_strdup(storage->pool, active_path); fstorage->active_fname = p_strdup(storage->pool, active_fname); } /* Determine storage path */ storage_dir = storage_path; if (storage_path != NULL && *storage_path != '\0') { e_debug(storage->event, "Using script storage path: %s", storage_path); fstorage->is_file = FALSE; } else { if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) { sieve_storage_set_critical(storage, "Storage path cannot be empty for write access"); return -1; } storage_path = active_path; fstorage->is_file = TRUE; } i_assert(storage_path != NULL); /* Prepare for write access */ if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) { mode_t dir_create_mode, file_create_mode; gid_t file_create_gid; const char *file_create_gid_origin; /* Use safe permission defaults */ file_create_mode = 0600; dir_create_mode = 0700; file_create_gid = (gid_t)-1; file_create_gid_origin = "defaults"; /* Get actual permissions */ if (exists) { file_create_mode = (fstorage->st.st_mode & 0666) | 0600; dir_create_mode = (fstorage->st.st_mode & 0777) | 0700; file_create_gid_origin = storage_dir; if (!S_ISDIR(fstorage->st.st_mode)) { /* We're getting permissions from a file. Apply +x modes as necessary. */ dir_create_mode = mkdir_get_executable_mode( dir_create_mode); } if (S_ISDIR(fstorage->st.st_mode) && (fstorage->st.st_mode & S_ISGID) != 0) { /* Directory's GID is used automatically for new files */ file_create_gid = (gid_t)-1; } else if (((fstorage->st.st_mode & 0070) >> 3) == (fstorage->st.st_mode & 0007)) { /* Group has same permissions as world, so don't bother changing it */ file_create_gid = (gid_t)-1; } else if (getegid() == fstorage->st.st_gid) { /* Using our own gid, no need to change it */ file_create_gid = (gid_t)-1; } else { file_create_gid = fstorage->st.st_gid; } } e_debug(storage->event, "Using permissions from %s: mode=0%o gid=%ld", file_create_gid_origin, (int)dir_create_mode, file_create_gid == (gid_t)-1 ? -1L : (long)file_create_gid); /* Ensure sieve local directory structure exists (full autocreate): This currently only consists of a ./tmp directory. */ tmp_dir = t_strconcat(storage_path, "/tmp", NULL); /* Try to find and clean up tmp dir */ ret = check_tmp(storage, tmp_dir); if (ret < 0) return -1; /* Auto-create if necessary */ if (ret == 0 && mkdir_verify(storage, tmp_dir, dir_create_mode, file_create_gid, file_create_gid_origin) < 0) return -1; fstorage->dir_create_mode = dir_create_mode; fstorage->file_create_mode = file_create_mode; fstorage->file_create_gid = file_create_gid; } if (!exists && sieve_file_storage_stat(fstorage, storage_path) < 0) return -1; if (!fstorage->is_file) { if (t_realpath(storage_path, &storage_path, &error) < 0) { sieve_storage_set_critical(storage, "Failed to normalize storage path (path=%s): %s", storage_path, error); return -1; } if (active_path != NULL && *active_path != '\0') { /* Get the path to be prefixed to the script name in the symlink pointing to the active script. */ link_path = sieve_storage_get_relative_link_path( fstorage->active_path, storage_path); e_debug(storage->event, "Relative path to sieve storage in active link: %s", link_path); fstorage->link_path = p_strdup(storage->pool, link_path); } } fstorage->path = p_strdup(storage->pool, storage_path); return 0; } static int sieve_file_storage_init_from_settings( struct sieve_file_storage *fstorage, const struct sieve_file_storage_settings *set) { struct sieve_storage *storage = &fstorage->storage; const char *storage_path = set->script_path; const char *active_path = set->script_active_path; bool exists = FALSE; /* Get full storage path */ if (sieve_file_storage_get_full_path(fstorage, &storage_path) < 0) return -1; /* Stat storage directory */ bool is_personal = sieve_storage_is_personal(storage); if (storage_path != NULL && *storage_path != '\0') { if (sieve_file_storage_stat(fstorage, storage_path) < 0) { if (!is_personal || storage->error_code != SIEVE_ERROR_NOT_FOUND) return -1; if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) { /* For backwards compatibility, recognize when storage directory does not exist while active script exists and is a regular file. */ if (active_path == NULL || *active_path == '\0') return -1; if (sieve_file_storage_get_full_active_path( fstorage, &active_path) < 0) return -1; if (sieve_file_storage_stat(fstorage, active_path) < 0) return -1; if (!S_ISREG(fstorage->lnk_st.st_mode)) return -1; e_debug(storage->event, "Sieve storage path '%s' not found, " "but the active script '%s' is a regular file, " "so this is used for backwards compatibility.", storage_path, active_path); storage_path = NULL; } } else { exists = TRUE; if (!S_ISDIR(fstorage->st.st_mode)) { if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) { sieve_storage_set_critical(storage, "Sieve storage path '%s' is not a directory, " "but it is to be opened for write access", storage_path); return -1; } if (active_path != NULL && *active_path != '\0') { e_warning(storage->event, "Explicitly specified active script path '%s' is ignored; " "storage path '%s' is not a directory", active_path, storage_path); } active_path = storage_path; storage_path = NULL; } } } if ((active_path == NULL || *active_path == '\0') && (is_personal || (storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0)) { e_debug(storage->event, "Active script path is unconfigured; " "using default (path=%s)", SIEVE_FILE_DEFAULT_ACTIVE_PATH); active_path = SIEVE_FILE_DEFAULT_ACTIVE_PATH; } return sieve_file_storage_init_common(fstorage, active_path, storage_path, exists); } static int sieve_file_storage_init(struct sieve_storage *storage) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); const struct sieve_file_storage_settings *fstorage_set; const char *error; int ret; if (settings_get(storage->event, &sieve_file_storage_setting_parser_info, 0, &fstorage_set, &error) < 0) { e_error(storage->event, "%s", error); sieve_storage_set_internal_error(storage); return -1; } ret = sieve_file_storage_init_from_settings(fstorage, fstorage_set); settings_free(fstorage_set); if (ret < 0) return -1; return ret; } static int sieve_file_storage_do_autodetect( struct sieve_instance *svinst, struct event *event, const char *cause, const struct sieve_storage_settings *storage_set, const struct sieve_file_storage_settings *fstorage_set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { const char *home = sieve_environment_get_homedir(svinst); int mode = ((flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 ? R_OK|W_OK|X_OK : R_OK|X_OK); const char *storage_path = fstorage_set->script_path; if (storage_path == NULL || *storage_path == '\0') { /* We'll need to figure out the storage location ourself. It's $HOME/sieve or /sieve when (presumed to be) chrooted. */ if (home != NULL && *home != '\0') { /* Use default ~/sieve */ e_debug(event, "Use home (%s)", home); storage_path = t_strconcat(home, "/sieve", NULL); } else { e_debug(event, "HOME is not set"); if (access("/sieve", mode) == 0) { storage_path = "/sieve"; e_debug(event, "Directory '/sieve' exists, " "assuming chroot"); } } } if ((storage_path == NULL || *storage_path == '\0') && (flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) { e_error(event, "Could not find storage root directory for write access; " "path was left unconfigured and autodetection failed"); sieve_error_create_internal(error_code_r, error_r); return -1; } struct sieve_storage *storage; struct sieve_file_storage *fstorage; const char *active_path = NULL; bool exists = FALSE; int ret; ret = sieve_storage_alloc_with_settings(svinst, event, &sieve_file_storage, cause, storage_set, flags, &storage, error_code_r, error_r); if (ret < 0) return -1; event = storage->event; fstorage = container_of(storage, struct sieve_file_storage, storage); /* Determine what we have found so far */ bool tried_active = FALSE; while (!tried_active) { if (storage_path == NULL || *storage_path == '\0') { storage_path = fstorage_set->script_active_path; if (storage_path == NULL || *storage_path == '\0') storage_path = SIEVE_FILE_DEFAULT_ACTIVE_PATH; tried_active = TRUE; } e_debug(event, "Checking storage path %s", storage_path); /* Get full storage path */ if (sieve_file_storage_get_full_path(fstorage, &storage_path) < 0) { *error_code_r = storage->error_code; *error_r = t_strdup(storage->error); sieve_storage_unref(&storage); return -1; } /* Got something: stat it */ ret = sieve_file_storage_stat(fstorage, storage_path); if (ret < 0) { if (storage->error_code != SIEVE_ERROR_NOT_FOUND) { /* Error */ *error_code_r = storage->error_code; *error_r = t_strdup(storage->error); sieve_storage_unref(&storage); return -1; } if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0) break; } if (ret == 0) break; storage_path = NULL; } if (storage_path == NULL || *storage_path == '\0') { sieve_storage_unref(&storage); return 0; } if (storage->error_code != SIEVE_ERROR_NONE) { /* Not found */ } else if (S_ISDIR(fstorage->st.st_mode)) { if (tried_active) { e_error(event, "Active script path '%s' is a directory", storage_path); sieve_error_create_internal(error_code_r, error_r); sieve_storage_unref(&storage); return -1; } /* Success */ exists = TRUE; active_path = fstorage_set->script_active_path; } else if ((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) { exists = TRUE; active_path = storage_path; storage_path = NULL; } if (active_path == NULL || *active_path == '\0') { e_debug(event, "Active script path is unconfigured; " "using default (path=%s)", SIEVE_FILE_DEFAULT_ACTIVE_PATH); active_path = SIEVE_FILE_DEFAULT_ACTIVE_PATH; } if (sieve_file_storage_init_common(fstorage, active_path, storage_path, exists) < 0) { *error_code_r = storage->error_code; *error_r = t_strdup(storage->error); sieve_storage_unref(&storage); return -1; } *storage_r = storage; return 1; } static int sieve_file_storage_autodetect(struct sieve_instance *svinst, struct event *event, const char *cause, const struct sieve_storage_settings *storage_set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { const struct sieve_file_storage_settings *fstorage_set; int ret; if (!sieve_storage_settings_match_script_type( storage_set, SIEVE_STORAGE_TYPE_PERSONAL)) return 0; e_debug(event, "Performing auto-detection"); const char *error; if (settings_get(event, &sieve_file_storage_setting_parser_info, 0, &fstorage_set, &error) < 0) { e_error(event, "%s", error); sieve_error_create_internal(error_code_r, error_r); return -1; } ret = sieve_file_storage_do_autodetect( svinst, event, cause, storage_set, fstorage_set, flags, storage_r, error_code_r, error_r); settings_free(fstorage_set); return ret; } int sieve_file_storage_init_from_path(struct sieve_instance *svinst, const char *cause, const char *script_type, const char *storage_name, const char *path, enum sieve_storage_flags flags, struct sieve_file_storage **fstorage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage *storage; struct sieve_file_storage *fstorage; int ret; i_assert(path != NULL); *fstorage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); ret = sieve_storage_alloc(svinst, svinst->event, &sieve_file_storage, cause, script_type, storage_name, sieve_script_file_get_scriptname(path), flags, &storage, error_code_r, error_r); if (ret < 0) return -1; fstorage = container_of(storage, struct sieve_file_storage, storage); T_BEGIN { ret = sieve_file_storage_init_common(fstorage, path, NULL, FALSE); } T_END; if (ret < 0) { *error_code_r = storage->error_code; *error_r = t_strdup(storage->error); sieve_storage_unref(&storage); return -1; } *fstorage_r = fstorage; return 0; } static int sieve_file_storage_is_singular(struct sieve_storage *storage) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct stat st; if (fstorage->active_path == NULL) return 1; /* Stat the file */ if (lstat(fstorage->active_path, &st) != 0) { if (errno != ENOENT) { sieve_storage_set_critical(storage, "Failed to stat active sieve script symlink (%s): %m.", fstorage->active_path); return -1; } return 0; } if (S_ISLNK(st.st_mode)) return 0; if (!S_ISREG(st.st_mode)) { sieve_storage_set_critical(storage, "Active sieve script file '%s' is no symlink nor a regular file.", fstorage->active_path); return -1; } return 1; } /* * */ static int sieve_file_storage_get_last_change(struct sieve_storage *storage, time_t *last_change_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct stat st; if (fstorage->prev_mtime == (time_t)-1) { /* Get the storage mtime before we modify it ourself */ if (stat(fstorage->path, &st) < 0) { if (errno != ENOENT) { e_error(storage->event, "stat(%s) failed: %m", fstorage->path); return -1; } st.st_mtime = 0; } fstorage->prev_mtime = st.st_mtime; } if (last_change_r != NULL) *last_change_r = fstorage->prev_mtime; return 0; } int sieve_file_storage_pre_modify(struct sieve_storage *storage) { i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); return sieve_storage_get_last_change(storage, NULL); } static void sieve_file_storage_set_modified(struct sieve_storage *storage, time_t mtime) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct utimbuf times; time_t cur_mtime; if (mtime != (time_t)-1) { if (sieve_storage_get_last_change(storage, &cur_mtime) >= 0 && cur_mtime > mtime) return; } else { mtime = ioloop_time; } times.actime = mtime; times.modtime = mtime; if (utime(fstorage->path, ×) < 0) { switch (errno) { case ENOENT: break; case EACCES: e_error(storage->event, "%s", eacces_error_get("utime", fstorage->path)); break; default: e_error(storage->event, "utime(%s) failed: %m", fstorage->path); } } else { fstorage->prev_mtime = mtime; } } /* * Script access */ static int sieve_file_storage_get_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_script *fscript; int ret; T_BEGIN { ret = sieve_file_script_init_from_name(fstorage, name, &fscript); } T_END; if (ret < 0) return -1; i_assert(fscript != NULL); *script_r = &fscript->script; return 0; } /* * Driver definition */ const struct sieve_storage sieve_file_storage = { .driver_name = SIEVE_FILE_STORAGE_DRIVER_NAME, .version = 0, .allows_synchronization = TRUE, .v = { .alloc = sieve_file_storage_alloc, .init = sieve_file_storage_init, .autodetect = sieve_file_storage_autodetect, .get_last_change = sieve_file_storage_get_last_change, .set_modified = sieve_file_storage_set_modified, .is_singular = sieve_file_storage_is_singular, .get_script = sieve_file_storage_get_script, .script_sequence_init = sieve_file_script_sequence_init, .script_sequence_next = sieve_file_script_sequence_next, .script_sequence_destroy = sieve_file_script_sequence_destroy, .active_script_get_name = sieve_file_storage_active_script_get_name, .active_script_open = sieve_file_storage_active_script_open, .deactivate = sieve_file_storage_deactivate, .active_script_get_last_change = sieve_file_storage_active_script_get_last_change, .list_init = sieve_file_storage_list_init, .list_next = sieve_file_storage_list_next, .list_deinit = sieve_file_storage_list_deinit, .save_alloc = sieve_file_storage_save_alloc, .save_init = sieve_file_storage_save_init, .save_continue = sieve_file_storage_save_continue, .save_finish = sieve_file_storage_save_finish, .save_get_tempscript = sieve_file_storage_save_get_tempscript, .save_cancel = sieve_file_storage_save_cancel, .save_commit = sieve_file_storage_save_commit, .save_as = sieve_file_storage_save_as, .save_as_active = sieve_file_storage_save_as_active, .quota_havespace = sieve_file_storage_quota_havespace, }, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/Makefile.in0000644000175100001700000005774015100335630026106 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/storage/file ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_storage_file_la_LIBADD = am_libsieve_storage_file_la_OBJECTS = sieve-file-script.lo \ sieve-file-script-sequence.lo sieve-file-storage-settings.lo \ sieve-file-storage-active.lo sieve-file-storage-save.lo \ sieve-file-storage-list.lo sieve-file-storage-quota.lo \ sieve-file-storage.lo libsieve_storage_file_la_OBJECTS = \ $(am_libsieve_storage_file_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/sieve-file-script-sequence.Plo \ ./$(DEPDIR)/sieve-file-script.Plo \ ./$(DEPDIR)/sieve-file-storage-active.Plo \ ./$(DEPDIR)/sieve-file-storage-list.Plo \ ./$(DEPDIR)/sieve-file-storage-quota.Plo \ ./$(DEPDIR)/sieve-file-storage-save.Plo \ ./$(DEPDIR)/sieve-file-storage-settings.Plo \ ./$(DEPDIR)/sieve-file-storage.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_storage_file_la_SOURCES) DIST_SOURCES = $(libsieve_storage_file_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_storage_file.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve \ -I$(top_srcdir)/src/lib-sieve/util libsieve_storage_file_la_SOURCES = \ sieve-file-script.c \ sieve-file-script-sequence.c \ sieve-file-storage-settings.c \ sieve-file-storage-active.c \ sieve-file-storage-save.c \ sieve-file-storage-list.c \ sieve-file-storage-quota.c \ sieve-file-storage.c noinst_HEADERS = \ sieve-file-storage-settings.h \ sieve-file-storage.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/storage/file/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/storage/file/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_storage_file.la: $(libsieve_storage_file_la_OBJECTS) $(libsieve_storage_file_la_DEPENDENCIES) $(EXTRA_libsieve_storage_file_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_storage_file_la_OBJECTS) $(libsieve_storage_file_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-script-sequence.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-storage-active.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-storage-list.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-storage-quota.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-storage-save.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-storage-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-file-storage.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/sieve-file-script-sequence.Plo -rm -f ./$(DEPDIR)/sieve-file-script.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-active.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-list.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-quota.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-save.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-file-storage.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/sieve-file-script-sequence.Plo -rm -f ./$(DEPDIR)/sieve-file-script.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-active.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-list.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-quota.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-save.Plo -rm -f ./$(DEPDIR)/sieve-file-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-file-storage.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-script.c0000644000175100001700000005700415100335616027534 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mempool.h" #include "str.h" #include "path-util.h" #include "istream.h" #include "time-util.h" #include "eacces-error.h" #include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-script-private.h" #include "sieve-file-storage.h" #include #include #include #include #include /* * Filename to name/name to filename */ const char *sieve_script_file_get_scriptname(const char *filename) { const char *ext; /* Extract the script name */ ext = strrchr(filename, '.'); if (ext == NULL || ext == filename || strcmp(ext, "."SIEVE_SCRIPT_FILEEXT) != 0) return NULL; return t_strdup_until(filename, ext); } bool sieve_script_file_has_extension(const char *filename) { return (sieve_script_file_get_scriptname(filename) != NULL); } const char *sieve_script_file_from_name(const char *name) { return t_strconcat(name, "."SIEVE_SCRIPT_FILEEXT, NULL); } /* * Common error handling */ static void sieve_file_script_handle_error(struct sieve_file_script *fscript, const char *op, const char *path, const char *name) { struct sieve_script *script = &fscript->script; const char *abspath, *error; switch (errno) { case ENOENT: if (t_abspath(path, &abspath, &error) < 0) { sieve_script_set_critical(script, "t_abspath(%s) failed: %s", path, error); break; } e_debug(script->event, "File '%s' not found", abspath); sieve_script_set_not_found_error(script, name); break; case EACCES: sieve_script_set_critical(script, "Failed to %s sieve script: %s", op, eacces_error_get(op, path)); script->storage->error_code = SIEVE_ERROR_NO_PERMISSION; break; default: sieve_script_set_critical( script, "Failed to %s sieve script: %s(%s) failed: %m", op, op, path); break; } } /* * */ static struct sieve_file_script *sieve_file_script_alloc(void) { struct sieve_file_script *fscript; pool_t pool; pool = pool_alloconly_create("sieve_file_script", 2048); fscript = p_new(pool, struct sieve_file_script, 1); fscript->script = sieve_file_script; fscript->script.pool = pool; return fscript; } int sieve_file_script_init_from_filename(struct sieve_file_storage *fstorage, const char *filename, const char *scriptname, struct sieve_file_script **fscript_r) { struct sieve_storage *storage = &fstorage->storage; struct sieve_file_script *fscript = NULL; *fscript_r = NULL; /* Prevent initializing the active script link as a script when it resides in the sieve storage directory. */ if (scriptname != NULL && fstorage->link_path != NULL && *(fstorage->link_path) == '\0') { if (strcmp(filename, fstorage->active_fname) == 0) { sieve_storage_set_error( storage, SIEVE_ERROR_NOT_FOUND, "Script '%s' does not exist.", scriptname); return -1; } } fscript = sieve_file_script_alloc(); sieve_script_init(&fscript->script, storage, &sieve_file_script, scriptname); fscript->filename = p_strdup(fscript->script.pool, filename); event_add_str(fscript->script.event, "sieve_script_file_path", sieve_file_storage_path_extend(fstorage, filename)); *fscript_r = fscript; return 0; } int sieve_file_script_open_from_filename(struct sieve_file_storage *fstorage, const char *filename, const char *scriptname, struct sieve_file_script **fscript_r) { struct sieve_file_script *fscript; *fscript_r = NULL; if (sieve_file_script_init_from_filename(fstorage, filename, scriptname, &fscript) < 0) return -1; if (sieve_script_open(&fscript->script, NULL) < 0) { struct sieve_script *script = &fscript->script; sieve_script_unref(&script); return -1; } *fscript_r = fscript; return 0; } int sieve_file_script_init_from_name(struct sieve_file_storage *fstorage, const char *name, struct sieve_file_script **fscript_r) { struct sieve_storage *storage = &fstorage->storage; struct sieve_file_script *fscript; *fscript_r = NULL; if (name != NULL && S_ISDIR(fstorage->st.st_mode)) { return sieve_file_script_init_from_filename( fstorage, sieve_script_file_from_name(name), name, fscript_r); } fscript = sieve_file_script_alloc(); sieve_script_init(&fscript->script, storage, &sieve_file_script, name); event_add_str(fscript->script.event, "sieve_script_file_path", fstorage->active_path); *fscript_r = fscript; return 0; } int sieve_file_script_open_from_name(struct sieve_file_storage *fstorage, const char *name, struct sieve_file_script **fscript_r) { struct sieve_file_script *fscript; *fscript_r = NULL; if (sieve_file_script_init_from_name(fstorage, name, &fscript) < 0) return -1; if (sieve_script_open(&fscript->script, NULL) < 0) { struct sieve_script *script = &fscript->script; sieve_script_unref(&script); return -1; } *fscript_r = fscript; return 0; } int sieve_file_script_init_from_path(struct sieve_file_storage *fstorage, const char *path, const char *scriptname, struct sieve_file_script **fscript_r) { struct sieve_storage *storage = &fstorage->storage; struct sieve_instance *svinst = storage->svinst; struct sieve_file_storage *fsubstorage; struct sieve_file_script *fscript; struct sieve_storage *substorage; enum sieve_error error_code; const char *error; *fscript_r = NULL; if (sieve_file_storage_init_from_path(svinst, storage->cause, storage->type, storage->name, path, 0, &fsubstorage, &error_code, &error) < 0) { sieve_storage_set_error(storage, error_code, "%s", error); return -1; } substorage = &fsubstorage->storage; fscript = sieve_file_script_alloc(); sieve_script_init(&fscript->script, substorage, &sieve_file_script, scriptname); sieve_storage_unref(&substorage); event_add_str(fscript->script.event, "sieve_script_file_path", fstorage->active_path); *fscript_r = fscript; return 0; } int sieve_file_script_open_from_path(struct sieve_file_storage *fstorage, const char *path, const char *scriptname, struct sieve_file_script **fscript_r) { struct sieve_storage *storage = &fstorage->storage; struct sieve_file_script *fscript; *fscript_r = NULL; if (sieve_file_script_init_from_path(fstorage, path, scriptname, &fscript) < 0) return -1; if (sieve_script_open(&fscript->script, NULL) < 0) { struct sieve_script *script = &fscript->script; sieve_storage_copy_error(storage, script->storage); sieve_script_unref(&script); return -1; } *fscript_r = fscript; return 0; } /* * Open */ static int sieve_file_script_stat(const char *path, struct stat *st, struct stat *lnk_st) { if (lstat(path, st) < 0) return -1; *lnk_st = *st; if (S_ISLNK(st->st_mode) && stat(path, st) < 0) return -1; return 0; } static const char * path_split_filename(const char *path, const char **dir_path_r) { const char *filename; filename = strrchr(path, '/'); if (filename == NULL) { *dir_path_r = ""; filename = path; } else { *dir_path_r = t_strdup_until(path, filename); filename++; } return filename; } static int sieve_file_script_open(struct sieve_script *script) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); struct sieve_storage *storage = script->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); pool_t pool = script->pool; const char *filename, *name, *path; const char *dir_path, *basename, *bin_path, *bin_prefix; struct stat st, lnk_st; bool success = TRUE; int ret = 0; filename = fscript->filename; basename = NULL; name = script->name; st = fstorage->st; lnk_st = fstorage->lnk_st; if (name == NULL && storage->script_name != NULL && *storage->script_name != '\0') name = storage->script_name; T_BEGIN { if (S_ISDIR(st.st_mode)) { /* Storage is a directory */ path = fstorage->path; if ((filename == NULL || *filename == '\0') && name != NULL && *name != '\0') { /* Name is used to find actual filename */ filename = sieve_script_file_from_name(name); basename = name; } if (filename == NULL || *filename == '\0') { sieve_script_set_critical( script, "Sieve script file path '%s' is a directory.", path); success = FALSE; } else { /* Extend storage path with filename */ if (name == NULL) { if (basename == NULL && (basename = sieve_script_file_get_scriptname(filename)) == NULL) basename = filename; name = basename; } else if (basename == NULL) { basename = name; } dir_path = path; path = sieve_file_storage_path_extend(fstorage, filename); ret = sieve_file_script_stat(path, &st, &lnk_st); } } else { /* Storage is a single file */ path = fstorage->active_path; /* Extract filename from path */ filename = path_split_filename(path, &dir_path); basename = sieve_script_file_get_scriptname(filename); if (basename == NULL) basename = filename; if (name == NULL) name = basename; } if (success) { if (ret < 0) { /* Make sure we have a script name for the error */ if (name == NULL) { i_assert(basename != NULL); name = basename; } sieve_file_script_handle_error(fscript, "stat", path, name); success = FALSE; } else if (!S_ISREG(st.st_mode)) { sieve_script_set_critical( script, "Sieve script file '%s' is not a regular file.", path); success = FALSE; } } if (success) { const char *bpath, *bfile, *bprefix; if (storage->bin_path != NULL) { bpath = storage->bin_path; bfile = sieve_binfile_from_name(name); bprefix = name; } else { bpath = dir_path; bfile = sieve_binfile_from_name(basename); bprefix = basename; } if (*bpath == '\0') { bin_path = bfile; bin_prefix = bprefix; } else if (bpath[strlen(bpath)-1] == '/') { bin_path = t_strconcat(bpath, bfile, NULL); bin_prefix = t_strconcat(bpath, bprefix, NULL); } else { bin_path = t_strconcat(bpath, "/", bfile, NULL); bin_prefix = t_strconcat(bpath, "/", bprefix, NULL); } fscript->st = st; fscript->lnk_st = lnk_st; fscript->path = p_strdup(pool, path); fscript->filename = p_strdup(pool, filename); fscript->dir_path = p_strdup(pool, dir_path); fscript->bin_path = p_strdup(pool, bin_path); fscript->bin_prefix = p_strdup(pool, bin_prefix); if (fscript->script.name == NULL) fscript->script.name = p_strdup(pool, basename); event_add_str(script->event, "sieve_script_file_path", fscript->path); } } T_END; return (success ? 0 : -1); } static int sieve_file_script_get_stream(struct sieve_script *script, struct istream **stream_r) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); struct stat st; struct istream *result; int fd; fd = open(fscript->path, O_RDONLY); if (fd < 0) { sieve_file_script_handle_error(fscript, "open", fscript->path, fscript->script.name); return -1; } if (fstat(fd, &st) != 0) { sieve_script_set_critical( script, "Failed to open sieve script: fstat(fd=%s) failed: %m", fscript->path); result = NULL; /* Re-check the file type just to be sure */ } else if (!S_ISREG(st.st_mode)) { sieve_script_set_critical( script, "Sieve script file '%s' is not a regular file", fscript->path); result = NULL; } else { result = i_stream_create_fd_autoclose( &fd, SIEVE_FILE_READ_BLOCK_SIZE); fscript->st = fscript->lnk_st = st; } if (result == NULL) { /* Something went wrong, close the fd */ if (fd >= 0 && close(fd) != 0) { e_error(script->event, "Failed to close sieve script: " "close(fd=%s) failed: %m", fscript->path); } return -1; } *stream_r = result; return 0; } /* * Binary */ static int sieve_file_script_binary_read_metadata(struct sieve_script *script, struct sieve_binary_block *sblock, sieve_size_t *offset) { struct sieve_instance *svinst = script->storage->svinst; struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); string_t *path; /* Open if not open already */ if (sieve_script_open(script, NULL) < 0) return 0; /* Metadata: path */ if (!sieve_binary_read_string(sblock, offset, &path)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid file path", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } i_assert(fscript->path != NULL); if (strcmp(str_c(path), fscript->path) != 0) { e_debug(script->event, "Binary '%s' reports different file path for script '%s' " "('%s' rather than '%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(path), fscript->path); return 0; } const struct stat *sstat, *bstat; bstat = sieve_binary_stat(sbin); if (fscript->st.st_mtime > fscript->lnk_st.st_mtime || (fscript->st.st_mtime == fscript->lnk_st.st_mtime && ST_MTIME_NSEC(fscript->st) >= ST_MTIME_NSEC(fscript->lnk_st))) { sstat = &fscript->st; } else { sstat = &fscript->lnk_st; } if (bstat->st_mtime < sstat->st_mtime || (bstat->st_mtime == sstat->st_mtime && ST_MTIME_NSEC(*bstat) <= ST_MTIME_NSEC(*sstat))) { if (svinst->debug) { e_debug(script->event, "Sieve binary '%s' is not newer " "than the Sieve script '%s' (path=%s, %s.%lu <= %s.%lu)", sieve_binary_path(sbin), sieve_script_label(script), fscript->path, t_strflocaltime("%Y-%m-%d %H:%M:%S", bstat->st_mtime), ST_MTIME_NSEC(*bstat), t_strflocaltime("%Y-%m-%d %H:%M:%S", sstat->st_mtime), ST_MTIME_NSEC(*sstat)); } return 0; } return 1; } static void sieve_file_script_binary_write_metadata(struct sieve_script *script, struct sieve_binary_block *sblock) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); sieve_binary_emit_cstring(sblock, fscript->path); } static bool sieve_file_script_binary_dump_metadata(struct sieve_script *script ATTR_UNUSED, struct sieve_dumptime_env *denv, struct sieve_binary_block *sblock, sieve_size_t *offset) { string_t *path; if (!sieve_binary_read_string(sblock, offset, &path)) return FALSE; sieve_binary_dumpf(denv, "file.path = %s\n", str_c(path)); return TRUE; } static int sieve_file_script_binary_load(struct sieve_script *script, struct sieve_binary **sbin_r) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); return sieve_script_binary_load_default(script, fscript->bin_path, sbin_r); } static int sieve_file_script_binary_save(struct sieve_script *script, struct sieve_binary *sbin, bool update) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); return sieve_script_binary_save_default( script, sbin, fscript->bin_path, update, (fscript->st.st_mode & 0777)); } static const char * sieve_file_script_binary_get_prefix(struct sieve_script *script) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); return fscript->bin_prefix; } /* * Management */ static int sieve_file_storage_script_is_active(struct sieve_script *script) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); struct sieve_file_storage *fstorage = container_of(script->storage, struct sieve_file_storage, storage); const char *afile; int ret = 0; T_BEGIN { ret = sieve_file_storage_active_script_get_file( fstorage, &afile); if (ret > 0) { /* Is the requested script active? */ ret = (strcmp(fscript->filename, afile) == 0 ? 1 : 0); } } T_END; return ret; } static int sieve_file_storage_script_delete(struct sieve_script *script) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); int ret = 0; if (sieve_file_storage_pre_modify(script->storage) < 0) return -1; ret = unlink(fscript->path); if (ret < 0) { if (errno == ENOENT) { sieve_script_set_error(script, SIEVE_ERROR_NOT_FOUND, "Sieve script does not exist."); } else { sieve_script_set_critical( script, "Performing unlink() failed on sieve file '%s': %m", fscript->path); } } return ret; } static int _sieve_file_storage_script_activate(struct sieve_file_script *fscript) { struct sieve_script *script = &fscript->script; struct sieve_storage *storage = script->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct stat st; const char *link_path, *afile; int activated = 0; int ret; /* Find out whether there is an active script, but recreate the symlink either way. This way, any possible error in the symlink resolves automatically. This step is only necessary to provide a proper return value indicating whether the script was already active. */ ret = sieve_file_storage_active_script_get_file(fstorage, &afile); /* Is the requested script already active? */ if (ret <= 0 || strcmp(fscript->filename, afile) != 0) activated = 1; i_assert(fstorage->link_path != NULL); /* Check the scriptfile we are trying to activate */ if (lstat(fscript->path, &st) != 0) { sieve_script_set_critical( script, "Failed to activate Sieve script: lstat(%s) failed: %m.", fscript->path); return -1; } /* Rescue a possible ".dovecot.sieve" regular file remaining from old installations. */ if (!sieve_file_storage_active_rescue_regular(fstorage)) { /* Rescue failed, manual intervention is necessary */ return -1; } /* Just try to create the symlink first */ link_path = t_strconcat(fstorage->link_path, fscript->filename, NULL); ret = symlink(link_path, fstorage->active_path); if (ret < 0) { if (errno == EEXIST) { ret = sieve_file_storage_active_replace_link( fstorage, link_path); if (ret < 0) return ret; } else { /* Other error, critical */ sieve_script_set_critical( script, "Failed to activate Sieve script: " "symlink(%s, %s) failed: %m", link_path, fstorage->active_path); return -1; } } return activated; } static int sieve_file_storage_script_activate(struct sieve_script *script) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); int ret; if (sieve_file_storage_pre_modify(script->storage) < 0) return -1; T_BEGIN { ret = _sieve_file_storage_script_activate(fscript); } T_END; return ret; } static int sieve_file_storage_script_rename(struct sieve_script *script, const char *newname) { struct sieve_file_script *fscript = container_of(script, struct sieve_file_script, script); struct sieve_storage *storage = script->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); const char *newpath, *newfile, *link_path; int ret = 0; if (sieve_file_storage_pre_modify(storage) < 0) return -1; T_BEGIN { newfile = sieve_script_file_from_name(newname); newpath = t_strconcat(fstorage->path, "/", newfile, NULL); /* The normal rename() system call overwrites the existing file without notice. Also, active scripts must not be disrupted by renaming a script. That is why we use a link(newpath) [activate newpath] unlink(oldpath) */ /* Link to the new path */ ret = link(fscript->path, newpath); if (ret >= 0) { /* Is the requested script active? */ if (sieve_script_is_active(script) > 0) { /* Active; make active link point to the new copy */ i_assert(fstorage->link_path != NULL); link_path = t_strconcat(fstorage->link_path, newfile, NULL); ret = sieve_file_storage_active_replace_link( fstorage, link_path); } if (ret >= 0) { /* If all is good, remove the old link */ if (unlink(fscript->path) < 0) { e_error(script->event, "Failed to clean up after rename: " "unlink(%s) failed: %m", fscript->path); } if (script->name != NULL && *script->name != '\0') script->name = p_strdup(script->pool, newname); fscript->path = p_strdup(script->pool, newpath); fscript->filename = p_strdup(script->pool, newfile); } else { /* If something went wrong, remove the new link to restore previous state */ if (unlink(newpath) < 0) { e_error(script->event, "Failed to clean up after failed rename: " "unlink(%s) failed: %m", newpath); } } } else { /* Our efforts failed right away */ switch (errno) { case ENOENT: sieve_script_set_error( script, SIEVE_ERROR_NOT_FOUND, "Sieve script does not exist."); break; case EEXIST: sieve_script_set_error( script, SIEVE_ERROR_EXISTS, "A sieve script with that name already exists."); break; default: sieve_script_set_critical( script, "Failed to rename Sieve script: " "link(%s, %s) failed: %m", fscript->path, newpath); } } } T_END; return ret; } /* * Properties */ static int sieve_file_script_get_size(const struct sieve_script *script, uoff_t *size_r) { const struct sieve_file_script *fscript = container_of(script, const struct sieve_file_script, script); *size_r = fscript->st.st_size; return 1; } const char *sieve_file_script_get_dir_path(const struct sieve_script *script) { const struct sieve_file_script *fscript = container_of(script, const struct sieve_file_script, script); if (script->driver_name != sieve_file_script.driver_name) return NULL; return fscript->dir_path; } const char *sieve_file_script_get_path(const struct sieve_script *script) { const struct sieve_file_script *fscript = container_of(script, const struct sieve_file_script, script); if (script->driver_name != sieve_file_script.driver_name) return NULL; return fscript->path; } /* * Matching */ static int sieve_file_script_cmp(const struct sieve_script *script1, const struct sieve_script *script2) { const struct sieve_file_script *fscript1 = container_of(script1, const struct sieve_file_script, script); const struct sieve_file_script *fscript2 = container_of(script2, const struct sieve_file_script, script); int ret; if (!script1->open || !script2->open) { ret = sieve_storage_cmp(script1->storage, script2->storage); if (ret != 0) return ret; return null_strcmp(script1->name, script2->name); } if (major(fscript1->st.st_dev) != major(fscript2->st.st_dev)) { return (major(fscript1->st.st_dev) > major(fscript2->st.st_dev) ? 1 : -1); } if (minor(fscript1->st.st_dev) != minor(fscript2->st.st_dev)) { return (minor(fscript1->st.st_dev) > minor(fscript2->st.st_dev) ? 1 : -1); } if (fscript1->st.st_ino != fscript2->st.st_ino) return (fscript1->st.st_ino > fscript2->st.st_ino ? 1 : -1); return 0; } /* * Driver definition */ const struct sieve_script sieve_file_script = { .driver_name = SIEVE_FILE_STORAGE_DRIVER_NAME, .v = { .open = sieve_file_script_open, .get_stream = sieve_file_script_get_stream, .binary_read_metadata = sieve_file_script_binary_read_metadata, .binary_write_metadata = sieve_file_script_binary_write_metadata, .binary_dump_metadata = sieve_file_script_binary_dump_metadata, .binary_load = sieve_file_script_binary_load, .binary_save = sieve_file_script_binary_save, .binary_get_prefix = sieve_file_script_binary_get_prefix, .rename = sieve_file_storage_script_rename, .delete = sieve_file_storage_script_delete, .is_active = sieve_file_storage_script_is_active, .activate = sieve_file_storage_script_activate, .get_size = sieve_file_script_get_size, .cmp = sieve_file_script_cmp, } }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage-quota.c0000644000175100001700000000517615100335616031026 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve.h" #include "sieve-script.h" #include "sieve-file-storage.h" #include #include #include #include int sieve_file_storage_quota_havespace(struct sieve_storage *storage, const char *scriptname, size_t size, enum sieve_storage_quota *quota_r, uint64_t *limit_r) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct dirent *dp; DIR *dirp; uint64_t script_count = 1; uint64_t script_storage = size; int result = 1; /* Open the directory */ dirp = opendir(fstorage->path); if (dirp == NULL) { sieve_storage_set_critical( storage, "quota: opendir(%s) failed: %m", fstorage->path); return -1; } /* Scan all files */ for (;;) { const char *name; bool replaced = FALSE; /* Read next entry */ errno = 0; dp = readdir(dirp); if (dp == NULL) { if (errno != 0) { sieve_storage_set_critical( storage, "quota: readdir(%s) failed: %m", fstorage->path); result = -1; } break; } /* Parse filename */ name = sieve_script_file_get_scriptname(dp->d_name); /* Ignore non-script files */ if (name == NULL) continue; /* Don't list our active sieve script link if the link resides in the script dir (generally a bad idea). */ i_assert( fstorage->link_path != NULL ); if (*(fstorage->link_path) == '\0' && strcmp(fstorage->active_fname, dp->d_name) == 0) continue; if (strcmp(name, scriptname) == 0) replaced = TRUE; /* Check count quota if necessary */ if (storage->max_scripts > 0) { if (!replaced) { script_count++; if (script_count > storage->max_scripts) { *quota_r = SIEVE_STORAGE_QUOTA_MAXSCRIPTS; *limit_r = storage->max_scripts; result = 0; break; } } } /* Check storage quota if necessary */ if (storage->max_storage > 0) { const char *path; struct stat st; path = t_strconcat(fstorage->path, "/", dp->d_name, NULL); if (stat(path, &st) < 0) { e_warning(storage->event, "quota: stat(%s) failed: %m", path); continue; } if (!replaced) { script_storage += st.st_size; if (script_storage > storage->max_storage) { *quota_r = SIEVE_STORAGE_QUOTA_MAXSTORAGE; *limit_r = storage->max_storage; result = 0; break; } } } } /* Close directory */ if (closedir(dirp) < 0) { sieve_storage_set_critical(storage, "quota: closedir(%s) failed: %m", fstorage->path); } return result; } dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-script-sequence.c0000644000175100001700000001341415100335616031337 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "array.h" #include "eacces-error.h" #include "sieve-common.h" #include "sieve-script-private.h" #include "sieve-file-storage.h" #include #include /* * Script sequence */ struct sieve_file_script_sequence { pool_t pool; ARRAY_TYPE(const_string) script_files; unsigned int index; bool storage_is_file:1; }; static int sieve_file_script_sequence_read_dir(struct sieve_script_sequence *sseq, struct sieve_file_script_sequence *fseq, const char *path) { struct sieve_storage *storage = sseq->storage; DIR *dirp; int ret = 0; /* Open the directory */ dirp = opendir(path); if (dirp == NULL) { switch (errno) { case ENOENT: sieve_storage_set_error( storage, SIEVE_ERROR_NOT_FOUND, "Script sequence location not found"); break; case EACCES: sieve_storage_set_error( storage, SIEVE_ERROR_NO_PERMISSION, "Script sequence location not accessible"); e_error(storage->event, "Failed to open sieve sequence: %s", eacces_error_get("stat", path)); break; default: sieve_storage_set_critical( storage, "Failed to open sieve sequence: " "opendir(%s) failed: %m", path); break; } return -1; } /* Read and sort script files */ for (;;) { const char *const *files; unsigned int count, i; const char *file; struct dirent *dp; struct stat st; errno = 0; dp = readdir(dirp); if (dp == NULL) break; if (!sieve_script_file_has_extension(dp->d_name)) continue; file = NULL; T_BEGIN { if (path[strlen(path)-1] == '/') file = t_strconcat(path, dp->d_name, NULL); else file = t_strconcat(path, "/", dp->d_name, NULL); if (stat(file, &st) == 0 && S_ISREG(st.st_mode)) file = p_strdup(fseq->pool, dp->d_name); else file = NULL; } T_END; if (file == NULL) continue; /* Insert into sorted array */ files = array_get(&fseq->script_files, &count); for (i = 0; i < count; i++) { if (strcmp(file, files[i]) < 0) break; } if (i == count) array_append(&fseq->script_files, &file, 1); else array_insert(&fseq->script_files, i, &file, 1); } if (errno != 0) { sieve_storage_set_critical( storage, "Failed to read sequence directory: " "readdir(%s) failed: %m", path); ret = -1; } /* Close the directory */ if (dirp != NULL && closedir(dirp) < 0) { e_error(storage->event, "Failed to close sequence directory: " "closedir(%s) failed: %m", path); } return ret; } int sieve_file_script_sequence_init(struct sieve_script_sequence *sseq) { struct sieve_storage *storage = sseq->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_script_sequence *fseq = NULL; const char *name = storage->script_name; const char *file; pool_t pool; struct stat st; /* Specified path can either be a regular file or a directory */ if (stat(fstorage->path, &st) != 0) { switch (errno) { case ENOENT: sieve_storage_set_error( storage, SIEVE_ERROR_NOT_FOUND, "Script sequence location not found"); break; case EACCES: sieve_storage_set_error( storage, SIEVE_ERROR_NO_PERMISSION, "Script sequence location not accessible"); e_error(storage->event, "Failed to open sieve sequence: %s", eacces_error_get("stat", fstorage->path)); break; default: sieve_storage_set_critical( storage, "Failed to open sieve sequence: " "stat(%s) failed: %m", fstorage->path); break; } return -1; } /* Create sequence object */ pool = pool_alloconly_create("sieve_file_script_sequence", 1024); fseq = p_new(pool, struct sieve_file_script_sequence, 1); fseq->pool = pool; sseq->storage_data = fseq; if (S_ISDIR(st.st_mode)) { i_array_init(&fseq->script_files, 16); /* Path is directory */ if (name == 0 || *name == '\0') { /* Read all '.sieve' files in directory */ if (sieve_file_script_sequence_read_dir( sseq, fseq, fstorage->path) < 0) { pool_unref(&fseq->pool); return -1; } } else { /* Read specific script file */ file = sieve_script_file_from_name(name); file = p_strdup(pool, file); array_append(&fseq->script_files, &file, 1); } } else { /* Path is a file (apparently; we'll see about that once it is opened) */ fseq->storage_is_file = TRUE; } return 0; } int sieve_file_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r) { struct sieve_file_script_sequence *fseq = sseq->storage_data; struct sieve_storage *storage = sseq->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_script *fscript = NULL; const char *const *files; unsigned int count; int ret; if (fseq->storage_is_file) { i_assert(fseq->index <= 1); if (fseq->index++ > 0) return 0; ret = sieve_file_script_open_from_name(fstorage, NULL, &fscript); } else { files = array_get(&fseq->script_files, &count); i_assert(fseq->index <= count); if (fseq->index == count) return 0; for (;;) { ret = sieve_file_script_open_from_filename( fstorage, files[fseq->index++], NULL, &fscript); if (ret == 0) break; if (storage->error_code != SIEVE_ERROR_NOT_FOUND) break; sieve_storage_clear_error(storage); if (fseq->index >= count) return 0; } } if (ret < 0) { if (storage->error_code == SIEVE_ERROR_NOT_FOUND) return 0; return -1; } *script_r = &fscript->script; return 1; } void sieve_file_script_sequence_destroy(struct sieve_script_sequence *sseq) { struct sieve_file_script_sequence *fseq = sseq->storage_data; if (array_is_created(&fseq->script_files)) array_free(&fseq->script_files); pool_unref(&fseq->pool); } dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage.h0000644000175100001700000001317115100335616027676 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_FILE_STORAGE_H #define SIEVE_FILE_STORAGE_H #include "lib.h" #include "mail-user.h" #include "sieve.h" #include "sieve-script-private.h" #include "sieve-storage-private.h" #include "sieve-file-storage-settings.h" #include #include #define SIEVE_FILE_READ_BLOCK_SIZE (1024*8) /* How often to scan tmp/ directory for old files (based on dir's atime) */ #define SIEVE_FILE_STORAGE_TMP_SCAN_SECS (8*60*60) /* Delete files having ctime older than this from tmp/. 36h is standard. */ #define SIEVE_FILE_STORAGE_TMP_DELETE_SECS (36*60*60) /* * Storage class */ struct sieve_file_storage { struct sieve_storage storage; const char *path; const char *active_path; const char *active_fname; const char *link_path; struct stat st; struct stat lnk_st; mode_t dir_create_mode; mode_t file_create_mode; gid_t file_create_gid; time_t prev_mtime; bool is_file:1; }; const char * sieve_file_storage_path_extend(struct sieve_file_storage *fstorage, const char *filename); int sieve_file_storage_init_from_path(struct sieve_instance *svinst, const char *cause, const char *script_type, const char *storage_name, const char *path, enum sieve_storage_flags flags, struct sieve_file_storage **fstorage_r, enum sieve_error *error_code_r, const char **error_r); int sieve_file_storage_pre_modify(struct sieve_storage *storage); /* Active script */ int sieve_file_storage_active_replace_link(struct sieve_file_storage *fstorage, const char *link_path); bool sieve_file_storage_active_rescue_regular( struct sieve_file_storage *fstorage); int sieve_file_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r); int sieve_file_storage_active_script_open(struct sieve_storage *storage, struct sieve_script **script_r); int sieve_file_storage_active_script_get_file( struct sieve_file_storage *fstorage, const char **file_r); int sieve_file_storage_active_script_is_no_link( struct sieve_file_storage *fstorage); int sieve_file_storage_deactivate(struct sieve_storage *storage); int sieve_file_storage_active_script_get_last_change( struct sieve_storage *storage, time_t *last_change_r); /* Listing */ int sieve_file_storage_list_init(struct sieve_storage *storage, struct sieve_storage_list_context **lctx_r); const char * sieve_file_storage_list_next(struct sieve_storage_list_context *lctx, bool *active); int sieve_file_storage_list_deinit(struct sieve_storage_list_context *lctx); /* Saving */ struct sieve_storage_save_context * sieve_file_storage_save_alloc(struct sieve_storage *storage); int sieve_file_storage_save_init(struct sieve_storage_save_context *sctx, const char *scriptname, struct istream *input); int sieve_file_storage_save_continue(struct sieve_storage_save_context *sctx); int sieve_file_storage_save_finish(struct sieve_storage_save_context *sctx); struct sieve_script * sieve_file_storage_save_get_tempscript(struct sieve_storage_save_context *sctx); int sieve_file_storage_save_commit(struct sieve_storage_save_context *sctx); void sieve_file_storage_save_cancel(struct sieve_storage_save_context *sctx); int sieve_file_storage_save_as(struct sieve_storage *storage, struct istream *input, const char *name); int sieve_file_storage_save_as_active(struct sieve_storage *storage, struct istream *input, time_t mtime); /* Quota */ int sieve_file_storage_quota_havespace(struct sieve_storage *storage, const char *scriptname, size_t size, enum sieve_storage_quota *quota_r, uint64_t *limit_r); /* * Sieve script filenames */ const char *sieve_script_file_get_scriptname(const char *filename); const char *sieve_script_file_from_name(const char *name); /* * Script class */ struct sieve_file_script { struct sieve_script script; struct stat st; struct stat lnk_st; const char *path; const char *dir_path; const char *filename; const char *bin_path; const char *bin_prefix; time_t prev_mtime; }; int sieve_file_script_init_from_filename(struct sieve_file_storage *fstorage, const char *filename, const char *scriptname, struct sieve_file_script **fscript_r); int sieve_file_script_open_from_filename(struct sieve_file_storage *fstorage, const char *filename, const char *scriptname, struct sieve_file_script **fscript_r); int sieve_file_script_init_from_name(struct sieve_file_storage *fstorage, const char *name, struct sieve_file_script **fscript_r); int sieve_file_script_open_from_name(struct sieve_file_storage *fstorage, const char *name, struct sieve_file_script **fscript_r); int sieve_file_script_init_from_path(struct sieve_file_storage *fstorage, const char *path, const char *scriptname, struct sieve_file_script **fscript_r); int sieve_file_script_open_from_path(struct sieve_file_storage *fstorage, const char *path, const char *scriptname, struct sieve_file_script **fscript_r); /* Return directory where script resides in. Returns NULL if this is not a file script. */ const char *sieve_file_script_get_dir_path(const struct sieve_script *script); /* Return full path to file script. Returns NULL if this is not a file script. */ const char *sieve_file_script_get_path(const struct sieve_script *script); /* * Script sequence */ int sieve_file_script_sequence_init(struct sieve_script_sequence *sseq); int sieve_file_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r); void sieve_file_script_sequence_destroy(struct sieve_script_sequence *sseq); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage-save.c0000644000175100001700000003434515100335616030633 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "hostpid.h" #include "ioloop.h" #include "array.h" #include "buffer.h" #include "istream.h" #include "ostream.h" #include "str.h" #include "eacces-error.h" #include "safe-mkstemp.h" #include "sieve-file-storage.h" #include #include #include #include struct sieve_file_save_context { struct sieve_storage_save_context context; pool_t pool; struct ostream *output; int fd; const char *tmp_path; time_t mtime; bool failed:1; bool finished:1; }; static const char *sieve_generate_tmp_filename(const char *scriptname) { static struct timeval last_tv = { 0, 0 }; struct timeval tv; /* use secs + usecs to guarantee uniqueness within this process. */ if (ioloop_timeval.tv_sec > last_tv.tv_sec || (ioloop_timeval.tv_sec == last_tv.tv_sec && ioloop_timeval.tv_usec > last_tv.tv_usec)) { tv = ioloop_timeval; } else { tv = last_tv; if (++tv.tv_usec == 1000000) { tv.tv_sec++; tv.tv_usec = 0; } } last_tv = tv; if (scriptname == NULL) { return t_strdup_printf("%s.M%sP%s.%s.tmp", dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); } scriptname = t_strdup_printf("%s_%s.M%sP%s.%s", scriptname, dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); return sieve_script_file_from_name(scriptname); } static int sieve_file_storage_create_tmp(struct sieve_file_storage *fstorage, const char *scriptname, const char **fpath_r) { struct sieve_storage *storage = &fstorage->storage; struct stat st; unsigned int prefix_len; const char *tmp_fname = NULL; string_t *path; int fd; path = t_str_new(256); str_append(path, fstorage->path); str_append(path, "/tmp/"); prefix_len = str_len(path); for (;;) { tmp_fname = sieve_generate_tmp_filename(scriptname); str_truncate(path, prefix_len); str_append(path, tmp_fname); /* stat() first to see if it exists. pretty much the only possibility of that happening is if time had moved backwards, but even then it's highly unlikely. */ if (stat(str_c(path), &st) == 0) { /* try another file name */ } else if (errno != ENOENT) { switch (errno) { case EACCES: sieve_storage_set_critical( storage, "save: %s", eacces_error_get("stat", fstorage->path)); break; default: sieve_storage_set_critical( storage, "save: " "stat(%s) failed: %m", str_c(path)); break; } return -1; } else { /* Doesn't exist */ mode_t old_mask = umask(0777 & ~(fstorage->file_create_mode)); fd = open(str_c(path), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0777); umask(old_mask); if (fd != -1 || errno != EEXIST) break; /* Race condition between stat() and open(). highly unlikely. */ } } *fpath_r = str_c(path); if (fd == -1) { if (ENOQUOTA(errno)) { sieve_storage_set_error(storage, SIEVE_ERROR_NO_QUOTA, "Not enough disk quota"); } else { switch (errno) { case EACCES: sieve_storage_set_critical( storage, "save: %s", eacces_error_get("open", fstorage->path)); break; default: sieve_storage_set_critical( storage, "save: open(%s) failed: %m", str_c(path)); break; } } } return fd; } static int sieve_file_storage_script_move(struct sieve_file_save_context *fsctx, const char *dst) { struct sieve_storage_save_context *sctx = &fsctx->context; struct sieve_storage *storage = sctx->storage; int result = 0; T_BEGIN { /* Using rename() to ensure existing files are replaced without conflicts with other processes using the same file. The kernel wont fully delete the original until all processes have closed the file. */ if (rename(fsctx->tmp_path, dst) == 0) result = 0; else { result = -1; if (ENOQUOTA(errno)) { sieve_storage_set_error( storage, SIEVE_ERROR_NO_QUOTA, "Not enough disk quota"); } else if (errno == EACCES) { sieve_storage_set_critical( storage, "save: " "Failed to save Sieve script: " "%s", eacces_error_get("rename", dst)); } else { sieve_storage_set_critical( storage, "save: " "rename(%s, %s) failed: %m", fsctx->tmp_path, dst); } } /* Always destroy temp file */ if (unlink(fsctx->tmp_path) < 0 && errno != ENOENT) { e_warning(storage->event, "save: " "unlink(%s) failed: %m", fsctx->tmp_path); } } T_END; return result; } struct sieve_storage_save_context * sieve_file_storage_save_alloc(struct sieve_storage *storage) { struct sieve_file_save_context *fsctx; pool_t pool; pool = pool_alloconly_create("sieve_file_save_context", 1024); fsctx = p_new(pool, struct sieve_file_save_context, 1); fsctx->context.pool = pool; fsctx->context.storage = storage; return &fsctx->context; } int sieve_file_storage_save_init(struct sieve_storage_save_context *sctx, const char *scriptname, struct istream *input) { struct sieve_storage *storage = sctx->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_save_context *fsctx = container_of(sctx, struct sieve_file_save_context, context); pool_t pool = sctx->pool; const char *path; int fd, ret = 0; if (sieve_file_storage_pre_modify(storage) < 0) return -1; if (scriptname != NULL) { /* Prevent overwriting the active script link when it resides in the sieve storage directory. */ i_assert(fstorage->link_path != NULL); if (*(fstorage->link_path) == '\0') { const char *svext; size_t namelen; svext = strrchr(fstorage->active_fname, '.'); namelen = svext - fstorage->active_fname; if (svext != NULL && str_begins_with(svext+1, "sieve") && strlen(scriptname) == namelen && str_begins_with(fstorage->active_fname, scriptname)) { sieve_storage_set_error( storage, SIEVE_ERROR_BAD_PARAMS, "Script name '%s' is reserved for internal use.", scriptname); return -1; } } } T_BEGIN { fd = sieve_file_storage_create_tmp(fstorage, scriptname, &path); if (fd == -1) { ret = -1; } else { fsctx->context.scriptname = p_strdup(pool, scriptname); fsctx->context.input = input; fsctx->fd = fd; fsctx->output = o_stream_create_fd(fsctx->fd, 0); fsctx->tmp_path = p_strdup(pool, path); } } T_END; return ret; } int sieve_file_storage_save_continue(struct sieve_storage_save_context *sctx) { struct sieve_file_save_context *fsctx = container_of(sctx, struct sieve_file_save_context, context); switch (o_stream_send_istream(fsctx->output, sctx->input)) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: return 0; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: i_unreached(); case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: sieve_storage_set_critical( sctx->storage, "save: read(%s) failed: %s", i_stream_get_name(sctx->input), i_stream_get_error(sctx->input)); return -1; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: sieve_storage_set_critical( sctx->storage, "save: write(%s) failed: %s", fsctx->tmp_path, o_stream_get_error(fsctx->output)); return -1; } return 0; } int sieve_file_storage_save_finish(struct sieve_storage_save_context *sctx) { struct sieve_file_save_context *fsctx = container_of(sctx, struct sieve_file_save_context, context); struct sieve_storage *storage = sctx->storage; int output_errno; if (sctx->failed && fsctx->fd == -1) { /* tmp file creation failed */ return -1; } T_BEGIN { output_errno = fsctx->output->stream_errno; o_stream_destroy(&fsctx->output); if (fsync(fsctx->fd) < 0) { sieve_storage_set_critical( storage, "save: fsync(%s) failed: %m", fsctx->tmp_path); sctx->failed = TRUE; } if (close(fsctx->fd) < 0) { sieve_storage_set_critical( storage, "save: close(%s) failed: %m", fsctx->tmp_path); sctx->failed = TRUE; } fsctx->fd = -1; if (sctx->failed) { /* Delete the tmp file */ if (unlink(fsctx->tmp_path) < 0 && errno != ENOENT) { e_warning(storage->event, "save: " "unlink(%s) failed: %m", fsctx->tmp_path); } errno = output_errno; if (ENOQUOTA(errno)) { sieve_storage_set_error( storage, SIEVE_ERROR_NO_QUOTA, "Not enough disk quota"); } else if (errno != 0) { sieve_storage_set_critical( storage, "save: write(%s) failed: %m", fsctx->tmp_path); } fsctx->tmp_path = NULL; } } T_END; return (sctx->failed ? -1 : 0); } struct sieve_script * sieve_file_storage_save_get_tempscript(struct sieve_storage_save_context *sctx) { struct sieve_file_save_context *fsctx = container_of(sctx, struct sieve_file_save_context, context); struct sieve_storage *storage = sctx->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); struct sieve_file_script *tmpscript; const char *scriptname; if (sctx->failed) return NULL; if (sctx->scriptobject != NULL) return sctx->scriptobject; scriptname = (sctx->scriptname == NULL ? "" : sctx->scriptname); if (sieve_file_script_open_from_path(fstorage, fsctx->tmp_path, scriptname, &tmpscript) < 0) { if (storage->error_code == SIEVE_ERROR_NOT_FOUND) { sieve_storage_set_critical( storage, "save: " "Temporary script file '%s' got lost, " "which should not happen " "(possibly deleted externally).", fsctx->tmp_path); } else { sieve_storage_set_critical( storage, "save: " "Failed to open temporary script file '%s'", fsctx->tmp_path); } return NULL; } return &tmpscript->script; } static void sieve_file_storage_update_mtime(struct sieve_storage *storage, const char *path, time_t mtime) { struct utimbuf times = { .actime = mtime, .modtime = mtime }; if (utime(path, ×) < 0) { switch (errno) { case ENOENT: break; case EACCES: e_error(storage->event, "save: %s", eacces_error_get("utime", path)); break; default: e_error(storage->event, "save: utime(%s) failed: %m", path); } } } int sieve_file_storage_save_commit(struct sieve_storage_save_context *sctx) { struct sieve_file_save_context *fsctx = container_of(sctx, struct sieve_file_save_context, context); struct sieve_storage *storage = sctx->storage; struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); const char *dest_path; bool failed = FALSE; i_assert(fsctx->output == NULL); T_BEGIN { dest_path = t_strconcat( fstorage->path, "/", sieve_script_file_from_name(sctx->scriptname), NULL); failed = (sieve_file_storage_script_move(fsctx, dest_path) < 0); if (sctx->mtime != (time_t)-1) { sieve_file_storage_update_mtime(storage, dest_path, sctx->mtime); } } T_END; return (failed ? -1 : 0); } void sieve_file_storage_save_cancel(struct sieve_storage_save_context *sctx) { struct sieve_file_save_context *fsctx = container_of(sctx, struct sieve_file_save_context, context); struct sieve_storage *storage = sctx->storage; if (fsctx->tmp_path != NULL && unlink(fsctx->tmp_path) < 0 && errno != ENOENT) { e_warning(storage->event, "save: unlink(%s) failed: %m", fsctx->tmp_path); } i_assert(fsctx->output == NULL); } static int sieve_file_storage_save_to(struct sieve_file_storage *fstorage, string_t *temp_path, struct istream *input, const char *target) { struct sieve_storage *storage = &fstorage->storage; struct ostream *output; int fd; // FIXME: move this to base class // FIXME: use io_stream_temp fd = safe_mkstemp_hostpid(temp_path, fstorage->file_create_mode, (uid_t)-1, (gid_t)-1); if (fd < 0) { if (errno == EACCES) { sieve_storage_set_critical( storage, "Failed to create temporary file: %s", eacces_error_get_creating( "open", str_c(temp_path))); } else { sieve_storage_set_critical( storage, "Failed to create temporary file: " "open(%s) failed: %m", str_c(temp_path)); } return -1; } output = o_stream_create_fd(fd, 0); switch (o_stream_send_istream(output, input)) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: break; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: i_unreached(); case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: sieve_storage_set_critical( storage, "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); o_stream_destroy(&output); i_unlink(str_c(temp_path)); return -1; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: sieve_storage_set_critical( storage, "write(%s) failed: %s", str_c(temp_path), o_stream_get_error(output)); o_stream_destroy(&output); i_unlink(str_c(temp_path)); return -1; } o_stream_destroy(&output); if (rename(str_c(temp_path), target) < 0) { if (ENOQUOTA(errno)) { sieve_storage_set_error( storage, SIEVE_ERROR_NO_QUOTA, "Not enough disk quota"); } else if (errno == EACCES) { sieve_storage_set_critical( storage, "%s", eacces_error_get("rename", target)); } else { sieve_storage_set_critical( storage, "rename(%s, %s) failed: %m", str_c(temp_path), target); } i_unlink(str_c(temp_path)); } return 0; } int sieve_file_storage_save_as(struct sieve_storage *storage, struct istream *input, const char *name) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); string_t *temp_path; const char *dest_path; temp_path = t_str_new(256); str_append(temp_path, fstorage->path); str_append(temp_path, "/tmp/"); str_append(temp_path, sieve_script_file_from_name(name)); str_append_c(temp_path, '.'); dest_path = t_strconcat(fstorage->path, "/", sieve_script_file_from_name(name), NULL); return sieve_file_storage_save_to(fstorage, temp_path, input, dest_path); } int sieve_file_storage_save_as_active(struct sieve_storage *storage, struct istream *input, time_t mtime) { struct sieve_file_storage *fstorage = container_of(storage, struct sieve_file_storage, storage); string_t *temp_path; temp_path = t_str_new(256); str_append(temp_path, fstorage->active_path); str_append_c(temp_path, '.'); if (sieve_file_storage_save_to(fstorage, temp_path, input, fstorage->active_path) < 0) return -1; sieve_file_storage_update_mtime(storage, fstorage->active_path, mtime); return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/file/sieve-file-storage-settings.h0000644000175100001700000000054215100335616031532 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_FILE_STORAGE_SETTINGS_H #define SIEVE_FILE_STORAGE_SETTINGS_H #define SIEVE_FILE_DEFAULT_ACTIVE_PATH "~/.dovecot."SIEVE_SCRIPT_FILEEXT struct sieve_file_storage_settings { pool_t pool; const char *script_path; const char *script_active_path; }; extern const struct setting_parser_info sieve_file_storage_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/0000755000175100001700000000000015100335670024034 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/sieve-dict-script.c0000644000175100001700000001762315100335616027547 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "strfuncs.h" #include "istream.h" #include "dict.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-dict-storage.h" /* * Script dict implementation */ static struct sieve_dict_script *sieve_dict_script_alloc(void) { struct sieve_dict_script *dscript; pool_t pool; pool = pool_alloconly_create("sieve_dict_script", 1024); dscript = p_new(pool, struct sieve_dict_script, 1); dscript->script = sieve_dict_script; dscript->script.pool = pool; return dscript; } struct sieve_dict_script * sieve_dict_script_init(struct sieve_dict_storage *dstorage, const char *name) { struct sieve_storage *storage = &dstorage->storage; struct sieve_dict_script *dscript = NULL; if (name == NULL || *name == '\0') name = SIEVE_DICT_SCRIPT_DEFAULT; dscript = sieve_dict_script_alloc(); sieve_script_init(&dscript->script, storage, &sieve_dict_script, name); return dscript; } static void sieve_dict_script_destroy(struct sieve_script *script) { struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); if (dscript->data_pool != NULL) pool_unref(&dscript->data_pool); } static int sieve_dict_script_open(struct sieve_script *script) { struct sieve_storage *storage = script->storage; struct sieve_instance *svinst = storage->svinst; struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); const char *name = script->name; const char *path, *data_id, *error; int ret; path = t_strconcat(DICT_SIEVE_NAME_PATH, dict_escape_string(name), NULL); struct dict_op_settings set = { .username = svinst->username, }; ret = dict_lookup(dstorage->dict, &set, script->pool, path, &data_id, &error); if (ret <= 0) { if (ret < 0) { sieve_script_set_critical(script, "Failed to lookup script id from path %s: %s", path, error); } else { e_debug(script->event, "Script '%s' not found at path %s", name, path); sieve_script_set_not_found_error(script, name); } return -1; } dscript->data_id = p_strdup(script->pool, data_id); return 0; } static int sieve_dict_script_get_stream(struct sieve_script *script, struct istream **stream_r) { struct sieve_storage *storage = script->storage; struct sieve_instance *svinst = storage->svinst; struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); const char *path, *name = script->name, *data, *error; int ret; dscript->data_pool = pool_alloconly_create("sieve_dict_script data pool", 1024); path = t_strconcat(DICT_SIEVE_DATA_PATH, dict_escape_string(dscript->data_id), NULL); struct dict_op_settings set = { .username = svinst->username, }; ret = dict_lookup(dstorage->dict, &set, dscript->data_pool, path, &data, &error); if (ret <= 0) { if (ret < 0) { sieve_script_set_critical(script, "Failed to lookup data with id '%s' " "for script '%s' from path %s: %s", dscript->data_id, name, path, error); } else { sieve_script_set_critical(script, "Data with id '%s' for script '%s' not found at path %s", dscript->data_id, name, path); } return -1; } dscript->data = p_strdup(script->pool, data); *stream_r = i_stream_create_from_data(dscript->data, strlen(dscript->data)); return 0; } static int sieve_dict_script_binary_read_metadata(struct sieve_script *script, struct sieve_binary_block *sblock, sieve_size_t *offset) { struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); string_t *data_id; if (dscript->data_id == NULL && sieve_script_open(script, NULL) < 0) return 0; if (!sieve_binary_read_string(sblock, offset, &data_id)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s'", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } i_assert(dscript->data_id != NULL); if (strcmp(str_c(data_id), dscript->data_id) != 0) { e_debug(script->event, "Binary '%s' reports different data ID for script '%s' " "(`%s' rather than `%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(data_id), dscript->data_id); return 0; } return 1; } static void sieve_dict_script_binary_write_metadata(struct sieve_script *script, struct sieve_binary_block *sblock) { struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); sieve_binary_emit_cstring(sblock, dscript->data_id); } static bool sieve_dict_script_binary_dump_metadata(struct sieve_script *script ATTR_UNUSED, struct sieve_dumptime_env *denv, struct sieve_binary_block *sblock, sieve_size_t *offset) { string_t *data_id; if (!sieve_binary_read_string(sblock, offset, &data_id)) return FALSE; sieve_binary_dumpf(denv, "dict.data_id = %s\n", str_c(data_id)); return TRUE; } static const char * sieve_dict_script_get_bin_path(struct sieve_dict_script *dscript) { struct sieve_script *script = &dscript->script; struct sieve_storage *storage = script->storage; if (dscript->bin_path == NULL) { if (storage->bin_path == NULL) return NULL; dscript->bin_path = p_strconcat( script->pool, storage->bin_path, "/", sieve_binfile_from_name(script->name), NULL); } return dscript->bin_path; } static int sieve_dict_script_binary_load(struct sieve_script *script, struct sieve_binary **sbin_r) { struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); return sieve_script_binary_load_default( script, sieve_dict_script_get_bin_path(dscript), sbin_r); } static int sieve_dict_script_binary_save(struct sieve_script *script, struct sieve_binary *sbin, bool update) { struct sieve_dict_script *dscript = container_of(script, struct sieve_dict_script, script); return sieve_script_binary_save_default( script, sbin, sieve_dict_script_get_bin_path(dscript), update, 0600); } const struct sieve_script sieve_dict_script = { .driver_name = SIEVE_DICT_STORAGE_DRIVER_NAME, .v = { .destroy = sieve_dict_script_destroy, .open = sieve_dict_script_open, .get_stream = sieve_dict_script_get_stream, .binary_read_metadata = sieve_dict_script_binary_read_metadata, .binary_write_metadata = sieve_dict_script_binary_write_metadata, .binary_dump_metadata = sieve_dict_script_binary_dump_metadata, .binary_load = sieve_dict_script_binary_load, .binary_save = sieve_dict_script_binary_save, }, }; /* * Script sequence */ struct sieve_dict_script_sequence { bool done:1; }; int sieve_dict_script_sequence_init(struct sieve_script_sequence *sseq) { struct sieve_dict_script_sequence *dseq; /* Create sequence object */ dseq = i_new(struct sieve_dict_script_sequence, 1); sseq->storage_data = dseq; return 0; } int sieve_dict_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r) { struct sieve_dict_script_sequence *dseq = sseq->storage_data; struct sieve_storage *storage = sseq->storage; struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); struct sieve_dict_script *dscript; if (dseq->done) return 0; dseq->done = TRUE; dscript = sieve_dict_script_init(dstorage, storage->script_name); if (sieve_script_open(&dscript->script, NULL) < 0) { struct sieve_script *script = &dscript->script; sieve_script_unref(&script); return -1; } *script_r = &dscript->script; return 1; } void sieve_dict_script_sequence_destroy(struct sieve_script_sequence *sseq) { struct sieve_dict_script_sequence *dseq = sseq->storage_data; i_free(dseq); } dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/Makefile.am0000644000175100001700000000051115100335616026065 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_storage_dict.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve libsieve_storage_dict_la_SOURCES = \ sieve-dict-script.c \ sieve-dict-storage.c \ sieve-dict-storage-settings.c noinst_HEADERS = \ sieve-dict-storage.h \ sieve-dict-storage-settings.h dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/sieve-dict-storage.h0000644000175100001700000000216515100335616027707 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_DICT_STORAGE_H #define SIEVE_DICT_STORAGE_H #include "sieve.h" #include "sieve-script-private.h" #include "sieve-storage-private.h" #define DICT_SIEVE_PATH DICT_PATH_PRIVATE"sieve/" #define DICT_SIEVE_NAME_PATH DICT_SIEVE_PATH"name/" #define DICT_SIEVE_DATA_PATH DICT_SIEVE_PATH"data/" #define SIEVE_DICT_SCRIPT_DEFAULT "default" /* * Storage class */ struct sieve_dict_storage { struct sieve_storage storage; struct dict *dict; }; int sieve_dict_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r); /* * Script class */ struct sieve_dict_script { struct sieve_script script; pool_t data_pool; const char *data_id; const char *data; const char *bin_path; }; struct sieve_dict_script * sieve_dict_script_init(struct sieve_dict_storage *dstorage, const char *name); /* * Script sequence */ int sieve_dict_script_sequence_init(struct sieve_script_sequence *sseq); int sieve_dict_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r); void sieve_dict_script_sequence_destroy(struct sieve_script_sequence *sseq); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/sieve-dict-storage.c0000644000175100001700000000631215100335616027700 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "settings.h" #include "dict.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-dict-storage.h" /* * Storage class */ static struct sieve_storage *sieve_dict_storage_alloc(void) { struct sieve_dict_storage *dstorage; pool_t pool; pool = pool_alloconly_create("sieve_dict_storage", 1024); dstorage = p_new(pool, struct sieve_dict_storage, 1); dstorage->storage = sieve_dict_storage; dstorage->storage.pool = pool; return &dstorage->storage; } static int sieve_dict_storage_init(struct sieve_storage *storage) { struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); const char *error; int ret; struct event *event = event_create(storage->event); event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, "sieve_script_dict"); ret = dict_init_auto(event, &dstorage->dict, &error); event_unref(&event); if (ret <= 0) { sieve_storage_set_critical(storage, "Failed to initialize sieve_script %s dict: %s", storage->name, error); return -1; } return 0; } static void sieve_dict_storage_destroy(struct sieve_storage *storage) { struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); dict_deinit(&dstorage->dict); } /* * Script access */ static int sieve_dict_storage_get_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r) { struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); struct sieve_dict_script *dscript; T_BEGIN { dscript = sieve_dict_script_init(dstorage, name); } T_END; if (dscript == NULL) return -1; *script_r = &dscript->script; return 0; } /* * Active script */ static int sieve_dict_storage_active_script_open(struct sieve_storage *storage, struct sieve_script **script_r) { struct sieve_dict_storage *dstorage = container_of(storage, struct sieve_dict_storage, storage); struct sieve_dict_script *dscript; dscript = sieve_dict_script_init(dstorage, storage->script_name); if (sieve_script_open(&dscript->script, NULL) < 0) { struct sieve_script *script = &dscript->script; sieve_script_unref(&script); return -1; } *script_r = &dscript->script; return 0; } int sieve_dict_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r) { if (storage->script_name != NULL) *name_r = storage->script_name; else *name_r = SIEVE_DICT_SCRIPT_DEFAULT; return 0; } /* * Driver definition */ const struct sieve_storage sieve_dict_storage = { .driver_name = SIEVE_DICT_STORAGE_DRIVER_NAME, .version = 0, .v = { .alloc = sieve_dict_storage_alloc, .destroy = sieve_dict_storage_destroy, .init = sieve_dict_storage_init, .get_script = sieve_dict_storage_get_script, .script_sequence_init = sieve_dict_script_sequence_init, .script_sequence_next = sieve_dict_script_sequence_next, .script_sequence_destroy = sieve_dict_script_sequence_destroy, .active_script_get_name = sieve_dict_storage_active_script_get_name, .active_script_open = sieve_dict_storage_active_script_open, // FIXME: impement management interface }, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/Makefile.in0000644000175100001700000005463515100335630026112 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/storage/dict ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_storage_dict_la_LIBADD = am_libsieve_storage_dict_la_OBJECTS = sieve-dict-script.lo \ sieve-dict-storage.lo sieve-dict-storage-settings.lo libsieve_storage_dict_la_OBJECTS = \ $(am_libsieve_storage_dict_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/sieve-dict-script.Plo \ ./$(DEPDIR)/sieve-dict-storage-settings.Plo \ ./$(DEPDIR)/sieve-dict-storage.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_storage_dict_la_SOURCES) DIST_SOURCES = $(libsieve_storage_dict_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_storage_dict.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve libsieve_storage_dict_la_SOURCES = \ sieve-dict-script.c \ sieve-dict-storage.c \ sieve-dict-storage-settings.c noinst_HEADERS = \ sieve-dict-storage.h \ sieve-dict-storage-settings.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/storage/dict/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/storage/dict/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_storage_dict.la: $(libsieve_storage_dict_la_OBJECTS) $(libsieve_storage_dict_la_DEPENDENCIES) $(EXTRA_libsieve_storage_dict_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_storage_dict_la_OBJECTS) $(libsieve_storage_dict_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-dict-script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-dict-storage-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-dict-storage.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/sieve-dict-script.Plo -rm -f ./$(DEPDIR)/sieve-dict-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-dict-storage.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/sieve-dict-script.Plo -rm -f ./$(DEPDIR)/sieve-dict-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-dict-storage.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/sieve-dict-storage-settings.h0000644000175100001700000000024515100335616031542 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_DICT_STORAGE_SETTINGS_H #define SIEVE_DICT_STORAGE_SETTINGS_H extern const struct setting_parser_info sieve_dict_storage_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/dict/sieve-dict-storage-settings.c0000644000175100001700000000075115100335616031537 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "settings-parser.h" #include "sieve-dict-storage-settings.h" static const struct setting_define sieve_dict_storage_setting_defines[] = { { .type = SET_FILTER_NAME, .key = "sieve_script_dict" }, SETTING_DEFINE_LIST_END, }; const struct setting_parser_info sieve_dict_storage_setting_parser_info = { .name = "sieve_dict_storage", .defines = sieve_dict_storage_setting_defines, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/0000755000175100001700000000000015100335670024031 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/Makefile.am0000644000175100001700000000212115100335616026061 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_storage_ldap.la sieve_plugindir = $(dovecot_moduledir)/sieve sieve_plugin_LTLIBRARIES = AM_CPPFLAGS = \ $(LDAP_CFLAGS) \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_LDAP_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve ldap_sources = \ sieve-ldap-db.c \ sieve-ldap-script.c \ sieve-ldap-storage.c \ sieve-ldap-storage-settings.c libsieve_storage_ldap_la_SOURCES = $(ldap_sources) libsieve_storage_ldap_la_LIBADD = \ $(LDAP_LIBS) \ $(LIBDOVECOT) \ $(LIBDOVECOT_LDAP) \ $(DOVECOT_LDAP_LIBS) noinst_HEADERS = \ sieve-ldap-db.h \ sieve-ldap-storage-settings.h \ sieve-ldap-storage.h if LDAP_PLUGIN sieve_plugin_LTLIBRARIES += lib10_sieve_storage_ldap_plugin.la lib10_sieve_storage_ldap_plugin_la_LDFLAGS = -module -avoid-version lib10_sieve_storage_ldap_plugin_la_LIBADD = \ $(LIBDOVECOT) \ $(LIBDOVECOT_LDAP) \ $(DOVECOT_LDAP_LIBS) lib10_sieve_storage_ldap_plugin_la_DEPENDENCIES = $(LIBDOVECOT_LDAP_DEPS) lib10_sieve_storage_ldap_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DPLUGIN_BUILD lib10_sieve_storage_ldap_plugin_la_SOURCES = $(ldap_sources) endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-storage.c0000644000175100001700000001331215100335616027670 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "settings.h" #include "iostream-ssl.h" #include "sieve-common.h" #include "sieve-ldap-storage.h" #include "sieve-ldap-storage-settings.h" #if defined(SIEVE_BUILTIN_LDAP) || defined(PLUGIN_BUILD) #include "ldap-utils.h" #include "sieve-error.h" #ifndef PLUGIN_BUILD const struct sieve_storage sieve_ldap_storage; #else const struct sieve_storage sieve_ldap_storage_plugin; #endif /* * Storage class */ static struct sieve_storage *sieve_ldap_storage_alloc(void) { struct sieve_ldap_storage *lstorage; pool_t pool; pool = pool_alloconly_create("sieve_ldap_storage", 1024); lstorage = p_new(pool, struct sieve_ldap_storage, 1); #ifndef PLUGIN_BUILD lstorage->storage = sieve_ldap_storage; #else lstorage->storage = sieve_ldap_storage_plugin; #endif lstorage->storage.pool = pool; return &lstorage->storage; } static int sieve_ldap_storage_init(struct sieve_storage *storage) { struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); const struct sieve_ldap_settings *ldap_set; const struct sieve_ldap_storage_settings *set = NULL; const struct ssl_settings *ssl_set; const char *error; int ret; struct event *event = event_create(storage->event); event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, "ldap"); ret = settings_get(event, &sieve_ldap_setting_parser_info, 0, &ldap_set, &error); event_unref(&event); if (ret < 0) { e_error(storage->event, "%s", error); sieve_storage_set_internal_error(storage); return -1; } if (*ldap_set->uris == '\0') { sieve_storage_set_critical(storage, "sieve_script %s { ldap_uris / ldap_hosts } not set", storage->name); settings_free(ldap_set); return -1; } if (settings_get(storage->event, &sieve_ldap_storage_setting_parser_info, 0, &set, &error) < 0 || settings_get(storage->event, &ssl_setting_parser_info, 0, &ssl_set, &error) < 0) { e_error(storage->event, "%s", error); sieve_storage_set_internal_error(storage); settings_free(set); settings_free(ldap_set); return -1; } lstorage->ldap_set = ldap_set; lstorage->set = set; lstorage->ssl_set = ssl_set; lstorage->conn = sieve_ldap_db_init(lstorage); return 0; } static void sieve_ldap_storage_destroy(struct sieve_storage *storage) { struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); sieve_ldap_db_unref(&lstorage->conn); settings_free(lstorage->ssl_set); settings_free(lstorage->ldap_set); settings_free(lstorage->set); } /* * Script access */ static int sieve_ldap_storage_get_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r) { struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); struct sieve_ldap_script *lscript; T_BEGIN { lscript = sieve_ldap_script_init(lstorage, name); } T_END; if (lscript == NULL) return -1; *script_r = &lscript->script; return 0; } /* * Active script */ static int sieve_ldap_storage_active_script_open(struct sieve_storage *storage, struct sieve_script **script_r) { struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); struct sieve_ldap_script *lscript; lscript = sieve_ldap_script_init(lstorage, storage->script_name); if (sieve_script_open(&lscript->script, NULL) < 0) { struct sieve_script *script = &lscript->script; sieve_script_unref(&script); return -1; } *script_r = &lscript->script; return 0; } int sieve_ldap_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r) { if (storage->script_name != NULL) *name_r = storage->script_name; else *name_r = SIEVE_LDAP_SCRIPT_DEFAULT; return 0; } /* * Driver definition */ #ifndef PLUGIN_BUILD const struct sieve_storage sieve_ldap_storage = { #else const struct sieve_storage sieve_ldap_storage_plugin = { #endif .driver_name = SIEVE_LDAP_STORAGE_DRIVER_NAME, .version = 0, .v = { .alloc = sieve_ldap_storage_alloc, .init = sieve_ldap_storage_init, .destroy = sieve_ldap_storage_destroy, .get_script = sieve_ldap_storage_get_script, .script_sequence_init = sieve_ldap_script_sequence_init, .script_sequence_next = sieve_ldap_script_sequence_next, .script_sequence_destroy = sieve_ldap_script_sequence_destroy, .active_script_get_name = sieve_ldap_storage_active_script_get_name, .active_script_open = sieve_ldap_storage_active_script_open, // FIXME: impement management interface }, }; #ifndef SIEVE_BUILTIN_LDAP /* Building a plugin */ const char *sieve_storage_ldap_plugin_version = PIGEONHOLE_ABI_VERSION; int sieve_storage_ldap_plugin_load(struct sieve_instance *svinst, void **context); void sieve_storage_ldap_plugin_unload(struct sieve_instance *svinst, void *context); void sieve_storage_ldap_plugin_init(void); void sieve_storage_ldap_plugin_deinit(void); int sieve_storage_ldap_plugin_load(struct sieve_instance *svinst, void **context ATTR_UNUSED) { sieve_storage_class_register(svinst, &sieve_ldap_storage_plugin); e_debug(svinst->event, "Sieve LDAP storage plugin for %s version %s loaded", PIGEONHOLE_NAME, PIGEONHOLE_VERSION_FULL); return 0; } void sieve_storage_ldap_plugin_unload(struct sieve_instance *svinst ATTR_UNUSED, void *context ATTR_UNUSED) { sieve_storage_class_unregister(svinst, &sieve_ldap_storage_plugin); } void sieve_storage_ldap_plugin_init(void) { /* Nothing */ } void sieve_storage_ldap_plugin_deinit(void) { /* Nothing */ } #endif #else /* !defined(SIEVE_BUILTIN_LDAP) && !defined(PLUGIN_BUILD) */ const struct sieve_storage sieve_ldap_storage = { .driver_name = SIEVE_LDAP_STORAGE_DRIVER_NAME, }; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.c0000644000175100001700000001120515100335616031525 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "env-util.h" #include "settings-parser.h" #include "sieve-common.h" #include "sieve-ldap-storage.h" #include "sieve-ldap-storage-settings.h" #ifdef STORAGE_LDAP #include "sieve-error.h" #include "sieve-ldap-db.h" #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("ldap_"#name, name, \ struct sieve_ldap_settings) /* */ static bool sieve_ldap_settings_check(void *_set, pool_t pool, const char **error_r); static bool sieve_ldap_storage_settings_check(void *_set, pool_t pool, const char **error_r); /* */ static const struct setting_define sieve_ldap_setting_defines[] = { DEF(STR, uris), DEF(STR, auth_dn), DEF(STR, auth_dn_password), DEF(BOOL, starttls), DEF(BOOLLIST, auth_sasl_mechanisms), DEF(STR, auth_sasl_realm), DEF(STR, auth_sasl_authz_id), DEF(ENUM, deref), DEF(ENUM, scope), DEF(STR, base), DEF(UINT, version), DEF(UINT, debug_level), SETTING_DEFINE_LIST_END }; const struct sieve_ldap_settings sieve_ldap_default_settings = { .uris = "", .auth_dn = "", .auth_dn_password = "", .starttls = FALSE, .auth_sasl_mechanisms = ARRAY_INIT, .auth_sasl_realm = "", .auth_sasl_authz_id = "", .deref = "never:searching:finding:always", .scope = "subtree:onelevel:base", .base = "", .version = 3, .debug_level = 0, }; const struct setting_parser_info sieve_ldap_setting_parser_info = { .name = "sieve_ldap", .defines = sieve_ldap_setting_defines, .defaults = &sieve_ldap_default_settings, .pool_offset1 = 1 + offsetof(struct sieve_ldap_settings, pool), .struct_size = sizeof(struct sieve_ldap_settings), .check_func = sieve_ldap_settings_check, }; #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_script_ldap_"#name, name, \ struct sieve_ldap_storage_settings) static const struct setting_define sieve_ldap_storage_setting_defines[] = { DEF(STR, script_attribute), DEF(STR, modified_attribute), DEF(STR, filter), SETTING_DEFINE_LIST_END }; static struct sieve_ldap_storage_settings sieve_ldap_storage_server_default_settings = { .script_attribute = "", .modified_attribute = "", .filter = "", }; const struct setting_parser_info sieve_ldap_storage_setting_parser_info = { .name = "sieve_ldap_storage", .defines = sieve_ldap_storage_setting_defines, .defaults = &sieve_ldap_storage_server_default_settings, .pool_offset1 = 1 + offsetof(struct sieve_ldap_storage_settings, pool), .struct_size = sizeof(struct sieve_ldap_storage_settings), .check_func = sieve_ldap_storage_settings_check, }; /* */ static int ldap_deref_from_str(const char *str, int *deref_r) { if (strcasecmp(str, "never") == 0) *deref_r = LDAP_DEREF_NEVER; else if (strcasecmp(str, "searching") == 0) *deref_r = LDAP_DEREF_SEARCHING; else if (strcasecmp(str, "finding") == 0) *deref_r = LDAP_DEREF_FINDING; else if (strcasecmp(str, "always") == 0) *deref_r = LDAP_DEREF_ALWAYS; else return -1; return 0; } static int ldap_scope_from_str(const char *str, int *scope_r) { if (strcasecmp(str, "base") == 0) *scope_r = LDAP_SCOPE_BASE; else if (strcasecmp(str, "onelevel") == 0) *scope_r = LDAP_SCOPE_ONELEVEL; else if (strcasecmp(str, "subtree") == 0) *scope_r = LDAP_SCOPE_SUBTREE; else return -1; return 0; } static bool sieve_ldap_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct sieve_ldap_settings *set = _set; if (set->base[0] == '\0' && settings_get_config_binary() == SETTINGS_BINARY_OTHER) { *error_r = "ldap: No ldap_base configured"; return FALSE; } if (ldap_deref_from_str(set->deref, &set->parsed.deref) < 0) { *error_r = t_strdup_printf("ldap: " "Invalid ldap_deref value '%s'", set->deref); return FALSE; } if (ldap_scope_from_str(set->scope, &set->parsed.scope) < 0) { *error_r = t_strdup_printf("ldap: " "Invalid ldap_scope value '%s'", set->scope); return FALSE; } return TRUE; } static bool sieve_ldap_storage_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct sieve_ldap_storage_settings *set = _set; if (settings_get_config_binary() == SETTINGS_BINARY_OTHER) { if (*set->script_attribute == '\0') { *error_r = "ldap: " "No sieve_script_ldap_script_attribute configured"; return FALSE; } if (*set->modified_attribute == '\0') { *error_r = "ldap: " "No sieve_script_ldap_modified_attribute configured"; return FALSE; } if (*set->filter == '\0') { *error_r = "ldap: " "No sieve_script_ldap_filter configured"; return FALSE; } } return TRUE; } /* */ #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/Makefile.in0000644000175100001700000010615415100335630026101 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ @LDAP_PLUGIN_TRUE@am__append_1 = lib10_sieve_storage_ldap_plugin.la subdir = src/lib-sieve/storage/ldap ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = 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)$(sieve_plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(sieve_plugin_LTLIBRARIES) am__DEPENDENCIES_1 = am__lib10_sieve_storage_ldap_plugin_la_SOURCES_DIST = sieve-ldap-db.c \ sieve-ldap-script.c sieve-ldap-storage.c \ sieve-ldap-storage-settings.c am__objects_1 = lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.lo \ lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.lo \ lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.lo \ lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.lo @LDAP_PLUGIN_TRUE@am_lib10_sieve_storage_ldap_plugin_la_OBJECTS = \ @LDAP_PLUGIN_TRUE@ $(am__objects_1) lib10_sieve_storage_ldap_plugin_la_OBJECTS = \ $(am_lib10_sieve_storage_ldap_plugin_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = lib10_sieve_storage_ldap_plugin_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lib10_sieve_storage_ldap_plugin_la_LDFLAGS) $(LDFLAGS) -o $@ @LDAP_PLUGIN_TRUE@am_lib10_sieve_storage_ldap_plugin_la_rpath = \ @LDAP_PLUGIN_TRUE@ -rpath $(sieve_plugindir) libsieve_storage_ldap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__objects_2 = sieve-ldap-db.lo sieve-ldap-script.lo \ sieve-ldap-storage.lo sieve-ldap-storage-settings.lo am_libsieve_storage_ldap_la_OBJECTS = $(am__objects_2) libsieve_storage_ldap_la_OBJECTS = \ $(am_libsieve_storage_ldap_la_OBJECTS) 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Plo \ ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Plo \ ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Plo \ ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Plo \ ./$(DEPDIR)/sieve-ldap-db.Plo \ ./$(DEPDIR)/sieve-ldap-script.Plo \ ./$(DEPDIR)/sieve-ldap-storage-settings.Plo \ ./$(DEPDIR)/sieve-ldap-storage.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(lib10_sieve_storage_ldap_plugin_la_SOURCES) \ $(libsieve_storage_ldap_la_SOURCES) DIST_SOURCES = $(am__lib10_sieve_storage_ldap_plugin_la_SOURCES_DIST) \ $(libsieve_storage_ldap_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_storage_ldap.la sieve_plugindir = $(dovecot_moduledir)/sieve sieve_plugin_LTLIBRARIES = $(am__append_1) AM_CPPFLAGS = \ $(LDAP_CFLAGS) \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_LDAP_INCLUDE) \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve ldap_sources = \ sieve-ldap-db.c \ sieve-ldap-script.c \ sieve-ldap-storage.c \ sieve-ldap-storage-settings.c libsieve_storage_ldap_la_SOURCES = $(ldap_sources) libsieve_storage_ldap_la_LIBADD = \ $(LDAP_LIBS) \ $(LIBDOVECOT) \ $(LIBDOVECOT_LDAP) \ $(DOVECOT_LDAP_LIBS) noinst_HEADERS = \ sieve-ldap-db.h \ sieve-ldap-storage-settings.h \ sieve-ldap-storage.h @LDAP_PLUGIN_TRUE@lib10_sieve_storage_ldap_plugin_la_LDFLAGS = -module -avoid-version @LDAP_PLUGIN_TRUE@lib10_sieve_storage_ldap_plugin_la_LIBADD = \ @LDAP_PLUGIN_TRUE@ $(LIBDOVECOT) \ @LDAP_PLUGIN_TRUE@ $(LIBDOVECOT_LDAP) \ @LDAP_PLUGIN_TRUE@ $(DOVECOT_LDAP_LIBS) @LDAP_PLUGIN_TRUE@lib10_sieve_storage_ldap_plugin_la_DEPENDENCIES = $(LIBDOVECOT_LDAP_DEPS) @LDAP_PLUGIN_TRUE@lib10_sieve_storage_ldap_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DPLUGIN_BUILD @LDAP_PLUGIN_TRUE@lib10_sieve_storage_ldap_plugin_la_SOURCES = $(ldap_sources) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/storage/ldap/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/storage/ldap/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-sieve_pluginLTLIBRARIES: $(sieve_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(sieve_plugin_LTLIBRARIES)'; test -n "$(sieve_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(sieve_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sieve_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(sieve_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(sieve_plugindir)"; \ } uninstall-sieve_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(sieve_plugin_LTLIBRARIES)'; test -n "$(sieve_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(sieve_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(sieve_plugindir)/$$f"; \ done clean-sieve_pluginLTLIBRARIES: -test -z "$(sieve_plugin_LTLIBRARIES)" || rm -f $(sieve_plugin_LTLIBRARIES) @list='$(sieve_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } lib10_sieve_storage_ldap_plugin.la: $(lib10_sieve_storage_ldap_plugin_la_OBJECTS) $(lib10_sieve_storage_ldap_plugin_la_DEPENDENCIES) $(EXTRA_lib10_sieve_storage_ldap_plugin_la_DEPENDENCIES) $(AM_V_CCLD)$(lib10_sieve_storage_ldap_plugin_la_LINK) $(am_lib10_sieve_storage_ldap_plugin_la_rpath) $(lib10_sieve_storage_ldap_plugin_la_OBJECTS) $(lib10_sieve_storage_ldap_plugin_la_LIBADD) $(LIBS) libsieve_storage_ldap.la: $(libsieve_storage_ldap_la_OBJECTS) $(libsieve_storage_ldap_la_DEPENDENCIES) $(EXTRA_libsieve_storage_ldap_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_storage_ldap_la_OBJECTS) $(libsieve_storage_ldap_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-ldap-db.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-ldap-script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-ldap-storage-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-ldap-storage.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.lo: sieve-ldap-db.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.lo -MD -MP -MF $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Tpo -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.lo `test -f 'sieve-ldap-db.c' || echo '$(srcdir)/'`sieve-ldap-db.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Tpo $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sieve-ldap-db.c' object='lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.lo `test -f 'sieve-ldap-db.c' || echo '$(srcdir)/'`sieve-ldap-db.c lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.lo: sieve-ldap-script.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.lo -MD -MP -MF $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Tpo -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.lo `test -f 'sieve-ldap-script.c' || echo '$(srcdir)/'`sieve-ldap-script.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Tpo $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sieve-ldap-script.c' object='lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.lo `test -f 'sieve-ldap-script.c' || echo '$(srcdir)/'`sieve-ldap-script.c lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.lo: sieve-ldap-storage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.lo -MD -MP -MF $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Tpo -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.lo `test -f 'sieve-ldap-storage.c' || echo '$(srcdir)/'`sieve-ldap-storage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Tpo $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sieve-ldap-storage.c' object='lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.lo `test -f 'sieve-ldap-storage.c' || echo '$(srcdir)/'`sieve-ldap-storage.c lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.lo: sieve-ldap-storage-settings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.lo -MD -MP -MF $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Tpo -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.lo `test -f 'sieve-ldap-storage-settings.c' || echo '$(srcdir)/'`sieve-ldap-storage-settings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Tpo $(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sieve-ldap-storage-settings.c' object='lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib10_sieve_storage_ldap_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.lo `test -f 'sieve-ldap-storage-settings.c' || echo '$(srcdir)/'`sieve-ldap-storage-settings.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(sieve_plugindir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ clean-sieve_pluginLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Plo -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Plo -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Plo -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Plo -rm -f ./$(DEPDIR)/sieve-ldap-db.Plo -rm -f ./$(DEPDIR)/sieve-ldap-script.Plo -rm -f ./$(DEPDIR)/sieve-ldap-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-ldap-storage.Plo -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-sieve_pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-db.Plo -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-script.Plo -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage-settings.Plo -rm -f ./$(DEPDIR)/lib10_sieve_storage_ldap_plugin_la-sieve-ldap-storage.Plo -rm -f ./$(DEPDIR)/sieve-ldap-db.Plo -rm -f ./$(DEPDIR)/sieve-ldap-script.Plo -rm -f ./$(DEPDIR)/sieve-ldap-storage-settings.Plo -rm -f ./$(DEPDIR)/sieve-ldap-storage.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-sieve_pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-sieve_pluginLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am 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-sieve_pluginLTLIBRARIES \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-sieve_pluginLTLIBRARIES .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-storage.h0000644000175100001700000000241215100335616027674 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_LDAP_STORAGE_H #define SIEVE_LDAP_STORAGE_H #include "sieve.h" #include "sieve-script-private.h" #include "sieve-storage-private.h" #define SIEVE_LDAP_SCRIPT_DEFAULT "default" #if defined(SIEVE_BUILTIN_LDAP) || defined(PLUGIN_BUILD) #include "sieve-ldap-storage-settings.h" #include "sieve-ldap-db.h" struct sieve_ldap_storage; /* * Storage class */ struct sieve_ldap_storage { struct sieve_storage storage; const struct sieve_ldap_settings *ldap_set; const struct sieve_ldap_storage_settings *set; const struct ssl_settings *ssl_set; time_t set_mtime; struct ldap_connection *conn; }; int sieve_ldap_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r); /* * Script class */ struct sieve_ldap_script { struct sieve_script script; const char *dn; const char *modattr; const char *bin_path; }; struct sieve_ldap_script * sieve_ldap_script_init(struct sieve_ldap_storage *lstorage, const char *name); /* * Script sequence */ int sieve_ldap_script_sequence_init(struct sieve_script_sequence *sseq); int sieve_ldap_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r); void sieve_ldap_script_sequence_destroy(struct sieve_script_sequence *sseq); #endif #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.h0000644000175100001700000000145015100335616031533 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_LDAP_STORAGE_SETTINGS_H #define SIEVE_LDAP_STORAGE_SETTINGS_H struct sieve_ldap_settings { pool_t pool; const char *uris; const char *auth_dn; const char *auth_dn_password; bool starttls; ARRAY_TYPE(const_string) auth_sasl_mechanisms; const char *auth_sasl_realm; const char *auth_sasl_authz_id; const char *deref; const char *scope; const char *base; unsigned int version; unsigned int debug_level; /* ... */ struct { int deref, scope, tls_require_cert; } parsed; }; struct sieve_ldap_storage_settings { pool_t pool; const char *script_attribute; const char *modified_attribute; const char *filter; }; extern const struct setting_parser_info sieve_ldap_setting_parser_info; extern const struct setting_parser_info sieve_ldap_storage_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-db.c0000644000175100001700000007721415100335616026624 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-ldap-storage.h" /* FIXME: Imported this from Dovecot auth for now. We're working on a proper lib-ldap, but, until then, some code is duplicated here. */ #if defined(SIEVE_BUILTIN_LDAP) || defined(PLUGIN_BUILD) #include "net.h" #include "ioloop.h" #include "array.h" #include "hash.h" #include "aqueue.h" #include "str.h" #include "time-util.h" #include "env-util.h" #include "var-expand.h" #include "istream.h" #include "ldap-utils.h" #include #include struct db_ldap_result { int refcount; LDAPMessage *msg; }; struct db_ldap_result_iterate_context { pool_t pool; struct auth_request *auth_request; const ARRAY_TYPE(ldap_field) *attr_map; unsigned int attr_idx; /* attribute name => value */ HASH_TABLE(char *, struct db_ldap_value *) ldap_attrs; const char *val_1_arr[2]; string_t *var, *debug; bool skip_null_values; bool iter_dn_values; }; struct db_ldap_sasl_bind_context { const char *authcid; const char *passwd; const char *realm; const char *authzid; }; static struct ldap_connection *ldap_connections = NULL; static int db_ldap_bind(struct ldap_connection *conn); static void db_ldap_conn_close(struct ldap_connection *conn); static int ldap_get_errno(struct ldap_connection *conn) { struct sieve_storage *storage = &conn->lstorage->storage; int ret, err; ret = ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, &err); if (ret != LDAP_SUCCESS) { e_error(storage->event, "db: " "Can't get error number: %s", ldap_err2string(ret)); return LDAP_UNAVAILABLE; } return err; } const char *ldap_get_error(struct ldap_connection *conn) { const char *ret; char *str = NULL; ret = ldap_err2string(ldap_get_errno(conn)); ldap_get_option(conn->ld, LDAP_OPT_ERROR_STRING, &str); if (str != NULL) { ret = t_strconcat(ret, ", ", str, NULL); ldap_memfree(str); } ldap_set_option(conn->ld, LDAP_OPT_ERROR_STRING, NULL); return ret; } static void ldap_conn_reconnect(struct ldap_connection *conn) { db_ldap_conn_close(conn); if (sieve_ldap_db_connect(conn) < 0) db_ldap_conn_close(conn); } static int ldap_handle_error(struct ldap_connection *conn) { int err = ldap_get_errno(conn); switch (err) { case LDAP_SUCCESS: i_unreached(); case LDAP_SIZELIMIT_EXCEEDED: case LDAP_TIMELIMIT_EXCEEDED: case LDAP_NO_SUCH_ATTRIBUTE: case LDAP_UNDEFINED_TYPE: case LDAP_INAPPROPRIATE_MATCHING: case LDAP_CONSTRAINT_VIOLATION: case LDAP_TYPE_OR_VALUE_EXISTS: case LDAP_INVALID_SYNTAX: case LDAP_NO_SUCH_OBJECT: case LDAP_ALIAS_PROBLEM: case LDAP_INVALID_DN_SYNTAX: case LDAP_IS_LEAF: case LDAP_ALIAS_DEREF_PROBLEM: case LDAP_FILTER_ERROR: /* Invalid input */ return -1; case LDAP_SERVER_DOWN: case LDAP_TIMEOUT: case LDAP_UNAVAILABLE: case LDAP_BUSY: #ifdef LDAP_CONNECT_ERROR case LDAP_CONNECT_ERROR: #endif case LDAP_LOCAL_ERROR: case LDAP_INVALID_CREDENTIALS: case LDAP_OPERATIONS_ERROR: default: /* Connection problems */ ldap_conn_reconnect(conn); return 0; } } static int db_ldap_request_search(struct ldap_connection *conn, struct ldap_request *request) { struct sieve_storage *storage = &conn->lstorage->storage; i_assert(conn->conn_state == LDAP_CONN_STATE_BOUND); i_assert(request->msgid == -1); request->msgid = ldap_search(conn->ld, *request->base == '\0' ? NULL : request->base, request->scope, request->filter, request->attributes, 0); if (request->msgid == -1) { e_error(storage->event, "db: " "ldap_search(%s) parsing failed: %s", request->filter, ldap_get_error(conn)); if (ldap_handle_error(conn) < 0) { /* Broken request, remove it */ return 0; } return -1; } return 1; } static bool db_ldap_request_queue_next(struct ldap_connection *conn) { struct ldap_request *const *requestp, *request; int ret = -1; /* Connecting may call db_ldap_connect_finish(), which gets us back here. so do the connection before checking the request queue. */ if (sieve_ldap_db_connect(conn) < 0) return FALSE; if (conn->pending_count == aqueue_count(conn->request_queue)) { /* No non-pending requests */ return FALSE; } if (conn->pending_count > DB_LDAP_MAX_PENDING_REQUESTS) { /* Wait until server has replied to some requests */ return FALSE; } requestp = array_idx(&conn->request_array, aqueue_idx(conn->request_queue, conn->pending_count)); request = *requestp; switch (conn->conn_state) { case LDAP_CONN_STATE_DISCONNECTED: case LDAP_CONN_STATE_BINDING: /* Wait until we're in bound state */ return FALSE; case LDAP_CONN_STATE_BOUND: /* We can do anything in this state */ break; } ret = db_ldap_request_search(conn, request); if (ret > 0) { /* Success */ i_assert(request->msgid != -1); conn->pending_count++; return TRUE; } else if (ret < 0) { /* Disconnected */ return FALSE; } else { /* Broken request, remove from queue */ aqueue_delete_tail(conn->request_queue); request->callback(conn, request, NULL); return TRUE; } } static bool db_ldap_check_limits(struct ldap_connection *conn) { struct sieve_storage *storage = &conn->lstorage->storage; struct ldap_request *const *first_requestp; unsigned int count; time_t secs_diff; count = aqueue_count(conn->request_queue); if (count == 0) return TRUE; first_requestp = array_idx(&conn->request_array, aqueue_idx(conn->request_queue, 0)); secs_diff = ioloop_time - (*first_requestp)->create_time; if (secs_diff > DB_LDAP_REQUEST_LOST_TIMEOUT_SECS) { e_error(storage->event, "db: " "Connection appears to be hanging, reconnecting"); ldap_conn_reconnect(conn); return TRUE; } return TRUE; } void db_ldap_request(struct ldap_connection *conn, struct ldap_request *request) { request->msgid = -1; request->create_time = ioloop_time; if (!db_ldap_check_limits(conn)) { request->callback(conn, request, NULL); return; } aqueue_append(conn->request_queue, &request); (void)db_ldap_request_queue_next(conn); } static int db_ldap_connect_finish(struct ldap_connection *conn, int ret) { struct sieve_storage *storage = &conn->lstorage->storage; const struct sieve_ldap_settings *set = conn->lstorage->ldap_set; if (ret == LDAP_SERVER_DOWN) { e_error(storage->event, "db: " "Can't connect to server: %s", set->uris); return -1; } if (ret != LDAP_SUCCESS) { e_error(storage->event, "db: " "binding failed (dn %s): %s", *set->auth_dn == '\0' ? "(none)" : set->auth_dn, ldap_get_error(conn)); return -1; } timeout_remove(&conn->to); conn->conn_state = LDAP_CONN_STATE_BOUND; e_debug(storage->event, "db: " "Successfully bound (dn %s)", *set->auth_dn == '\0' ? "(none)" : set->auth_dn); while (db_ldap_request_queue_next(conn)) ; return 0; } static void db_ldap_default_bind_finished(struct ldap_connection *conn, struct db_ldap_result *res) { int ret; i_assert(conn->pending_count == 0); conn->default_bind_msgid = -1; ret = ldap_result2error(conn->ld, res->msg, FALSE); if (db_ldap_connect_finish(conn, ret) < 0) { /* Lost connection, close it */ db_ldap_conn_close(conn); } } static void db_ldap_abort_requests(struct ldap_connection *conn, unsigned int max_count, unsigned int timeout_secs, bool error, const char *reason) { struct sieve_storage *storage = &conn->lstorage->storage; struct ldap_request *const *requestp, *request; time_t diff; while (aqueue_count(conn->request_queue) > 0 && max_count > 0) { requestp = array_idx(&conn->request_array, aqueue_idx(conn->request_queue, 0)); request = *requestp; diff = ioloop_time - request->create_time; if (diff < (time_t)timeout_secs) break; /* timed out, abort */ aqueue_delete_tail(conn->request_queue); if (request->msgid != -1) { i_assert(conn->pending_count > 0); conn->pending_count--; } if (error) e_error(storage->event, "db: %s", reason); else e_debug(storage->event, "db: %s", reason); request->callback(conn, request, NULL); max_count--; } } static struct ldap_request * db_ldap_find_request(struct ldap_connection *conn, int msgid, unsigned int *idx_r) { struct ldap_request *const *requests, *request = NULL; unsigned int i, count; count = aqueue_count(conn->request_queue); if (count == 0) return NULL; requests = array_idx(&conn->request_array, 0); for (i = 0; i < count; i++) { request = requests[aqueue_idx(conn->request_queue, i)]; if (request->msgid == msgid) { *idx_r = i; return request; } if (request->msgid == -1) break; } return NULL; } static bool db_ldap_handle_request_result(struct ldap_connection *conn, struct ldap_request *request, unsigned int idx, struct db_ldap_result *res) { struct sieve_storage *storage = &conn->lstorage->storage; int ret; bool final_result; i_assert(conn->pending_count > 0); switch (ldap_msgtype(res->msg)) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_RESULT: break; case LDAP_RES_SEARCH_REFERENCE: /* We're going to ignore this */ return FALSE; default: e_error(storage->event, "db: Reply with unexpected type %d", ldap_msgtype(res->msg)); return TRUE; } if (ldap_msgtype(res->msg) == LDAP_RES_SEARCH_ENTRY) { ret = LDAP_SUCCESS; final_result = FALSE; } else { final_result = TRUE; ret = ldap_result2error(conn->ld, res->msg, 0); } if (ret != LDAP_SUCCESS) { /* Handle search failures here */ e_error(storage->event, "db: " "ldap_search(base=%s filter=%s) failed: %s", request->base, request->filter, ldap_err2string(ret)); res = NULL; } else { if (!final_result && storage->svinst->debug) { e_debug(storage->event, "db: ldap_search(base=%s filter=%s) returned entry: %s", request->base, request->filter, ldap_get_dn(conn->ld, res->msg)); } } if (res == NULL && !final_result) { /* Wait for the final reply */ request->failed = TRUE; return TRUE; } if (request->failed) res = NULL; if (final_result) { conn->pending_count--; aqueue_delete(conn->request_queue, idx); } T_BEGIN { request->callback(conn, request, res == NULL ? NULL : res->msg); } T_END; if (idx > 0) { /* See if there are timed out requests */ db_ldap_abort_requests(conn, idx, DB_LDAP_REQUEST_LOST_TIMEOUT_SECS, TRUE, "Request lost"); } return TRUE; } static void db_ldap_result_unref(struct db_ldap_result **_res) { struct db_ldap_result *res = *_res; *_res = NULL; i_assert(res->refcount > 0); if (--res->refcount == 0) { ldap_msgfree(res->msg); i_free(res); } } static void db_ldap_request_free(struct ldap_request *request) { if (request->result != NULL) db_ldap_result_unref(&request->result); } static void db_ldap_handle_result(struct ldap_connection *conn, struct db_ldap_result *res) { struct sieve_storage *storage = &conn->lstorage->storage; struct ldap_request *request; unsigned int idx; int msgid; msgid = ldap_msgid(res->msg); if (msgid == conn->default_bind_msgid) { db_ldap_default_bind_finished(conn, res); return; } request = db_ldap_find_request(conn, msgid, &idx); if (request == NULL) { e_error(storage->event, "db: Reply with unknown msgid %d", msgid); return; } if (db_ldap_handle_request_result(conn, request, idx, res)) db_ldap_request_free(request); } static void ldap_input(struct ldap_connection *conn) { struct sieve_storage *storage = &conn->lstorage->storage; struct timeval timeout; struct db_ldap_result *res; LDAPMessage *msg; time_t prev_reply_diff; int ret; do { if (conn->ld == NULL) return; i_zero(&timeout); ret = ldap_result(conn->ld, LDAP_RES_ANY, 0, &timeout, &msg); #ifdef OPENLDAP_ASYNC_WORKAROUND if (ret == 0) { /* Try again, there may be another in buffer */ ret = ldap_result(conn->ld, LDAP_RES_ANY, 0, &timeout, &msg); } #endif if (ret <= 0) break; res = i_new(struct db_ldap_result, 1); res->refcount = 1; res->msg = msg; db_ldap_handle_result(conn, res); db_ldap_result_unref(&res); } while (conn->io != NULL); prev_reply_diff = ioloop_time - conn->last_reply_stamp; conn->last_reply_stamp = ioloop_time; if (ret > 0) { /* Input disabled, continue once it's enabled */ i_assert(conn->io == NULL); } else if (ret == 0) { /* Send more requests */ while (db_ldap_request_queue_next(conn)) ; } else if (ldap_get_errno(conn) != LDAP_SERVER_DOWN) { e_error(storage->event, "db: ldap_result() failed: %s", ldap_get_error(conn)); ldap_conn_reconnect(conn); } else if (aqueue_count(conn->request_queue) > 0 || prev_reply_diff < DB_LDAP_IDLE_RECONNECT_SECS) { e_error(storage->event, "db: Connection lost to LDAP server, reconnecting"); ldap_conn_reconnect(conn); } else { /* Server probably disconnected an idle connection. don't reconnect until the next request comes. */ db_ldap_conn_close(conn); } } #ifdef HAVE_LDAP_SASL static int sasl_interact(LDAP *ld ATTR_UNUSED, unsigned flags ATTR_UNUSED, void *defaults, void *interact) { struct db_ldap_sasl_bind_context *context = defaults; sasl_interact_t *in; const char *str; for (in = interact; in->id != SASL_CB_LIST_END; in++) { switch (in->id) { case SASL_CB_GETREALM: str = context->realm; break; case SASL_CB_AUTHNAME: str = context->authcid; break; case SASL_CB_USER: str = context->authzid; break; case SASL_CB_PASS: str = context->passwd; break; default: str = NULL; break; } if (str != NULL) { in->len = strlen(str); in->result = str; } } return LDAP_SUCCESS; } #endif static void ldap_connection_timeout(struct ldap_connection *conn) { struct sieve_storage *storage = &conn->lstorage->storage; i_assert(conn->conn_state == LDAP_CONN_STATE_BINDING); e_error(storage->event, "db: Initial binding to LDAP server timed out"); db_ldap_conn_close(conn); } static int db_ldap_bind(struct ldap_connection *conn) { const struct sieve_ldap_settings *set = conn->lstorage->ldap_set; int msgid; i_assert(conn->conn_state != LDAP_CONN_STATE_BINDING); i_assert(conn->default_bind_msgid == -1); i_assert(conn->pending_count == 0); msgid = ldap_bind(conn->ld, set->auth_dn, set->auth_dn_password, LDAP_AUTH_SIMPLE); if (msgid == -1) { i_assert(ldap_get_errno(conn) != LDAP_SUCCESS); if (db_ldap_connect_finish(conn, ldap_get_errno(conn)) < 0) { /* Lost connection, close it */ db_ldap_conn_close(conn); } return -1; } conn->conn_state = LDAP_CONN_STATE_BINDING; conn->default_bind_msgid = msgid; timeout_remove(&conn->to); conn->to = timeout_add(DB_LDAP_REQUEST_LOST_TIMEOUT_SECS*1000, ldap_connection_timeout, conn); return 0; } static int db_ldap_get_fd(struct ldap_connection *conn) { struct sieve_storage *storage = &conn->lstorage->storage; int ret; /* Get the connection's fd */ ret = ldap_get_option(conn->ld, LDAP_OPT_DESC, &conn->fd); if (ret != LDAP_SUCCESS) { e_error(storage->event, "db: Can't get connection fd: %s", ldap_err2string(ret)); return -1; } if (conn->fd <= STDERR_FILENO) { /* Solaris LDAP library seems to be broken */ e_error(storage->event, "db: Buggy LDAP library returned wrong fd: %d", conn->fd); return -1; } i_assert(conn->fd != -1); net_set_nonblock(conn->fd, TRUE); return 0; } static int db_ldap_set_opt(struct ldap_connection *conn, int opt, const void *value, const char *optname, const char *value_str) { struct sieve_storage *storage = &conn->lstorage->storage; int ret; ret = ldap_set_option(conn->ld, opt, value); if (ret != LDAP_SUCCESS) { e_error(storage->event, "db: Can't set option %s to %s: %s", optname, value_str, ldap_err2string(ret)); return -1; } return 0; } static int db_ldap_set_options(struct ldap_connection *conn) { const struct sieve_ldap_settings *set = conn->lstorage->ldap_set; struct sieve_storage *storage = &conn->lstorage->storage; unsigned int ldap_version; const char *error; if (db_ldap_set_opt(conn, LDAP_OPT_DEREF, &set->parsed.deref, "ldap_deref", set->deref) < 0) return -1; #ifdef LDAP_OPT_DEBUG_LEVEL if (set->debug_level != 0) { int value = set->debug_level; if (db_ldap_set_opt(conn, LDAP_OPT_DEBUG_LEVEL, &value, "ldap_debug_level", dec2str(set->debug_level)) < 0) return -1; } #endif if (set->version < 3) { if (!array_is_empty(&set->auth_sasl_mechanisms)) { e_error(storage->event, "db: ldap_auth_sasl_mechanisms requires ldap_version=3"); return -1; } if (set->starttls) { e_error(storage->event, "db: ldap_starttls=yes requires ldap_version=3"); return -1; } } ldap_version = set->version; if (db_ldap_set_opt(conn, LDAP_OPT_PROTOCOL_VERSION, &ldap_version, "ldap_version", dec2str(ldap_version)) < 0) return -1; if (ldap_set_tls_options(conn->ld, set->starttls, set->uris, conn->lstorage->ssl_set, &error) < 0) { e_error(storage->event, "db: %s", error); return -1; } return 0; } int sieve_ldap_db_connect(struct ldap_connection *conn) { const struct sieve_ldap_settings *set = conn->lstorage->ldap_set; struct sieve_storage *storage = &conn->lstorage->storage; struct timeval start, end; bool debug; int ret; if (conn->conn_state != LDAP_CONN_STATE_DISCONNECTED) return 0; debug = set->debug_level > 0; if (debug) i_gettimeofday(&start); i_assert(conn->pending_count == 0); if (conn->ld == NULL) { if (ldap_initialize(&conn->ld, set->uris) != LDAP_SUCCESS) { e_error(storage->event, "db: " "ldap_init() failed with uris: %s", set->uris); return -1; } if (db_ldap_set_options(conn) < 0) return -1; } if (set->starttls) { ret = ldap_start_tls_s(conn->ld, NULL, NULL); if (ret != LDAP_SUCCESS) { if (ret == LDAP_OPERATIONS_ERROR && *set->uris != '\0' && str_begins_with(set->uris, "ldaps:")) { e_error(storage->event, "db: " "Don't use both ldap_starttls=yes and ldaps URI"); } e_error(storage->event, "db: " "ldap_start_tls_s() failed: %s", ldap_err2string(ret)); return -1; } } if (!array_is_empty(&set->auth_sasl_mechanisms)) { #ifdef HAVE_LDAP_SASL struct db_ldap_sasl_bind_context context; i_zero(&context); context.authcid = set->auth_dn; context.passwd = set->auth_dn_password; context.realm = set->auth_sasl_realm; context.authzid = set->auth_sasl_authz_id; const char *mechs = t_array_const_string_join( &set->auth_sasl_mechanisms, " "); /* There doesn't seem to be a way to do SASL binding asynchronously.. */ ret = ldap_sasl_interactive_bind_s(conn->ld, NULL, mechs, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, &context); if (db_ldap_connect_finish(conn, ret) < 0) return -1; #else e_error(storage->event, "db: " "ldap_auth_sasl_mechanisms is set, but no SASL support compiled in"); return -1; #endif conn->conn_state = LDAP_CONN_STATE_BOUND; } else { if (db_ldap_bind(conn) < 0) return -1; } if (debug) { i_gettimeofday(&end); long long msecs = timeval_diff_msecs(&end, &start); e_debug(storage->event, "db: " "Initialization took %lld msecs", msecs); } if (db_ldap_get_fd(conn) < 0) return -1; conn->io = io_add(conn->fd, IO_READ, ldap_input, conn); return 0; } void db_ldap_enable_input(struct ldap_connection *conn, bool enable) { if (!enable) { io_remove(&conn->io); } else { if (conn->io == NULL && conn->fd != -1) { conn->io = io_add(conn->fd, IO_READ, ldap_input, conn); ldap_input(conn); } } } static void db_ldap_disconnect_timeout(struct ldap_connection *conn) { db_ldap_abort_requests(conn, UINT_MAX, DB_LDAP_REQUEST_DISCONNECT_TIMEOUT_SECS, FALSE, "Aborting (timeout), we're not connected to LDAP server"); if (aqueue_count(conn->request_queue) == 0) { /* no requests left, remove this timeout handler */ timeout_remove(&conn->to); } } static void db_ldap_conn_close(struct ldap_connection *conn) { struct ldap_request *const *requests, *request; unsigned int i; conn->conn_state = LDAP_CONN_STATE_DISCONNECTED; conn->default_bind_msgid = -1; timeout_remove(&conn->to); if (conn->pending_count != 0) { requests = array_idx(&conn->request_array, 0); for (i = 0; i < conn->pending_count; i++) { request = requests[aqueue_idx(conn->request_queue, i)]; i_assert(request->msgid != -1); request->msgid = -1; } conn->pending_count = 0; } if (conn->ld != NULL) { ldap_unbind(conn->ld); conn->ld = NULL; } conn->fd = -1; /* The fd may have already been closed before ldap_unbind(), so we'll have to use io_remove_closed(). */ io_remove_closed(&conn->io); if (aqueue_count(conn->request_queue) > 0) { conn->to = timeout_add( DB_LDAP_REQUEST_DISCONNECT_TIMEOUT_SECS * 1000/2, db_ldap_disconnect_timeout, conn); } } struct ldap_field_find_context { ARRAY_TYPE(string) attr_names; pool_t pool; }; #define IS_LDAP_ESCAPED_CHAR(c) \ ((c) == '*' || (c) == '(' || (c) == ')' || (c) == '\\') const char *ldap_escape(const char *str) { const char *p; string_t *ret; for (p = str; *p != '\0'; p++) { if (IS_LDAP_ESCAPED_CHAR(*p)) break; } if (*p == '\0') return str; ret = t_str_new((size_t) (p - str) + 64); str_append_data(ret, str, (size_t) (p - str)); for (; *p != '\0'; p++) { if (IS_LDAP_ESCAPED_CHAR(*p)) str_append_c(ret, '\\'); str_append_c(ret, *p); } return str_c(ret); } struct ldap_connection *sieve_ldap_db_init(struct sieve_ldap_storage *lstorage) { struct ldap_connection *conn; pool_t pool; pool = pool_alloconly_create("ldap_connection", 1024); conn = p_new(pool, struct ldap_connection, 1); conn->pool = pool; conn->refcount = 1; conn->lstorage = lstorage; conn->conn_state = LDAP_CONN_STATE_DISCONNECTED; conn->default_bind_msgid = -1; conn->fd = -1; i_array_init(&conn->request_array, 512); conn->request_queue = aqueue_init(&conn->request_array.arr); conn->next = ldap_connections; ldap_connections = conn; return conn; } void sieve_ldap_db_unref(struct ldap_connection **_conn) { struct ldap_connection *conn = *_conn; struct ldap_connection **p; if (conn == NULL) return; *_conn = NULL; i_assert(conn->refcount >= 0); if (--conn->refcount > 0) return; for (p = &ldap_connections; *p != NULL; p = &(*p)->next) { if (*p == conn) { *p = conn->next; break; } } db_ldap_abort_requests(conn, UINT_MAX, 0, FALSE, "Shutting down"); i_assert(conn->pending_count == 0); db_ldap_conn_close(conn); i_assert(conn->to == NULL); array_free(&conn->request_array); aqueue_deinit(&conn->request_queue); pool_unref(&conn->pool); } static void db_ldap_switch_ioloop(struct ldap_connection *conn) { if (conn->to != NULL) conn->to = io_loop_move_timeout(&conn->to); if (conn->io != NULL) conn->io = io_loop_move_io(&conn->io); } static void db_ldap_wait(struct ldap_connection *conn) { struct sieve_storage *storage = &conn->lstorage->storage; struct ioloop *prev_ioloop = current_ioloop; i_assert(conn->ioloop == NULL); if (aqueue_count(conn->request_queue) == 0) return; conn->ioloop = io_loop_create(); db_ldap_switch_ioloop(conn); /* Either we're waiting for network I/O or we're getting out of a callback using timeout_add_short(0) */ i_assert(io_loop_have_ios(conn->ioloop) || io_loop_have_immediate_timeouts(conn->ioloop)); do { e_debug(storage->event, "db: " "Waiting for %d requests to finish", aqueue_count(conn->request_queue)); io_loop_run(conn->ioloop); } while (aqueue_count(conn->request_queue) > 0); e_debug(storage->event, "db: All requests finished"); current_ioloop = prev_ioloop; db_ldap_switch_ioloop(conn); current_ioloop = conn->ioloop; io_loop_destroy(&conn->ioloop); } static void sieve_ldap_db_script_free(unsigned char *script) { i_free(script); } static int sieve_ldap_db_get_script_modattr(struct ldap_connection *conn, LDAPMessage *entry, pool_t pool, const char **modattr_r) { const struct sieve_ldap_storage_settings *set = conn->lstorage->set; struct sieve_storage *storage = &conn->lstorage->storage; char *attr, **vals; BerElement *ber; *modattr_r = NULL; attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { if (strcmp(attr, set->modified_attribute) == 0) { vals = ldap_get_values(conn->ld, entry, attr); if (vals == NULL || vals[0] == NULL) return 0; if (vals[1] != NULL) { e_warning(storage->event, "db: " "Search returned more than one Sieve modified attribute '%s'; " "using only the first one.", set->modified_attribute); } *modattr_r = p_strdup(pool, vals[0]); ldap_value_free(vals); ldap_memfree(attr); return 1; } ldap_memfree(attr); attr = ldap_next_attribute(conn->ld, entry, ber); } ber_free(ber, 0); return 0; } static int sieve_ldap_db_get_script(struct ldap_connection *conn, LDAPMessage *entry, struct istream **script_r) { const struct sieve_ldap_storage_settings *set = conn->lstorage->set; struct sieve_storage *storage = &conn->lstorage->storage; char *attr; unsigned char *data; size_t size; struct berval **vals; BerElement *ber; attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { if (strcmp(attr, set->script_attribute) == 0) { vals = ldap_get_values_len(conn->ld, entry, attr); if (vals == NULL || vals[0] == NULL) return 0; if (vals[1] != NULL) { e_warning(storage->event, "db: " "Search returned more than one Sieve script attribute '%s'; " "using only the first one.", set->script_attribute); } size = vals[0]->bv_len; data = i_malloc(size); e_debug(storage->event, "db: " "Found script with length %zu", size); memcpy(data, vals[0]->bv_val, size); ldap_value_free_len(vals); ldap_memfree(attr); *script_r = i_stream_create_from_data(data, size); i_stream_add_destroy_callback( *script_r, sieve_ldap_db_script_free, data); return 1; } ldap_memfree(attr); attr = ldap_next_attribute(conn->ld, entry, ber); } ber_free(ber, 0); return 0; } const struct var_expand_table auth_request_var_expand_static_tab[] = { { .key = "user", .value = NULL }, { .key = "username", .value = NULL }, { .key = "domain", .value = NULL }, { .key = "home", .value = NULL }, { .key = "name", .value = NULL }, VAR_EXPAND_TABLE_END }; static const struct var_expand_table * db_ldap_get_var_expand_table(struct ldap_connection *conn, const char *name) { struct sieve_ldap_storage *lstorage = conn->lstorage; struct sieve_instance *svinst = lstorage->storage.svinst; const unsigned int auth_count = N_ELEMENTS(auth_request_var_expand_static_tab); struct var_expand_table *tab; /* Keep the extra fields at the beginning. the last static_tab field contains the ending NULL-fields. */ tab = t_malloc_no0((auth_count) * sizeof(*tab)); memcpy(tab, auth_request_var_expand_static_tab, auth_count * sizeof(*tab)); tab[0].value = ldap_escape(svinst->username); tab[1].value = ldap_escape(t_strcut(svinst->username, '@')); tab[2].value = strchr(svinst->username, '@'); if (tab[2].value != NULL) tab[2].value = ldap_escape(tab[2].value+1); tab[3].value = ldap_escape(svinst->home_dir); tab[4].value = ldap_escape(name); return tab; } struct sieve_ldap_script_lookup_request { struct ldap_request request; unsigned int entries; const char *result_dn; const char *result_modattr; }; static void sieve_ldap_lookup_script_callback(struct ldap_connection *conn, struct ldap_request *request, LDAPMessage *res) { struct sieve_storage *storage = &conn->lstorage->storage; struct sieve_ldap_script_lookup_request *srequest = container_of(request, struct sieve_ldap_script_lookup_request, request); if (res == NULL) { io_loop_stop(conn->ioloop); return; } if (ldap_msgtype(res) != LDAP_RES_SEARCH_RESULT) { if (srequest->result_dn == NULL) { srequest->result_dn = p_strdup( request->pool, ldap_get_dn(conn->ld, res)); (void)sieve_ldap_db_get_script_modattr( conn, res, request->pool, &srequest->result_modattr); } else if (srequest->entries++ == 0) { e_warning(storage->event, "db: " "Search returned more than one entry for Sieve script; " "using only the first one."); } } else { io_loop_stop(conn->ioloop); return; } } int sieve_ldap_db_lookup_script(struct ldap_connection *conn, const char *name, const char **dn_r, const char **modattr_r) { struct sieve_ldap_storage *lstorage = conn->lstorage; struct sieve_storage *storage = &lstorage->storage; const struct sieve_ldap_settings *ldap_set = lstorage->ldap_set; const struct sieve_ldap_storage_settings *set = lstorage->set; struct sieve_ldap_script_lookup_request *request; char **attr_names; const char *error; string_t *str; pool_t pool = pool_alloconly_create( "sieve_ldap_script_lookup_request", 512); request = p_new(pool, struct sieve_ldap_script_lookup_request, 1); request->request.pool = pool; const struct var_expand_params params = { .table = db_ldap_get_var_expand_table(conn, name), }; str = t_str_new(512); if (var_expand(str, ldap_set->base, ¶ms, &error) < 0) { e_error(storage->event, "db: " "Failed to expand base=%s: %s", ldap_set->base, error); return -1; } request->request.base = p_strdup(pool, str_c(str)); attr_names = p_new(pool, char *, 3); attr_names[0] = p_strdup(pool, set->modified_attribute); str_truncate(str, 0); if (var_expand(str, set->filter, ¶ms, &error) < 0) { e_error(storage->event, "db: " "Failed to expand sieve_ldap_filter=%s: %s", set->filter, error); return -1; } request->request.scope = ldap_set->parsed.scope; request->request.filter = p_strdup(pool, str_c(str)); request->request.attributes = attr_names; e_debug(storage->event, "base=%s scope=%s filter=%s fields=%s", request->request.base, ldap_set->scope, request->request.filter, t_strarray_join((const char **)attr_names, ",")); request->request.callback = sieve_ldap_lookup_script_callback; db_ldap_request(conn, &request->request); db_ldap_wait(conn); *dn_r = t_strdup(request->result_dn); *modattr_r = t_strdup(request->result_modattr); pool_unref(&request->request.pool); return (*dn_r == NULL ? 0 : 1); } struct sieve_ldap_script_read_request { struct ldap_request request; unsigned int entries; struct istream *result; }; static void sieve_ldap_read_script_callback(struct ldap_connection *conn, struct ldap_request *request, LDAPMessage *res) { struct sieve_storage *storage = &conn->lstorage->storage; struct sieve_ldap_script_read_request *srequest = container_of(request, struct sieve_ldap_script_read_request, request); if (res == NULL) { io_loop_stop(conn->ioloop); return; } if (ldap_msgtype(res) != LDAP_RES_SEARCH_RESULT) { if (srequest->result == NULL) { (void)sieve_ldap_db_get_script(conn, res, &srequest->result); } else { e_error(storage->event, "db: " "Search returned more than one entry for Sieve script DN"); i_stream_unref(&srequest->result); } } else { io_loop_stop(conn->ioloop); return; } } int sieve_ldap_db_read_script(struct ldap_connection *conn, const char *dn, struct istream **script_r) { struct sieve_ldap_storage *lstorage = conn->lstorage; struct sieve_storage *storage = &lstorage->storage; const struct sieve_ldap_storage_settings *set = lstorage->set; struct sieve_ldap_script_read_request *request; char **attr_names; pool_t pool = pool_alloconly_create( "sieve_ldap_script_read_request", 512); request = p_new(pool, struct sieve_ldap_script_read_request, 1); request->request.pool = pool; request->request.base = p_strdup(pool, dn); attr_names = p_new(pool, char *, 3); attr_names[0] = p_strdup(pool, set->script_attribute); request->request.scope = LDAP_SCOPE_BASE; request->request.filter = "(objectClass=*)"; request->request.attributes = attr_names; e_debug(storage->event, "base=%s scope=base filter=%s fields=%s", request->request.base, request->request.filter, t_strarray_join((const char **)attr_names, ",")); request->request.callback = sieve_ldap_read_script_callback; db_ldap_request(conn, &request->request); db_ldap_wait(conn); *script_r = request->result; pool_unref(&request->request.pool); return (*script_r == NULL ? 0 : 1); } #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-db.h0000644000175100001700000000666115100335616026627 0ustar00buildbotbuildbot00000000000000#ifndef DB_LDAP_H #define DB_LDAP_H /* Functions like ldap_bind() have been deprecated in OpenLDAP 2.3 This define enables them until the code here can be refactored. */ #define LDAP_DEPRECATED 1 /* Maximum number of pending requests before delaying new requests. */ #define DB_LDAP_MAX_PENDING_REQUESTS 8 /* If LDAP connection is down, fail requests after waiting for this long. */ #define DB_LDAP_REQUEST_DISCONNECT_TIMEOUT_SECS 4 /* If request is still in queue after this many seconds and other requests have been replied, assume the request was lost and abort it. */ #define DB_LDAP_REQUEST_LOST_TIMEOUT_SECS 60 /* If server disconnects us, don't reconnect if no requests have been sent for this many seconds. */ #define DB_LDAP_IDLE_RECONNECT_SECS 60 #include #define HAVE_LDAP_SASL #ifdef HAVE_SASL_SASL_H # include #elif defined (HAVE_SASL_H) # include #else # undef HAVE_LDAP_SASL #endif #ifdef LDAP_OPT_X_TLS # define OPENLDAP_TLS_OPTIONS #endif #if !defined(SASL_VERSION_MAJOR) || SASL_VERSION_MAJOR < 2 # undef HAVE_LDAP_SASL #endif #ifndef LDAP_SASL_QUIET # define LDAP_SASL_QUIET 0 /* Doesn't exist in Solaris LDAP */ #endif /* Older versions may require calling ldap_result() twice */ #if LDAP_VENDOR_VERSION <= 20112 # define OPENLDAP_ASYNC_WORKAROUND #endif /* Solaris LDAP library doesn't have LDAP_OPT_SUCCESS */ #ifndef LDAP_OPT_SUCCESS # define LDAP_OPT_SUCCESS LDAP_SUCCESS #endif struct ldap_connection; struct ldap_request; typedef void db_search_callback_t(struct ldap_connection *conn, struct ldap_request *request, LDAPMessage *res); struct ldap_request { pool_t pool; /* msgid for sent requests, -1 if not sent */ int msgid; /* timestamp when request was created */ time_t create_time; bool failed; db_search_callback_t *callback; const char *base; const char *filter; int scope; char **attributes; struct db_ldap_result *result; }; enum ldap_connection_state { /* Not connected */ LDAP_CONN_STATE_DISCONNECTED, /* Binding - either to default dn or doing auth bind */ LDAP_CONN_STATE_BINDING, /* Bound */ LDAP_CONN_STATE_BOUND }; struct ldap_connection { struct ldap_connection *next; struct sieve_ldap_storage *lstorage; pool_t pool; int refcount; LDAP *ld; enum ldap_connection_state conn_state; int default_bind_msgid; int fd; struct io *io; struct timeout *to; struct ioloop *ioloop; /* Request queue contains sent requests at tail (msgid != -1) and queued requests at head (msgid == -1). */ struct aqueue *request_queue; ARRAY(struct ldap_request *) request_array; /* Number of messages in queue with msgid != -1 */ unsigned int pending_count; /* Timestamp when we last received a reply */ time_t last_reply_stamp; }; /* Send/queue request */ void db_ldap_request(struct ldap_connection *conn, struct ldap_request *request); void db_ldap_enable_input(struct ldap_connection *conn, bool enable); const char *ldap_escape(const char *str); const char *ldap_get_error(struct ldap_connection *conn); int sieve_ldap_db_connect(struct ldap_connection *conn); struct ldap_connection * sieve_ldap_db_init(struct sieve_ldap_storage *lstorage); void sieve_ldap_db_unref(struct ldap_connection **conn); int sieve_ldap_db_lookup_script(struct ldap_connection *conn, const char *name, const char **dn_r, const char **modattr_r); int sieve_ldap_db_read_script(struct ldap_connection *conn, const char *dn, struct istream **script_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/storage/ldap/sieve-ldap-script.c0000644000175100001700000002040115100335616027525 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "time-util.h" #include "istream.h" #include "sieve-ldap-storage.h" #if defined(SIEVE_BUILTIN_LDAP) || defined(PLUGIN_BUILD) #include "str.h" #include "strfuncs.h" #include "sieve-error.h" #include "sieve-dump.h" #include "sieve-binary.h" /* * Script file implementation */ static struct sieve_ldap_script *sieve_ldap_script_alloc(void) { struct sieve_ldap_script *lscript; pool_t pool; pool = pool_alloconly_create("sieve_ldap_script", 1024); lscript = p_new(pool, struct sieve_ldap_script, 1); lscript->script = sieve_ldap_script; lscript->script.pool = pool; return lscript; } struct sieve_ldap_script * sieve_ldap_script_init(struct sieve_ldap_storage *lstorage, const char *name) { struct sieve_storage *storage = &lstorage->storage; struct sieve_ldap_script *lscript = NULL; if (name == NULL || *name == '\0') name = SIEVE_LDAP_SCRIPT_DEFAULT; lscript = sieve_ldap_script_alloc(); sieve_script_init(&lscript->script, storage, &sieve_ldap_script, name); return lscript; } static int sieve_ldap_script_open(struct sieve_script *script) { struct sieve_ldap_script *lscript = container_of(script, struct sieve_ldap_script, script); struct sieve_storage *storage = script->storage; struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); int ret; if (sieve_ldap_db_connect(lstorage->conn) < 0) { sieve_storage_set_critical( storage, "Failed to connect to LDAP database"); return -1; } ret = sieve_ldap_db_lookup_script(lstorage->conn, script->name, &lscript->dn, &lscript->modattr); if (ret <= 0) { if (ret == 0) { e_debug(script->event, "Script entry not found"); sieve_script_set_not_found_error(script, NULL); } else { sieve_script_set_internal_error(script); } return -1; } return 0; } static int sieve_ldap_script_get_stream(struct sieve_script *script, struct istream **stream_r) { struct sieve_ldap_script *lscript = container_of(script, struct sieve_ldap_script, script); struct sieve_storage *storage = script->storage; struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); int ret; i_assert(lscript->dn != NULL); ret = sieve_ldap_db_read_script(lstorage->conn, lscript->dn, stream_r); if (ret <= 0) { if (ret == 0) { e_debug(script->event, "Script attribute not found"); sieve_script_set_not_found_error(script, NULL); } else { sieve_script_set_internal_error(script); } return -1; } return 0; } static int sieve_ldap_script_binary_read_metadata(struct sieve_script *script, struct sieve_binary_block *sblock, sieve_size_t *offset) { struct sieve_ldap_script *lscript = container_of(script, struct sieve_ldap_script, script); struct sieve_storage *storage = script->storage; struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); string_t *dn, *modattr; // FIXME: Maybe detect config changes somehow to trigger recompile /* Open script if not open already */ if (lscript->dn == NULL && sieve_script_open(script, NULL) < 0) return 0; /* If modattr not found, recompile always */ if (lscript->modattr == NULL || *lscript->modattr == '\0') { e_error(script->event, "LDAP entry for script '%s' " "has no modified attribute '%s'", sieve_script_label(script), lstorage->set->modified_attribute); return 0; } /* Compare DN in binary and from search result */ if (!sieve_binary_read_string(sblock, offset, &dn)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid DN", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } i_assert(lscript->dn != NULL); if (strcmp(str_c(dn), lscript->dn) != 0) { e_debug(script->event, "Binary '%s' reports different LDAP DN for script '%s' " "('%s' rather than '%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(dn), lscript->dn); return 0; } /* Compare modattr in binary and from search result */ if (!sieve_binary_read_string(sblock, offset, &modattr)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid modified attribute", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } if (strcmp(str_c(modattr), lscript->modattr) != 0) { e_debug(script->event, "Binary '%s' reports different modified attribute content " "for script '%s' ('%s' rather than '%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(modattr), lscript->modattr); return 0; } return 1; } static void sieve_ldap_script_binary_write_metadata(struct sieve_script *script, struct sieve_binary_block *sblock) { struct sieve_ldap_script *lscript = container_of(script, struct sieve_ldap_script, script); sieve_binary_emit_cstring(sblock, lscript->dn); if (lscript->modattr == NULL) sieve_binary_emit_cstring(sblock, ""); else sieve_binary_emit_cstring(sblock, lscript->modattr); } static bool sieve_ldap_script_binary_dump_metadata(struct sieve_script *script ATTR_UNUSED, struct sieve_dumptime_env *denv, struct sieve_binary_block *sblock, sieve_size_t *offset) { string_t *dn, *modattr; if (!sieve_binary_read_string(sblock, offset, &dn)) return FALSE; sieve_binary_dumpf(denv, "ldap.dn = %s\n", str_c(dn)); if (!sieve_binary_read_string(sblock, offset, &modattr)) return FALSE; sieve_binary_dumpf(denv, "ldap.mod_attr = %s\n", str_c(modattr)); return TRUE; } static const char * sieve_ldap_script_get_bin_path(struct sieve_ldap_script *lscript) { struct sieve_script *script = &lscript->script; struct sieve_storage *storage = script->storage; if (lscript->bin_path == NULL) { if (storage->bin_path == NULL) return NULL; lscript->bin_path = p_strconcat( script->pool, storage->bin_path, "/", sieve_binfile_from_name(script->name), NULL); } return lscript->bin_path; } static int sieve_ldap_script_binary_load(struct sieve_script *script, struct sieve_binary **sbin_r) { struct sieve_ldap_script *lscript = container_of(script, struct sieve_ldap_script, script); return sieve_script_binary_load_default( script, sieve_ldap_script_get_bin_path(lscript), sbin_r); } static int sieve_ldap_script_binary_save(struct sieve_script *script, struct sieve_binary *sbin, bool update) { struct sieve_ldap_script *lscript = container_of(script, struct sieve_ldap_script, script); return sieve_script_binary_save_default( script, sbin, sieve_ldap_script_get_bin_path(lscript), update, 0600); } const struct sieve_script sieve_ldap_script = { .driver_name = SIEVE_LDAP_STORAGE_DRIVER_NAME, .v = { .open = sieve_ldap_script_open, .get_stream = sieve_ldap_script_get_stream, .binary_read_metadata = sieve_ldap_script_binary_read_metadata, .binary_write_metadata = sieve_ldap_script_binary_write_metadata, .binary_dump_metadata = sieve_ldap_script_binary_dump_metadata, .binary_load = sieve_ldap_script_binary_load, .binary_save = sieve_ldap_script_binary_save, }, }; /* * Script sequence */ struct sieve_ldap_script_sequence { bool done:1; }; int sieve_ldap_script_sequence_init(struct sieve_script_sequence *sseq) { struct sieve_ldap_script_sequence *lseq = NULL; /* Create sequence object */ lseq = i_new(struct sieve_ldap_script_sequence, 1); sseq->storage_data = lseq; return 0; } int sieve_ldap_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r) { struct sieve_ldap_script_sequence *lseq = sseq->storage_data; struct sieve_storage *storage = sseq->storage; struct sieve_ldap_storage *lstorage = container_of(storage, struct sieve_ldap_storage, storage); struct sieve_ldap_script *lscript; if (lseq->done) return 0; lseq->done = TRUE; lscript = sieve_ldap_script_init(lstorage, storage->script_name); if (sieve_script_open(&lscript->script, NULL) < 0) { struct sieve_script *script = &lscript->script; sieve_script_unref(&script); return -1; } *script_r = &lscript->script; return 1; } void sieve_ldap_script_sequence_destroy(struct sieve_script_sequence *sseq) { struct sieve_ldap_script_sequence *lseq = sseq->storage_data; i_free(lseq); } #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-storage-settings.c0000644000175100001700000000753215100335616026233 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "array.h" #include "sort.h" #include "settings.h" #include "settings-parser.h" #include "sieve-script.h" #include "sieve-storage.h" #include "sieve-storage-settings.h" static bool sieve_storage_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \ "sieve_"#name, name, \ struct sieve_storage_settings) static const struct setting_filter_array_order sieve_storage_order_precedence = { .info = &sieve_storage_setting_parser_info, .field_name = "sieve_script_precedence", }; static const struct setting_define sieve_storage_setting_defines[] = { DEF(STR, script_storage), DEF(UINT, script_precedence), DEF(STR, script_type), DEF(BOOLLIST, script_cause), DEF(STR, script_driver), DEF(STR, script_name), DEF(STR, script_bin_path), DEF(SIZE, quota_storage_size), DEF(UINT, quota_script_count), { .type = SET_FILTER_ARRAY, .key = "sieve_script", .offset = offsetof(struct sieve_storage_settings, storages), .filter_array_field_name = "sieve_script_storage", .filter_array_order = &sieve_storage_order_precedence }, SETTING_DEFINE_LIST_END, }; static const struct sieve_storage_settings sieve_storage_default_settings = { .script_storage = "", .script_precedence = UINT_MAX, .script_type = SIEVE_STORAGE_TYPE_PERSONAL, .script_cause = ARRAY_INIT, .script_driver = "file", .script_name = "", .script_bin_path = "", .quota_storage_size = 0, .quota_script_count = 0, .storages = ARRAY_INIT, }; const struct setting_parser_info sieve_storage_setting_parser_info = { .name = "sieve_storage", .defines = sieve_storage_setting_defines, .defaults = &sieve_storage_default_settings, .struct_size = sizeof(struct sieve_storage_settings), .pool_offset1 = 1 + offsetof(struct sieve_storage_settings, pool), .check_func = sieve_storage_settings_check, }; /* */ static bool sieve_storage_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct sieve_storage_settings *set = _set; if (*set->script_storage != '\0' && !sieve_storage_name_is_valid(set->script_storage)) { *error_r = t_strdup_printf( "Invalid script storage name '%s'", str_sanitize(set->script_storage, 128)); return FALSE; } if (*set->script_name != '\0' && !sieve_script_name_is_valid(set->script_name)) { *error_r = t_strdup_printf( "Invalid script name '%s'", str_sanitize(set->script_name, 128)); return FALSE; } if (array_is_created(&set->script_cause)) array_sort(&set->script_cause, i_strcmp_p); return TRUE; } /* */ bool sieve_storage_settings_match_script_type( const struct sieve_storage_settings *set, const char *type) { if (strcasecmp(type, SIEVE_STORAGE_TYPE_ANY) == 0) return TRUE; if (strcasecmp(type, set->script_type) == 0) return TRUE; return FALSE; } bool sieve_storage_settings_match_script_cause( const struct sieve_storage_settings *set, const char *cause) { if (strcasecmp(cause, SIEVE_SCRIPT_CAUSE_ANY) == 0) { /* Any cause will match */ return TRUE; } if (!array_is_created(&set->script_cause)) { /* Causes are not configured for this storage */ if (strcasecmp(set->script_type, SIEVE_STORAGE_TYPE_PERSONAL) == 0) { /* For personal storages the default is to match any cause. */ return TRUE; } if (strcasecmp(cause, SIEVE_SCRIPT_CAUSE_DELIVERY) == 0) { /* The default cause is delivery */ return TRUE; } return FALSE; } /* Causes are configured for this storage: perform lookup */ unsigned int set_cause_count; const char *const *set_cause; set_cause = array_get(&set->script_cause, &set_cause_count); return (i_bsearch(cause, set_cause, set_cause_count, sizeof(const char *), search_strcasecmp) != NULL); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-stringlist.c0000644000175100001700000001425515100335616025133 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str.h" #include "sieve-common.h" #include "sieve-stringlist.h" /* * Default implementation */ int sieve_stringlist_read_all(struct sieve_stringlist *strlist, pool_t pool, const char *const **list_r) { if (strlist->read_all == NULL) { ARRAY(const char *) items; string_t *item; int ret; sieve_stringlist_reset(strlist); p_array_init(&items, pool, 4); item = NULL; while ((ret = sieve_stringlist_next_item(strlist, &item)) > 0) { const char *stritem = p_strdup(pool, str_c(item)); array_append(&items, &stritem, 1); } (void)array_append_space(&items); *list_r = array_idx(&items, 0); return (ret < 0 ? -1 : 1); } return strlist->read_all(strlist, pool, list_r); } int sieve_stringlist_get_length(struct sieve_stringlist *strlist) { if (strlist->get_length == NULL) { string_t *item; int count = 0; int ret; sieve_stringlist_reset(strlist); while ((ret = sieve_stringlist_next_item(strlist, &item)) > 0) count++; sieve_stringlist_reset(strlist); return (ret < 0 ? -1 : count); } return strlist->get_length(strlist); } /* * Single Stringlist */ /* Object */ static int sieve_single_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void sieve_single_stringlist_reset(struct sieve_stringlist *_strlist); static int sieve_single_stringlist_get_length(struct sieve_stringlist *_strlist); struct sieve_single_stringlist { struct sieve_stringlist strlist; string_t *value; bool end:1; bool count_empty:1; }; struct sieve_stringlist * sieve_single_stringlist_create(const struct sieve_runtime_env *renv, string_t *str, bool count_empty) { struct sieve_single_stringlist *strlist; strlist = t_new(struct sieve_single_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = sieve_single_stringlist_next_item; strlist->strlist.reset = sieve_single_stringlist_reset; strlist->strlist.get_length = sieve_single_stringlist_get_length; strlist->count_empty = count_empty; strlist->value = str; return &strlist->strlist; } struct sieve_stringlist * sieve_single_stringlist_create_cstr(const struct sieve_runtime_env *renv, const char *cstr, bool count_empty) { string_t *str = t_str_new_const(cstr, strlen(cstr)); return sieve_single_stringlist_create(renv, str, count_empty); } /* Implementation */ static int sieve_single_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct sieve_single_stringlist *strlist = (struct sieve_single_stringlist *)_strlist; if (strlist->end) { *str_r = NULL; return 0; } *str_r = strlist->value; strlist->end = TRUE; return 1; } static void sieve_single_stringlist_reset(struct sieve_stringlist *_strlist) { struct sieve_single_stringlist *strlist = (struct sieve_single_stringlist *)_strlist; strlist->end = FALSE; } static int sieve_single_stringlist_get_length(struct sieve_stringlist *_strlist) { struct sieve_single_stringlist *strlist = (struct sieve_single_stringlist *)_strlist; return (strlist->count_empty || str_len(strlist->value) > 0 ? 1 : 0); } /* * Index Stringlist */ /* Object */ static int sieve_index_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void sieve_index_stringlist_reset(struct sieve_stringlist *_strlist); static int sieve_index_stringlist_get_length(struct sieve_stringlist *_strlist); static void sieve_index_stringlist_set_trace(struct sieve_stringlist *strlist, bool trace); struct sieve_index_stringlist { struct sieve_stringlist strlist; struct sieve_stringlist *source; int index; bool end:1; }; struct sieve_stringlist * sieve_index_stringlist_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *source, int index) { struct sieve_index_stringlist *strlist; strlist = t_new(struct sieve_index_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = sieve_index_stringlist_next_item; strlist->strlist.reset = sieve_index_stringlist_reset; strlist->strlist.get_length = sieve_index_stringlist_get_length; strlist->strlist.set_trace = sieve_index_stringlist_set_trace; strlist->source = source; strlist->index = index; return &strlist->strlist; } /* Implementation */ static int sieve_index_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct sieve_index_stringlist *strlist = (struct sieve_index_stringlist *)_strlist; int index, ret; if (strlist->end) { *str_r = NULL; return 0; } if (strlist->index < 0) { int len = sieve_stringlist_get_length(strlist->source); if (len < 0) { _strlist->exec_status = strlist->source->exec_status; return -1; } if (len < -strlist->index) { *str_r = NULL; strlist->end = TRUE; return 0; } index = len + 1 + strlist->index; } else { index = strlist->index; } i_assert(index > 0); while (index > 0) { ret = sieve_stringlist_next_item(strlist->source, str_r); if (ret <= 0) { if (ret < 0) { _strlist->exec_status = strlist->source->exec_status; } return ret; } index--; } strlist->end = TRUE; return 1; } static void sieve_index_stringlist_reset(struct sieve_stringlist *_strlist) { struct sieve_index_stringlist *strlist = (struct sieve_index_stringlist *)_strlist; sieve_stringlist_reset(strlist->source); strlist->end = FALSE; } static int sieve_index_stringlist_get_length(struct sieve_stringlist *_strlist) { struct sieve_index_stringlist *strlist = (struct sieve_index_stringlist *)_strlist; int len; len = sieve_stringlist_get_length(strlist->source); if (len < 0) { _strlist->exec_status = strlist->source->exec_status; return -1; } if (strlist->index < 0) { if (-strlist->index >= len) return 0; } else if (strlist->index >= len) { return 0; } return 1; } static void sieve_index_stringlist_set_trace(struct sieve_stringlist *_strlist, bool trace) { struct sieve_index_stringlist *strlist = (struct sieve_index_stringlist *)_strlist; sieve_stringlist_set_trace(strlist->source, trace); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-error-private.h0000644000175100001700000000311715100335616025532 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_ERROR_PRIVATE_H #define SIEVE_ERROR_PRIVATE_H #include "sieve-error.h" /* * Initialization */ void sieve_errors_init(struct sieve_instance *svinst); void sieve_errors_deinit(struct sieve_instance *svinst); /* * Error handler object */ struct sieve_error_handler { pool_t pool; int refcount; struct sieve_instance *svinst; unsigned int max_errors; unsigned int errors; unsigned int warnings; void (*log)(struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags, const char *message); void (*free)(struct sieve_error_handler *ehandler); bool master_log:1; /* this logs through master log facility */ bool log_info:1; /* handle or discard info log */ bool log_debug:1; /* handle or discard debug log */ }; void sieve_error_handler_init(struct sieve_error_handler *ehandler, struct sieve_instance *svinst, pool_t pool, unsigned int max_errors); /* * Direct handler calls */ void sieve_direct_logv(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags, const char *fmt, va_list args) ATTR_FORMAT(5, 0); static inline void ATTR_FORMAT(5, 6) sieve_direct_log(struct sieve_instance *svinst, struct sieve_error_handler *ehandler, const struct sieve_error_params *params, enum sieve_error_flags flags, const char *fmt, ...) { va_list args; va_start(args, fmt); sieve_direct_logv(svinst, ehandler, params, flags, fmt, args); va_end(args); } #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/util/0000755000175100001700000000000015100335667022430 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/util/urn.c0000644000175100001700000003204315100335616023374 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "uri-util.h" #include "urn.h" /* RFC 8141, Section 2 namestring = assigned-name [ rq-components ] [ "#" f-component ] assigned-name = "urn" ":" NID ":" NSS NID = (alphanum) 0*30(ldh) (alphanum) ldh = alphanum / "-" NSS = pchar *(pchar / "/") rq-components = [ "?+" r-component ] [ "?=" q-component ] r-component = pchar *( pchar / "/" / "?" ) q-component = pchar *( pchar / "/" / "?" ) f-component = fragment */ /* * URN parser */ struct urn_parser { struct uri_parser parser; enum urn_parse_flags flags; struct urn *urn; bool normalizing:1; }; const uint16_t urn_alphanum_char_mask = BIT(0); const uint16_t urn_pchar_char_mask = BIT(0) | BIT(1); const uint16_t urn_pchar_slash_char_mask = BIT(0) | BIT(1) | BIT(2); const uint16_t urn_component_char_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3); static unsigned const char urn_char_lookup[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 0, 2, 0, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 4, // 20 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 2, 0, 8, // 30 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, // 50 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 2, 2, 0, // 70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // b0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f0 }; static inline bool urn_char_is_alphanum(unsigned const char ch) { return ((urn_char_lookup[ch] & urn_alphanum_char_mask) != 0); } static inline bool urn_char_is_pchar(unsigned const char ch) { return ((urn_char_lookup[ch] & urn_pchar_char_mask) != 0); } static inline bool urn_char_is_pchar_slash(unsigned const char ch) { return ((urn_char_lookup[ch] & urn_pchar_slash_char_mask) != 0); } static inline bool urn_char_is_component(unsigned const char ch) { return ((urn_char_lookup[ch] & urn_component_char_mask) != 0); } static int urn_parse_scheme(struct urn_parser *urn_parser, const char **scheme_r) { struct uri_parser *parser = &urn_parser->parser; *scheme_r = NULL; if ((urn_parser->flags & URN_PARSE_SCHEME_EXTERNAL) != 0) return 0; if (uri_parse_scheme(parser, scheme_r) <= 0) { parser->cur = parser->begin; return -1; } return 1; } static int uri_parse_nid(struct urn_parser *urn_parser) { struct uri_parser *parser = &urn_parser->parser; struct urn *urn = urn_parser->urn; const unsigned char *first = parser->cur; /* NID = (alphanum) 0*30(ldh) (alphanum) */ if (parser->cur >= parser->end) { parser->error = "URN is empty"; return -1; } /* alphanum */ if (!urn_char_is_alphanum(*parser->cur)) { parser->error = p_strdup_printf(parser->pool, "URN NID begins with invalid character %s", uri_char_sanitize(*parser->cur)); return -1; } parser->cur++; /* 0*30(ldh) */ while (parser->cur < parser->end) { if (!urn_char_is_alphanum(*parser->cur) && *parser->cur != '-') break; if ((parser->cur - first) > 32) break; parser->cur++; } /* alphanum */ if (parser->cur >= parser->end) { parser->error = "URN ends without NSS"; return -1; } if (*parser->cur != ':') { if ((parser->cur - first) > 32) { parser->error = "URN NID is too long"; return -1; } parser->error = p_strdup_printf(parser->pool, "URN NID contains invalid character %s", uri_char_sanitize(*parser->cur)); return -1; } if (!urn_char_is_alphanum(*(parser->cur - 1))) { parser->error = p_strdup_printf(parser->pool, "URN NID ends with invalid character %s", uri_char_sanitize(*(parser->cur - 1))); return -1; } if ((parser->cur - first) < 2) { parser->error = "URN NID is too short"; return -1; } if (urn != NULL) urn->nid = p_strdup_until(parser->pool, first, parser->cur); return 0; } static int uri_parse_nss(struct urn_parser *urn_parser) { struct uri_parser *parser = &urn_parser->parser; struct urn *urn = urn_parser->urn; const unsigned char *first = parser->cur; string_t *nss = NULL; int ret; /* NSS = pchar *(pchar / "/") */ if (parser->cur >= parser->end) { parser->error = "URN NSS is empty"; return -1; } if (!urn_char_is_pchar(*parser->cur)) { parser->error = p_strdup_printf(parser->pool, "URN NSS begins with invalid character %s", uri_char_sanitize(*parser->cur)); return -1; } parser->cur++; if (urn != NULL) nss = t_str_new(128); /* pchar *( pchar / "/" / "?" ) */ while (parser->cur < parser->end) { if (*parser->cur == '%') { const unsigned char *pct = parser->cur; unsigned char ch = 0; ret = uri_parse_pct_encoded(parser, &ch); if (ret < 0) return -1; i_assert(ret > 0); if (urn != NULL) { str_append_data(nss, first, pct - first); if (!urn_parser->normalizing) str_append_c(nss, ch); else str_printfa(nss, "%%%02X", ch); first = parser->cur; } continue; } if (!urn_char_is_pchar_slash(*parser->cur)) break; parser->cur++; } if (parser->cur < parser->end && *parser->cur != '?' && *parser->cur != '#') { parser->error = p_strdup_printf(parser->pool, "URN NSS contains invalid character %s", uri_char_sanitize(*parser->cur)); return -1; } if (urn != NULL) { str_append_data(nss, first, parser->cur - first); urn->nss = p_strdup(parser->pool, str_c(nss)); } return 0; } static int urn_parse_assigned_name(struct urn_parser *urn_parser) { struct uri_parser *parser = &urn_parser->parser; struct urn *urn = urn_parser->urn; const unsigned char *first = parser->cur; /* assigned-name = "urn" ":" NID ":" NSS NID = (alphanum) 0*30(ldh) (alphanum) ldh = alphanum / "-" NSS = pchar *(pchar / "/") The "urn:" prefix is already parsed at this point. */ /* NID */ if (uri_parse_nid(urn_parser) < 0) return -1; /* : */ i_assert(*parser->cur == ':'); parser->cur++; /* NSS */ if (uri_parse_nss(urn_parser) < 0) return -1; if (urn != NULL && !urn_parser->normalizing) { urn->assigned_name = p_strconcat(parser->pool, "urn:", t_strdup_until(first, parser->cur), NULL); } return 0; } static int urn_parse_rq_component(struct urn_parser *urn_parser, bool query, const char **comp_r) { struct uri_parser *parser = &urn_parser->parser; const unsigned char *first = parser->cur; int ret; /* rq-components = [ "?+" r-component ] [ "?=" q-component ] r-component = pchar *( pchar / "/" / "?" ) q-component = pchar *( pchar / "/" / "?" ) */ /* "?" */ if (parser->cur >= parser->end || *parser->cur != '?') return 0; parser->cur++; /* "+" / "=" */ if (parser->cur >= parser->end) { parser->error = "URN assinged name ends in bare '?'"; return -1; } else if (query && *parser->cur == '+') { parser->error = p_strdup_printf(parser->pool, "URN has second R component"); return -1; } else if (!query && *parser->cur == '=') { parser->cur = first; return 0; } else if (*parser->cur != '+' && *parser->cur != '=' ) { parser->error = p_strdup_printf(parser->pool, "URN %sQ component starts with invalid character %s", (query ? "" : "R or "), uri_char_sanitize(*parser->cur)); return -1; } parser->cur++; /* pchar *( pchar / "/" / "?" ) */ while (parser->cur < parser->end) { if (*parser->cur == '%') { unsigned char ch = 0; ret = uri_parse_pct_encoded(parser, &ch); if (ret < 0) return -1; if (ret > 0) continue; } if (*parser->cur == '?' && !query && parser->cur < parser->end && *(parser->cur + 1) == '=') break; if (!urn_char_is_component(*parser->cur)) break; parser->cur++; } if (!parser->parse_prefix && parser->cur < parser->end && (query || *parser->cur != '?') && *parser->cur != '#') { parser->error = p_strdup_printf(parser->pool, "%s component contains invalid character %s", (query ? "Q" : "R"), uri_char_sanitize(*parser->cur)); return -1; } if (comp_r != NULL && !urn_parser->normalizing) *comp_r = p_strdup_until(parser->pool, first+2, parser->cur); return 1; } static int urn_parse_f_component(struct urn_parser *urn_parser) { struct uri_parser *parser = &urn_parser->parser; struct urn *urn = urn_parser->urn; const char *fragment; int ret; /* [ "#" f-component ] f-component = fragment */ ret = uri_parse_fragment(parser, &fragment); if (ret < 0) return -1; if (urn == NULL) return 0; if (ret > 0 && !urn_parser->normalizing) urn->enc_f_component = p_strdup(parser->pool, fragment); return ret; } static int urn_do_parse(struct urn_parser *urn_parser) { struct uri_parser *parser = &urn_parser->parser; struct urn *urn = urn_parser->urn; const char *scheme; int ret; /* "urn:" */ ret = urn_parse_scheme(urn_parser, &scheme); if (ret < 0) { parser->error = "Not a valid URI"; return -1; } if (ret > 0) { i_assert(scheme != NULL); if (strcasecmp(scheme, "urn") != 0) { parser->error = "Not an URN"; return -1; } } /* assigned-name ("urn:" already parsed) */ if (urn_parse_assigned_name(urn_parser) < 0) return -1; /* [ "?+" r-component ] */ if (urn_parse_rq_component(urn_parser, FALSE, (urn == NULL ? NULL : &urn->enc_r_component)) < 0) return -1; /* [ "?=" q-component ] */ if (urn_parse_rq_component(urn_parser, TRUE, (urn == NULL ? NULL : &urn->enc_q_component)) < 0) return -1; /* [ "#" f-component ] */ if (urn_parse_f_component(urn_parser) < 0) return -1; /* must be at end of URN now */ i_assert(parser->cur == parser->end); return 0; } int urn_parse(const char *urn, enum urn_parse_flags flags, pool_t pool, struct urn **urn_r, const char **error_r) { struct urn_parser urn_parser; *error_r = NULL; i_assert(urn_r == NULL || pool != NULL); i_zero(&urn_parser); uri_parser_init(&urn_parser.parser, pool, urn); urn_parser.urn = (urn_r == NULL ? NULL : p_new(pool, struct urn, 1)); urn_parser.flags = flags; if (urn_do_parse(&urn_parser) < 0) { *error_r = urn_parser.parser.error; return -1; } if (urn_r != NULL) *urn_r = urn_parser.urn; return 0; } int urn_validate(const char *urn, enum urn_parse_flags flags, const char **error_r) { return urn_parse(urn, flags, NULL, NULL, error_r); } /* * URN construction */ const char *urn_create(const struct urn *urn) { string_t *urnstr = t_str_new(512); uri_append_scheme(urnstr, "urn"); if (urn->nid != NULL) { i_assert(urn->nss != NULL); str_append(urnstr, urn->nid); str_append_c(urnstr, ':'); i_assert(*urn->nss != '/'); uri_data_encode(urnstr, urn_char_lookup, urn_pchar_slash_char_mask, "", urn->nss); } else { const char *suffix, *nid_end, *nss; i_assert(urn->assigned_name != NULL); if (!str_begins_icase(urn->assigned_name, "urn:", &suffix)) i_unreached(); nid_end = strchr(suffix, ':'); i_assert(nid_end != NULL); nss = nid_end + 1; i_assert(*nss != '/'); str_append(urnstr, suffix); } /* r-component (pre-encoded) */ if (urn->enc_r_component != NULL) { str_append(urnstr, "?+"); str_append(urnstr, urn->enc_r_component); } /* q-component (pre-encoded) */ if (urn->enc_q_component != NULL) { str_append(urnstr, "?="); str_append(urnstr, urn->enc_q_component); } /* fragment (pre-encoded) */ if (urn->enc_f_component != NULL) { str_append_c(urnstr, '#'); str_append(urnstr, urn->enc_f_component); } return str_c(urnstr); } /* * URN equality */ int urn_normalize(const char *urn_in, enum urn_parse_flags flags, const char **urn_out_r, const char **error_r) { struct urn_parser urn_parser; struct urn urn; *error_r = NULL; i_zero(&urn_parser); uri_parser_init(&urn_parser.parser, pool_datastack_create(), urn_in); urn_parser.urn = &urn; urn_parser.flags = flags; urn_parser.normalizing = TRUE; if (urn_do_parse(&urn_parser) < 0) { *error_r = urn_parser.parser.error; return -1; } string_t *urnstr = t_str_new(512); if ((flags & URN_PARSE_SCHEME_EXTERNAL) == 0) uri_append_scheme(urnstr, "urn"); i_assert(urn.nss != NULL); str_append(urnstr, t_str_lcase(urn.nid)); str_append_c(urnstr, ':'); i_assert(*urn.nss != '/'); str_append(urnstr, urn.nss); *urn_out_r = str_c(urnstr); return 0; } int urn_equals(const char *urn1, const char *urn2, enum urn_parse_flags flags, const char **error_r) { const char *urn1n, *urn2n; if (urn_normalize(urn1, flags, &urn1n, error_r) < 0) return -1; if (urn_normalize(urn2, flags, &urn2n, error_r) < 0) return -1; if (strcmp(urn1n, urn2n) == 0) return 1; return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/util/rfc2822.c0000644000175100001700000001267715100335616023673 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* NOTE: much of the functionality implemented here should eventually appear * somewhere in Dovecot itself. */ #include "lib.h" #include "str.h" #include "unichar.h" #include "rfc2822.h" #include "message-header-encode.h" #include #include bool rfc2822_header_field_name_verify (const char *field_name, unsigned int len) { const char *p = field_name; const char *pend = p + len; /* field-name = 1*ftext * ftext = %d33-57 / ; Any character except * %d59-126 ; controls, SP, and * ; ":". */ while ( p < pend ) { if ( *p < 33 || *p == ':' ) return FALSE; p++; } return TRUE; } bool rfc2822_header_field_body_verify (const char *field_body, unsigned int len, bool allow_crlf, bool allow_utf8) { const unsigned char *p = (const unsigned char *)field_body; const unsigned char *pend = p + len; bool is8bit = FALSE; /* RFC5322: * * unstructured = (*([FWS] VCHAR) *WSP) * VCHAR = %x21-7E * FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space * WSP = SP / HTAB ; White space */ while ( p < pend ) { if ( *p < 0x20 ) { if ( (*p == '\r' || *p == '\n') ) { if ( !allow_crlf ) return FALSE; } else if ( *p != '\t' ) { return FALSE; } } if ( !is8bit && *p > 127 ) { if ( !allow_utf8 ) return FALSE; is8bit = TRUE; } p++; } if ( is8bit && !uni_utf8_str_is_valid(field_body) ) { return FALSE; } return TRUE; } /* * */ const char *rfc2822_header_field_name_sanitize(const char *name) { char *result = t_strdup_noconst(name); char *p; /* Make the whole name lower case ... */ result = str_lcase(result); /* ... except for the first letter and those that follow '-' */ p = result; *p = i_toupper(*p); while ( *p != '\0' ) { if ( *p == '-' ) { p++; if ( *p != '\0' ) *p = i_toupper(*p); continue; } p++; } return result; } /* * Message construction */ /* FIXME: This should be collected into a Dovecot API for composing internet * mail messages. */ unsigned int rfc2822_header_append (string_t *header, const char *name, const char *body, bool crlf, uoff_t *body_offset_r) { static const unsigned int max_line = 80; const char *bp = body; /* Pointer */ const char *sp = body; /* Start pointer */ const char *wp = NULL; /* Whitespace pointer */ const char *nlp = NULL; /* New-line pointer */ unsigned int line_len = strlen(name); unsigned int lines = 0; /* Write header field name first */ str_append(header, name); str_append(header, ": "); if ( body_offset_r != NULL ) *body_offset_r = str_len(header); line_len += 2; /* Add field body; fold it if necessary and account for existing folding */ while ( *bp != '\0' ) { bool ws_first = TRUE; while ( *bp != '\0' && nlp == NULL && (wp == NULL || line_len < max_line) ) { if ( *bp == ' ' || *bp == '\t' ) { if (ws_first) wp = bp; ws_first = FALSE; } else if ( *bp == '\r' || *bp == '\n' ) { if (ws_first) nlp = bp; else nlp = wp; break; } else { ws_first = TRUE; } bp++; line_len++; } if ( *bp == '\0' ) break; /* Existing newline ? */ if ( nlp != NULL ) { /* Replace any consecutive newline and whitespace for consistency */ while ( *bp == ' ' || *bp == '\t' || *bp == '\r' || *bp == '\n' ) bp++; str_append_data(header, sp, nlp-sp); if ( crlf ) str_append(header, "\r\n"); else str_append(header, "\n"); while ( *bp == ' ' || *bp == '\t' ) bp++; if ( *bp != '\0' ) { /* Continued line; replace leading whitespace with single TAB */ str_append_c(header, '\t'); } sp = bp; } else { /* Insert newline at last whitespace within the max_line limit */ i_assert(wp >= sp); str_append_data(header, sp, wp-sp); /* Force continued line; drop any existing whitespace */ while ( *wp == ' ' || *wp == '\t' ) wp++; if ( crlf ) str_append(header, "\r\n"); else str_append(header, "\n"); /* Insert single TAB instead of the original whitespace */ str_append_c(header, '\t'); sp = wp; if (sp > bp) bp = sp; } lines++; line_len = bp - sp; wp = NULL; nlp = NULL; } if ( bp != sp || lines == 0 ) { str_append_data(header, sp, bp-sp); if ( crlf ) str_append(header, "\r\n"); else str_append(header, "\n"); lines++; } return lines; } void rfc2822_header_printf (string_t *header, const char *name, const char *fmt, ...) { const char *body; va_list args; va_start(args, fmt); body = t_strdup_vprintf(fmt, args); va_end(args); rfc2822_header_write(header, name, body); } void rfc2822_header_utf8_printf (string_t *header, const char *name, const char *fmt, ...) { string_t *body = t_str_new(256); va_list args; va_start(args, fmt); message_header_encode(t_strdup_vprintf(fmt, args), body); va_end(args); rfc2822_header_write(header, name, str_c(body)); } void rfc2822_header_write_address(string_t *header, const char *name, const char *address) { bool has_8bit = FALSE; const char *p; for (p = address; *p != '\0'; p++) { if ((*p & 0x80) != 0) has_8bit = TRUE; } if (!has_8bit) { rfc2822_header_write(header, name, address); } else { string_t *body = t_str_new(256); message_header_encode(address, body); rfc2822_header_write(header, name, str_c(body)); } } dovecot-pigeonhole-2.4.2/src/lib-sieve/util/Makefile.am0000644000175100001700000000223415100335616024457 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_util.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) \ -DMODULEDIR=\""$(dovecot_moduledir)"\" libsieve_util_la_DEPENDENCIES = $(LIBDOVECOT_STORAGE_DEPS) $(LIBDOVECOT_DEPS) libsieve_util_la_SOURCES = \ mail-raw.c \ edit-mail.c \ rfc2822.c \ urn.c headers = \ mail-raw.h \ edit-mail.h \ rfc2822.h \ urn.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(headers) test_programs = \ test-edit-mail \ test-rfc2822 \ test-urn noinst_PROGRAMS = $(test_programs) test_libs = \ libsieve_util.la \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) test_deps = \ libsieve_util.la \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) test_edit_mail_SOURCES = test-edit-mail.c test_edit_mail_LDADD = $(test_libs) test_edit_mail_DEPENDENCIES = $(test_deps) test_rfc2822_SOURCES = test-rfc2822.c test_rfc2822_LDADD = $(test_libs) test_rfc2822_DEPENDENCIES = $(test_deps) test_urn_SOURCES = test-urn.c test_urn_LDADD = $(test_libs) test_urn_DEPENDENCIES = $(test_deps) check: check-am check-test check-test: all-am for bin in $(test_programs); do \ if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ done dovecot-pigeonhole-2.4.2/src/lib-sieve/util/edit-mail.h0000644000175100001700000000264115100335616024443 0ustar00buildbotbuildbot00000000000000#ifndef EDIT_MAIL_H #define EDIT_MAIL_H struct edit_mail; struct edit_mail *edit_mail_wrap(struct mail *mail); void edit_mail_unwrap(struct edit_mail **edmail); struct edit_mail *edit_mail_snapshot(struct edit_mail *edmail); void edit_mail_reset(struct edit_mail *edmail); struct mail *edit_mail_get_mail(struct edit_mail *edmail); /* * Header modification */ /* Simple API */ void edit_mail_header_add(struct edit_mail *edmail, const char *field_name, const char *value, bool last); int edit_mail_header_delete(struct edit_mail *edmail, const char *field_name, int index); int edit_mail_header_replace(struct edit_mail *edmail, const char *field_name, int index, const char *newname, const char *newvalue); /* Iterator */ struct edit_mail_header_iter; int edit_mail_headers_iterate_init(struct edit_mail *edmail, const char *field_name, bool reverse, struct edit_mail_header_iter **edhiter_r); void edit_mail_headers_iterate_deinit(struct edit_mail_header_iter **edhiter); void edit_mail_headers_iterate_get(struct edit_mail_header_iter *edhiter, const char **value_r); bool edit_mail_headers_iterate_next(struct edit_mail_header_iter *edhiter); bool edit_mail_headers_iterate_remove(struct edit_mail_header_iter *edhiter); bool edit_mail_headers_iterate_replace(struct edit_mail_header_iter *edhiter, const char *newname, const char *newvalue); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/util/Makefile.in0000644000175100001700000006700615100335630024474 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = $(am__EXEEXT_1) subdir = src/lib-sieve/util ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginc_lib_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = test-edit-mail$(EXEEXT) test-rfc2822$(EXEEXT) \ test-urn$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_util_la_LIBADD = am_libsieve_util_la_OBJECTS = mail-raw.lo edit-mail.lo rfc2822.lo \ urn.lo libsieve_util_la_OBJECTS = $(am_libsieve_util_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_test_edit_mail_OBJECTS = test-edit-mail.$(OBJEXT) test_edit_mail_OBJECTS = $(am_test_edit_mail_OBJECTS) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = libsieve_util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_test_rfc2822_OBJECTS = test-rfc2822.$(OBJEXT) test_rfc2822_OBJECTS = $(am_test_rfc2822_OBJECTS) am_test_urn_OBJECTS = test-urn.$(OBJEXT) test_urn_OBJECTS = $(am_test_urn_OBJECTS) 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/edit-mail.Plo \ ./$(DEPDIR)/mail-raw.Plo ./$(DEPDIR)/rfc2822.Plo \ ./$(DEPDIR)/test-edit-mail.Po ./$(DEPDIR)/test-rfc2822.Po \ ./$(DEPDIR)/test-urn.Po ./$(DEPDIR)/urn.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_util_la_SOURCES) $(test_edit_mail_SOURCES) \ $(test_rfc2822_SOURCES) $(test_urn_SOURCES) DIST_SOURCES = $(libsieve_util_la_SOURCES) $(test_edit_mail_SOURCES) \ $(test_rfc2822_SOURCES) $(test_urn_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(pkginc_lib_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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_util.la AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) \ -DMODULEDIR=\""$(dovecot_moduledir)"\" libsieve_util_la_DEPENDENCIES = $(LIBDOVECOT_STORAGE_DEPS) $(LIBDOVECOT_DEPS) libsieve_util_la_SOURCES = \ mail-raw.c \ edit-mail.c \ rfc2822.c \ urn.c headers = \ mail-raw.h \ edit-mail.h \ rfc2822.h \ urn.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(headers) test_programs = \ test-edit-mail \ test-rfc2822 \ test-urn test_libs = \ libsieve_util.la \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) test_deps = \ libsieve_util.la \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) test_edit_mail_SOURCES = test-edit-mail.c test_edit_mail_LDADD = $(test_libs) test_edit_mail_DEPENDENCIES = $(test_deps) test_rfc2822_SOURCES = test-rfc2822.c test_rfc2822_LDADD = $(test_libs) test_rfc2822_DEPENDENCIES = $(test_deps) test_urn_SOURCES = test-urn.c test_urn_LDADD = $(test_libs) test_urn_DEPENDENCIES = $(test_deps) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/util/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/util/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_util.la: $(libsieve_util_la_OBJECTS) $(libsieve_util_la_DEPENDENCIES) $(EXTRA_libsieve_util_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_util_la_OBJECTS) $(libsieve_util_la_LIBADD) $(LIBS) test-edit-mail$(EXEEXT): $(test_edit_mail_OBJECTS) $(test_edit_mail_DEPENDENCIES) $(EXTRA_test_edit_mail_DEPENDENCIES) @rm -f test-edit-mail$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_edit_mail_OBJECTS) $(test_edit_mail_LDADD) $(LIBS) test-rfc2822$(EXEEXT): $(test_rfc2822_OBJECTS) $(test_rfc2822_DEPENDENCIES) $(EXTRA_test_rfc2822_DEPENDENCIES) @rm -f test-rfc2822$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_rfc2822_OBJECTS) $(test_rfc2822_LDADD) $(LIBS) test-urn$(EXEEXT): $(test_urn_OBJECTS) $(test_urn_DEPENDENCIES) $(EXTRA_test_urn_DEPENDENCIES) @rm -f test-urn$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_urn_OBJECTS) $(test_urn_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit-mail.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mail-raw.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc2822.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-edit-mail.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-rfc2822.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-urn.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urn.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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) $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/edit-mail.Plo -rm -f ./$(DEPDIR)/mail-raw.Plo -rm -f ./$(DEPDIR)/rfc2822.Plo -rm -f ./$(DEPDIR)/test-edit-mail.Po -rm -f ./$(DEPDIR)/test-rfc2822.Po -rm -f ./$(DEPDIR)/test-urn.Po -rm -f ./$(DEPDIR)/urn.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/edit-mail.Plo -rm -f ./$(DEPDIR)/mail-raw.Plo -rm -f ./$(DEPDIR)/rfc2822.Plo -rm -f ./$(DEPDIR)/test-edit-mail.Po -rm -f ./$(DEPDIR)/test-rfc2822.Po -rm -f ./$(DEPDIR)/test-urn.Po -rm -f ./$(DEPDIR)/urn.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am 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-pkginc_libHEADERS \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ uninstall-pkginc_libHEADERS .PRECIOUS: Makefile check: check-am check-test check-test: all-am for bin in $(test_programs); do \ if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ done # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/util/rfc2822.h0000644000175100001700000000177415100335616023674 0ustar00buildbotbuildbot00000000000000#ifndef RFC2822_H #define RFC2822_H #include "lib.h" #include /* * Verification */ bool rfc2822_header_field_name_verify (const char *field_name, unsigned int len); bool rfc2822_header_field_body_verify (const char *field_body, unsigned int len, bool allow_crlf, bool allow_utf8); /* * */ const char *rfc2822_header_field_name_sanitize(const char *name); /* * Message composition */ unsigned int rfc2822_header_append (string_t *header, const char *name, const char *body, bool crlf, uoff_t *body_offset_r); static inline void rfc2822_header_write (string_t *header, const char *name, const char *body) { (void)rfc2822_header_append(header, name, body, TRUE, NULL); } void rfc2822_header_printf (string_t *header, const char *name, const char *fmt, ...) ATTR_FORMAT(3, 4); void rfc2822_header_utf8_printf (string_t *header, const char *name, const char *fmt, ...) ATTR_FORMAT(3, 4); void rfc2822_header_write_address(string_t *header, const char *name, const char *address); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/util/test-urn.c0000644000175100001700000001604715100335616024357 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "net.h" #include "urn.h" #include "test-common.h" struct valid_urn_test { const char *urn; enum urn_parse_flags flags; struct urn urn_parsed; }; /* Valid HTTP URL tests */ static struct valid_urn_test valid_urn_tests[] = { { .urn = "urn:frop1234:friep", .urn_parsed = { .assigned_name = "urn:frop1234:friep", .nid = "frop1234", .nss = "friep", }, }, { .urn = "urn:example:weather?=op=map&lat=39.56" "&lon=-104.85&datetime=1969-07-21T02:56:15Z", .urn_parsed = { .assigned_name = "urn:example:weather", .nid = "example", .nss = "weather", .enc_q_component = "op=map&lat=39.56" "&lon=-104.85&datetime=1969-07-21T02:56:15Z", }, }, }; static unsigned int valid_urn_test_count = N_ELEMENTS(valid_urn_tests); static void test_urn_equal(struct urn *urnt, struct urn *urnp) { test_assert(urnp->assigned_name != NULL); i_assert(urnt->assigned_name != NULL); test_assert(null_strcmp(urnp->assigned_name, urnt->assigned_name) == 0); test_assert(urnp->nid != NULL); i_assert(urnt->nid != NULL); test_assert(null_strcmp(urnp->nid, urnt->nid) == 0); test_assert(urnp->nss != NULL); i_assert(urnt->nss != NULL); test_assert(null_strcmp(urnp->nss, urnt->nss) == 0); if (urnp->enc_r_component == NULL || urnt->enc_r_component == NULL) { test_assert(urnp->enc_r_component == urnt->enc_r_component); } else { test_assert(strcmp(urnp->enc_r_component, urnt->enc_r_component) == 0); } if (urnp->enc_q_component == NULL || urnt->enc_q_component == NULL) { test_assert(urnp->enc_q_component == urnt->enc_q_component); } else { test_assert(strcmp(urnp->enc_q_component, urnt->enc_q_component) == 0); } if (urnp->enc_f_component == NULL || urnt->enc_f_component == NULL) { test_assert(urnp->enc_f_component == urnt->enc_f_component); } else { test_assert(strcmp(urnp->enc_f_component, urnt->enc_f_component) == 0); } } static void test_urn_valid(void) { unsigned int i; for (i = 0; i < valid_urn_test_count; i++) T_BEGIN { const char *urn = valid_urn_tests[i].urn; enum urn_parse_flags flags = valid_urn_tests[i].flags; struct urn *urnt = &valid_urn_tests[i].urn_parsed; struct urn *urnp; const char *error = NULL; test_begin(t_strdup_printf("urn valid [%d]", i)); if (urn_parse(urn, flags, pool_datastack_create(), &urnp, &error) < 0) urnp = NULL; test_out_reason(t_strdup_printf("urn_parse(%s)", valid_urn_tests[i].urn), urnp != NULL, error); if (urnp != NULL) test_urn_equal(urnt, urnp); test_end(); } T_END; } struct invalid_urn_test { const char *urn; enum urn_parse_flags flags; struct urn urn_base; }; static struct invalid_urn_test invalid_urn_tests[] = { { .urn = "imap://example.com/INBOX", }, { .urn = "http:/www.example.com", }, { .urn = "urn:-frop:bla", }, { .urn = "urn:frop-:bla", }, { .urn = "urn:&&&&:bla", }, }; static unsigned int invalid_urn_test_count = N_ELEMENTS(invalid_urn_tests); static void test_urn_invalid(void) { unsigned int i; for (i = 0; i < invalid_urn_test_count; i++) T_BEGIN { const char *urn = invalid_urn_tests[i].urn; enum urn_parse_flags flags = invalid_urn_tests[i].flags; struct urn *urnp; const char *error = NULL; test_begin(t_strdup_printf("urn invalid [%d]", i)); if (urn_parse(urn, flags, pool_datastack_create(), &urnp, &error) < 0) urnp = NULL; test_out_reason(t_strdup_printf("parse %s", urn), urnp == NULL, error); test_end(); } T_END; } static const char *parse_create_urn_tests[] = { "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z", }; static unsigned int parse_create_urn_test_count = N_ELEMENTS(parse_create_urn_tests); static void test_urn_parse_create(void) { unsigned int i; for (i = 0; i < parse_create_urn_test_count; i++) T_BEGIN { const char *urn = parse_create_urn_tests[i]; struct urn *urnp; const char *error = NULL; test_begin(t_strdup_printf("urn parse/create [%d]", i)); if (urn_parse(urn, 0, pool_datastack_create(), &urnp, &error) < 0) urnp = NULL; test_out_reason(t_strdup_printf("parse %s", urn), urnp != NULL, error); if (urnp != NULL) { const char *urnnew = urn_create(urnp); test_out(t_strdup_printf("create %s", urnnew), strcmp(urn, urnnew) == 0); } test_end(); } T_END; } static void test_urn_equality(void) { const char *error; int ret; const char *urn_first = "urn:example:a123,z456"; test_begin("urn all equal [1]"); ret = urn_equals(urn_first, "URN:example:a123,z456", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret > 0); test_end(); test_begin("urn all equal [2]"); ret = urn_equals(urn_first, "urn:EXAMPLE:a123,z456", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret > 0); test_end(); test_begin("urn all equal [3]"); ret = urn_equals(urn_first, "urn:example:a123,z456?+abc", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret > 0); test_end(); test_begin("urn all equal [4]"); ret = urn_equals(urn_first, "urn:example:a123,z456?=xyz", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret > 0); test_end(); test_begin("urn all equal [5]"); ret = urn_equals(urn_first, "urn:example:a123,z456#789", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret > 0); test_end(); test_begin("urn not equal / [1]"); ret = urn_equals("urn:example:a123,z456/foo", "urn:example:a123,z456/bar", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret == 0); test_end(); test_begin("urn not equal / [2]"); ret = urn_equals("urn:example:a123,z456/foo", "urn:example:a123,z456/baz", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret == 0); test_end(); test_begin("urn not equal / [3]"); ret = urn_equals("urn:example:a123,z456/bar", "urn:example:a123,z456/baz", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret == 0); test_end(); test_begin("urn equal pct"); ret = urn_equals("urn:example:a123%2Cz456", "URN:EXAMPLE:a123%2cz456", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret > 0); test_end(); test_begin("urn not equal pct [1]"); ret = urn_equals("urn:example:a123%2Cz456", "urn:example:a123,z456", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret == 0); test_end(); test_begin("urn not equal pct [2]"); ret = urn_equals("URN:EXAMPLE:a123%2cz456", "urn:example:a123,z456", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret == 0); test_end(); test_begin("urn not equal nss case"); ret = urn_equals("urn:example:A123,z456", "urn:example:a123,Z456", 0, &error); test_out_reason_quiet("equals", ret >= 0, error); test_assert(ret == 0); test_end(); } int main(void) { static void (*const test_functions[])(void) = { test_urn_valid, test_urn_invalid, test_urn_parse_create, test_urn_equality, NULL }; return test_run(test_functions); } dovecot-pigeonhole-2.4.2/src/lib-sieve/util/test-rfc2822.c0000644000175100001700000002037315100335616024640 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "test-common.h" #include "str.h" #include "rfc2822.h" struct test_header_write { const char *name; const char *body; const char *output; }; static const struct test_header_write header_write_tests[] = { { .name = "Frop", .body = "Bladiebla", .output = "Frop: Bladiebla\r\n" },{ .name = "Subject", .body = "This is a very long subject that well exceeds the " "boundary of 80 characters. It should therefore " "trigger the header folding algorithm.", .output = "Subject: This is a very long subject that well " "exceeds the boundary of 80\r\n" "\tcharacters. It should therefore trigger the header " "folding algorithm.\r\n" },{ .name = "Subject", .body = "This\tis\ta\tvery\tlong\tsubject\tthat\twell\texceeds" "\tthe\tboundary\tof\t80\tcharacters.\tIt\tshould\t" "therefore\ttrigger\tthe\theader\tfolding\talgorithm.", .output = "Subject: This\tis\ta\tvery\tlong\tsubject\tthat\twell" "\texceeds\tthe\tboundary\tof\t80\r\n" "\tcharacters.\tIt\tshould\ttherefore\ttrigger\tthe\t" "header\tfolding\talgorithm.\r\n" },{ .name = "Comment", .body = "This header already contains newlines.\n" "The header folding algorithm should respect these.\n" "It also should convert between CRLF and LF when " "needed.", .output = "Comment: This header already contains newlines.\r\n" "\tThe header folding algorithm should respect " "these.\r\n" "\tIt also should convert between CRLF and LF when " "needed.\r\n" },{ .name = "References", .body = " " " " "", .output = "References: " "\r\n" "\t\r\n" "\t\r\n", },{ .name = "Cc", .body = "\"Richard Edgar Cipient\" " ", \"Albert Buser\" " ", \"Steven Pammer\" " "", .output = "Cc: \"Richard Edgar Cipient\" " ", \"Albert Buser\"\r\n" "\t, \"Steven Pammer\" " "\r\n" },{ .name = "References", .body = "<00fd01d31b6c$33d98e30$9b8caa90$@karel@aa.example.org" "> <00f201d31c36$afbfa320$0f3ee960$@karel@aa.example.o" "rg> <015c01d32023$fe3840c0$faa8c240$@karel@aa.examp" "le.org> <014601d325a4$ece1ed90$c6a5c8b0$@karel@aa." "example.org> <012801d32b24$7734c380$659e4a80$@karel" "@aa.example.org> <00da01d32be9$2d9944b0$88cbce10$@kar" "el@aa.example.org> <006a01d336ef$6825d5b0$387181" "10$@karel@aa.example.org> <018501d33880$58b654f0$0a2" "2fed0$@frederik@aa.example.org> <00e601d33ba3$be50f10" "0$3af2d300$@frederik@aa.example.org> <016501d341ee$e" "678e1a0$b36aa4e0$@frederik@aa.example.org> <00ab01" "d348f9$ae2e1ab0$0a8a5010$@karel@aa.example.org> <0086" "01d349c1$98ff4ba0$cafde2e0$@frederik@aa.example.org> " " <019301d357e6$a2190680$e64b1380$@frederik@aa.example" ".org> <025f01d384b0$24d2c" "660$6e785320$@karel@aa.example.org> <01cf01d3889e$7" "280cb90$578262b0$@karel@aa.example.org> <013701d38" "bc2$9164b950$b42e2bf0$@karel@aa.example.org> " " <014f01d3a5b1$a51afc80$ef\n" " \n" "\t \t \t \t \t \t \t \t5\t0\tf\t5\t8\t0\t$\t@\tk\ta\t" "r\te\tl\t@\taa.example.org> <01cb01d3af29$dd7d" "1b40$987751c0$@karel@aa.example.org> " " <00b401d3f2bc$6ad8c180$408a4480" "$@karel@aa.example.org> <011a01d3f6ab$0eeb0480$2cc1" "0d80$@frederik@aa.example.org> <005c01d3f774$37f1b210" "$a7d51630$@richard@aa.example.org> <01a801d3fc2d$59" "0f7730$0b2e6590$@frederik@aa.example.org> <007501d3fc" "f5$23d75ce0$6b8616a0$@frederik@aa.example.org> <015d0" "1d3fdbf$136da510$3a48ef30$@frederik@aa.example.org> <" "021a01d3fe87$556d68b0$00483a10$@frederik@aa.example.o" "rg> <013f01d3ff4e$a2d13d30$e873b790$@frederik@aa.exam" "ple.org> <001f01d401ab$31e7b090$95b711b0$@frederik@aa" ".example.org> <017201d40273$a118d200$e34a7600$@freder" "ik@aa.example.org> <017401d4033e$ca3602e0$5ea208a0$@f" "rederik@aa.example.org> <02a601d40404$608b9e10$21a2da" "30$@frederik@aa.example.org> <014301d404d0$b65269b0$2" "2f73d10$@frederik@aa.example.org> <015901d4072b$b5a1b" "950$20e52bf0$@frederik@aa.example.org> <01b401d407f3$" "bef52050$3cdf\n" " 60 \n" "\tf0 \t$@ \tfr \ted \teri\tk@aa.example.org> <012801d" "408bd$6602fce0$3208f6a0$@frederik@aa.example.org> <01" "c801d40984$ae4b23c0$0ae16b40$@frederik@aa.example.org" "> <00ec01d40a4d$12859190$3790b4b0$@frederik@aa.exampl" "e.org> <02af01d40d74$589c9050$09d5b0f0$@frederik@aa.e" "xample.org> <000d01d40ec8$d3d337b0$7b79a710$@richard@" "aa.example.org>\n", .output = "References: <00fd01d31b6c$33d98e30$9b8caa90$@karel@aa.example.org>\r\n" "\t<00f201d31c36$afbfa320$0f3ee960$@karel@aa.example.org>\r\n" "\t<015c01d32023$fe3840c0$faa8c240$@karel@aa.example.org>\r\n" "\t<014601d325a4$ece1ed90$c6a5c8b0$@karel@aa.example.org>\r\n" "\t<012801d32b24$7734c380$659e4a80$@karel@aa.example.org>\r\n" "\t<00da01d32be9$2d9944b0$88cbce10$@karel@aa.example.org>\r\n" "\t<006a01d336ef$6825d5b0$38718110$@karel@aa.example.org>\r\n" "\t<018501d33880$58b654f0$0a22fed0$@frederik@aa.example.org>\r\n" "\t<00e601d33ba3$be50f100$3af2d300$@frederik@aa.example.org>\r\n" "\t<016501d341ee$e678e1a0$b36aa4e0$@frederik@aa.example.org>\r\n" "\t<00ab01d348f9$ae2e1ab0$0a8a5010$@karel@aa.example.org>\r\n" "\t<008601d349c1$98ff4ba0$cafde2e0$@frederik@aa.example.org>\r\n" "\t<019301d357e6$a2190680$e64b1380$@frederik@aa.example.org>\r\n" "\t<025f01d384b0$24d2c660$6e785320$@karel@aa.example.org>\r\n" "\t<01cf01d3889e$7280cb90$578262b0$@karel@aa.example.org>\r\n" "\t<013701d38bc2$9164b950$b42e2bf0$@karel@aa.example.org>\r\n" "\t<014f01d3a5b1$a51afc80$ef\r\n" "\t5\t0\tf\t5\t8\t0\t$\t@\tk\ta\tr\te\tl\t@\taa.example.org>\r\n" "\t<01cb01d3af29$dd7d1b40$987751c0$@karel@aa.example.org>\r\n" "\t<00b401d3f2bc$6ad8c180$408a4480$@karel@aa.example.org>\r\n" "\t<011a01d3f6ab$0eeb0480$2cc10d80$@frederik@aa.example.org>\r\n" "\t<005c01d3f774$37f1b210$a7d51630$@richard@aa.example.org>\r\n" "\t<01a801d3fc2d$590f7730$0b2e6590$@frederik@aa.example.org>\r\n" "\t<007501d3fcf5$23d75ce0$6b8616a0$@frederik@aa.example.org>\r\n" "\t<015d01d3fdbf$136da510$3a48ef30$@frederik@aa.example.org>\r\n" "\t<021a01d3fe87$556d68b0$00483a10$@frederik@aa.example.org>\r\n" "\t<013f01d3ff4e$a2d13d30$e873b790$@frederik@aa.example.org>\r\n" "\t<001f01d401ab$31e7b090$95b711b0$@frederik@aa.example.org>\r\n" "\t<017201d40273$a118d200$e34a7600$@frederik@aa.example.org>\r\n" "\t<017401d4033e$ca3602e0$5ea208a0$@frederik@aa.example.org>\r\n" "\t<02a601d40404$608b9e10$21a2da30$@frederik@aa.example.org>\r\n" "\t<014301d404d0$b65269b0$22f73d10$@frederik@aa.example.org>\r\n" "\t<015901d4072b$b5a1b950$20e52bf0$@frederik@aa.example.org>\r\n" "\t<01b401d407f3$bef52050$3cdf\r\n" "\t60\r\n" "\tf0 \t$@ \tfr \ted \teri\tk@aa.example.org>\r\n" "\t<012801d408bd$6602fce0$3208f6a0$@frederik@aa.example.org>\r\n" "\t<01c801d40984$ae4b23c0$0ae16b40$@frederik@aa.example.org>\r\n" "\t<00ec01d40a4d$12859190$3790b4b0$@frederik@aa.example.org>\r\n" "\t<02af01d40d74$589c9050$09d5b0f0$@frederik@aa.example.org>\r\n" "\t<000d01d40ec8$d3d337b0$7b79a710$@richard@aa.example.org>\r\n" } }; static const unsigned int header_write_tests_count = N_ELEMENTS(header_write_tests); static void test_rfc2822_header_write(void) { string_t *header; unsigned int i; test_begin("rfc2822 - header write"); header = t_str_new(1024); for (i = 0; i < header_write_tests_count; i++) { const struct test_header_write *test = &header_write_tests[i]; str_truncate(header, 0); rfc2822_header_write(header, test->name, test->body); test_assert_idx(strcmp(str_c(header), test->output) == 0, i); } test_end(); } int main(void) { static void (*test_functions[])(void) = { test_rfc2822_header_write, NULL }; return test_run(test_functions); } dovecot-pigeonhole-2.4.2/src/lib-sieve/util/urn.h0000644000175100001700000000157415100335616023406 0ustar00buildbotbuildbot00000000000000#ifndef URN_H #define URN_H struct urn { const char *assigned_name; const char *nid; const char *nss; const char *enc_r_component; const char *enc_q_component; const char *enc_f_component; }; /* * URN parsing */ enum urn_parse_flags { /* Scheme part 'urn:' is already parsed externally. */ URN_PARSE_SCHEME_EXTERNAL = 0x01, }; int urn_parse(const char *urn, enum urn_parse_flags flags, pool_t pool, struct urn **urn_r, const char **error_r); int urn_validate(const char *urn, enum urn_parse_flags flags, const char **error_r); /* * URN construction */ const char *urn_create(const struct urn *urn); /* * URN equality */ int urn_normalize(const char *urn_in, enum urn_parse_flags flags, const char **urn_out, const char **error_r); int urn_equals(const char *urn1, const char *urn2, enum urn_parse_flags flags, const char **error_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/util/edit-mail.c0000644000175100001700000016236115100335616024444 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str.h" #include "mempool.h" #include "llist.h" #include "istream-private.h" #include "master-service.h" #include "master-service-settings.h" #include "message-parser.h" #include "message-header-encode.h" #include "message-header-decode.h" #include "mail-user.h" #include "mail-storage-service.h" #include "mail-storage-private.h" #include "index-mail.h" #include "raw-storage.h" #include "rfc2822.h" #include "edit-mail.h" /* * Forward declarations */ struct _header_field_index; struct _header_field; struct _header_index; struct _header; static struct mail_vfuncs edit_mail_vfuncs; struct edit_mail_istream; struct istream *edit_mail_istream_create(struct edit_mail *edmail); static struct _header_index * edit_mail_header_clone(struct edit_mail *edmail, struct _header *header); /* * Raw storage */ static struct mail_user *edit_mail_user = NULL; static unsigned int edit_mail_refcount = 0; static struct mail_user *edit_mail_raw_storage_get(struct mail_user *mail_user) { if (edit_mail_user == NULL) { struct mail_storage_service_ctx *storage_service = mail_storage_service_user_get_service_ctx( mail_user->service_user); struct settings_instance *set_instance = mail_storage_service_user_get_settings_instance(mail_user->service_user); edit_mail_user = raw_storage_create_from_set(storage_service, set_instance); } edit_mail_refcount++; return edit_mail_user; } static void edit_mail_raw_storage_drop(void) { i_assert(edit_mail_refcount > 0); if (--edit_mail_refcount != 0) return; mail_user_unref(&edit_mail_user); edit_mail_user = NULL; } /* * Headers */ struct _header_field { struct _header *header; unsigned int refcount; char *data; size_t size; size_t virtual_size; uoff_t offset; unsigned int lines; uoff_t body_offset; char *utf8_value; }; struct _header_field_index { struct _header_field_index *prev, *next; struct _header_field *field; struct _header_index *header; }; struct _header { unsigned int refcount; char *name; }; struct _header_index { struct _header_index *prev, *next; struct _header *header; struct _header_field_index *first, *last; unsigned int count; }; static inline struct _header *_header_create(const char *name) { struct _header *header; header = i_new(struct _header, 1); header->name = i_strdup(name); header->refcount = 1; return header; } static inline void _header_ref(struct _header *header) { header->refcount++; } static inline void _header_unref(struct _header *header) { i_assert(header->refcount > 0); if (--header->refcount != 0) return; i_free(header->name); i_free(header); } static inline struct _header_field *_header_field_create(struct _header *header) { struct _header_field *hfield; hfield = i_new(struct _header_field, 1); hfield->refcount = 1; hfield->header = header; if (header != NULL) _header_ref(header); return hfield; } static inline void _header_field_ref(struct _header_field *hfield) { hfield->refcount++; } static inline void _header_field_unref(struct _header_field *hfield) { i_assert(hfield->refcount > 0); if (--hfield->refcount != 0) return; if (hfield->header != NULL) _header_unref(hfield->header); if (hfield->data != NULL) i_free(hfield->data); if (hfield->utf8_value != NULL) i_free(hfield->utf8_value); i_free(hfield); } /* * Edit mail object */ struct edit_mail { struct mail_private mail; struct mail_private *wrapped; struct edit_mail *parent; unsigned int refcount; struct istream *wrapped_stream; struct istream *stream; struct _header_index *headers_head, *headers_tail; struct _header_field_index *header_fields_head, *header_fields_tail; struct message_size hdr_size, body_size; struct message_size wrapped_hdr_size, wrapped_body_size; struct _header_field_index *header_fields_appended; struct message_size appended_hdr_size; bool modified:1; bool snapshot_modified:1; bool crlf:1; bool eoh_crlf:1; bool headers_parsed:1; bool destroying_stream:1; }; struct edit_mail *edit_mail_wrap(struct mail *mail) { struct mail_private *mailp = (struct mail_private *) mail; struct edit_mail *edmail; struct mail_user *raw_mail_user; struct mailbox *raw_box = NULL; struct mailbox_transaction_context *raw_trans; struct message_size hdr_size, body_size; struct istream *wrapped_stream; uoff_t size_diff; pool_t pool; if (mail_get_stream(mail, &hdr_size, &body_size, &wrapped_stream) < 0) return NULL; /* Create dummy raw mailbox for our wrapper */ raw_mail_user = edit_mail_raw_storage_get(mail->box->storage->user); if (raw_mailbox_alloc_stream(raw_mail_user, wrapped_stream, (time_t)-1, "editor@example.com", &raw_box) < 0) { i_error("edit-mail: failed to open raw box: %s", mailbox_get_last_internal_error(raw_box, NULL)); mailbox_free(&raw_box); edit_mail_raw_storage_drop(); return NULL; } raw_trans = mailbox_transaction_begin(raw_box, 0, __func__); /* Create the wrapper mail */ pool = pool_alloconly_create("edit_mail", 1024); edmail = p_new(pool, struct edit_mail, 1); edmail->refcount = 1; edmail->mail.pool = pool; edmail->wrapped = mailp; edmail->wrapped_hdr_size = hdr_size; edmail->wrapped_body_size = body_size; edmail->wrapped_stream = wrapped_stream; i_stream_ref(edmail->wrapped_stream); /* Determine whether we should use CRLF or LF for the physical message */ size_diff = ((hdr_size.virtual_size + body_size.virtual_size) - (hdr_size.physical_size + body_size.physical_size)); if (size_diff == 0 || size_diff <= (hdr_size.lines + body_size.lines)/2) edmail->crlf = edmail->eoh_crlf = TRUE; array_create(&edmail->mail.module_contexts, pool, sizeof(void *), 5); edmail->mail.v = edit_mail_vfuncs; edmail->mail.mail.seq = 1; edmail->mail.mail.box = raw_box; edmail->mail.mail.transaction = raw_trans; edmail->mail.wanted_fields = mailp->wanted_fields; edmail->mail.wanted_headers = mailp->wanted_headers; return edmail; } struct edit_mail *edit_mail_snapshot(struct edit_mail *edmail) { struct _header_field_index *field_idx, *field_idx_new; struct edit_mail *edmail_new; pool_t pool; if (!edmail->snapshot_modified) return edmail; pool = pool_alloconly_create("edit_mail", 1024); edmail_new = p_new(pool, struct edit_mail, 1); edmail_new->refcount = 1; edmail_new->mail.pool = pool; edmail_new->wrapped = edmail->wrapped; edmail_new->wrapped_hdr_size = edmail->wrapped_hdr_size; edmail_new->wrapped_body_size = edmail->wrapped_body_size; edmail_new->hdr_size = edmail->hdr_size; edmail_new->body_size = edmail->body_size; edmail_new->appended_hdr_size = edmail->appended_hdr_size; edmail_new->wrapped_stream = edmail->wrapped_stream; i_stream_ref(edmail_new->wrapped_stream); edmail_new->crlf = edmail->crlf; edmail_new->eoh_crlf = edmail->eoh_crlf; array_create(&edmail_new->mail.module_contexts, pool, sizeof(void *), 5); edmail_new->mail.v = edit_mail_vfuncs; edmail_new->mail.mail.seq = 1; edmail_new->mail.mail.box = edmail->mail.mail.box; edmail_new->mail.mail.transaction = edmail->mail.mail.transaction; edmail_new->mail.wanted_fields = edmail->mail.wanted_fields; edmail_new->mail.wanted_headers = edmail->mail.wanted_headers; edmail_new->stream = NULL; if (edmail->modified) { field_idx = edmail->header_fields_head; while (field_idx != NULL) { struct _header_field_index *next = field_idx->next; field_idx_new = i_new(struct _header_field_index, 1); field_idx_new->header = edit_mail_header_clone( edmail_new, field_idx->header->header); field_idx_new->field = field_idx->field; _header_field_ref(field_idx_new->field); DLLIST2_APPEND(&edmail_new->header_fields_head, &edmail_new->header_fields_tail, field_idx_new); field_idx_new->header->count++; if (field_idx->header->first == field_idx) field_idx_new->header->first = field_idx_new; if (field_idx->header->last == field_idx) field_idx_new->header->last = field_idx_new; if (field_idx == edmail->header_fields_appended) { edmail_new->header_fields_appended = field_idx_new; } field_idx = next; } edmail_new->modified = TRUE; } edmail_new->headers_parsed = edmail->headers_parsed; edmail_new->parent = edmail; return edmail_new; } void edit_mail_reset(struct edit_mail *edmail) { struct _header_index *header_idx; struct _header_field_index *field_idx; i_stream_unref(&edmail->stream); field_idx = edmail->header_fields_head; while (field_idx != NULL) { struct _header_field_index *next = field_idx->next; _header_field_unref(field_idx->field); i_free(field_idx); field_idx = next; } header_idx = edmail->headers_head; while (header_idx != NULL) { struct _header_index *next = header_idx->next; _header_unref(header_idx->header); i_free(header_idx); header_idx = next; } edmail->modified = FALSE; } void edit_mail_unwrap(struct edit_mail **edmail) { struct edit_mail *parent; i_assert((*edmail)->refcount > 0); if (--(*edmail)->refcount != 0) return; edit_mail_reset(*edmail); i_stream_unref(&(*edmail)->wrapped_stream); parent = (*edmail)->parent; if (parent == NULL) { mailbox_transaction_rollback(&(*edmail)->mail.mail.transaction); mailbox_free(&(*edmail)->mail.mail.box); edit_mail_raw_storage_drop(); } pool_unref(&(*edmail)->mail.pool); *edmail = NULL; if (parent != NULL) edit_mail_unwrap(&parent); } struct mail *edit_mail_get_mail(struct edit_mail *edmail) { /* Return wrapped mail when nothing is modified yet */ if (!edmail->modified) return &edmail->wrapped->mail; return &edmail->mail.mail; } /* * Editing */ static inline void edit_mail_modify(struct edit_mail *edmail) { edmail->mail.mail.seq++; edmail->modified = TRUE; edmail->snapshot_modified = TRUE; } /* Header modification */ static inline char *_header_value_unfold(const char *value) { string_t *out; unsigned int i; for (i = 0; value[i] != '\0'; i++) { if (value[i] == '\r' || value[i] == '\n') break; } if (value[i] == '\0') return i_strdup(value); out = t_str_new(i + strlen(value+i) + 10); str_append_data(out, value, i); for (; value[i] != '\0'; i++) { if (value[i] == '\n') { i++; if (value[i] == '\0') break; switch (value[i]) { case ' ': str_append_c(out, ' '); break; case '\t': default: str_append_c(out, '\t'); } } else { if (value[i] != '\r') str_append_c(out, value[i]); } } return i_strndup(str_c(out), str_len(out)); } static struct _header_index * edit_mail_header_find(struct edit_mail *edmail, const char *field_name) { struct _header_index *header_idx; header_idx = edmail->headers_head; while (header_idx != NULL) { if (strcasecmp(header_idx->header->name, field_name) == 0) return header_idx; header_idx = header_idx->next; } return NULL; } static struct _header_index * edit_mail_header_create(struct edit_mail *edmail, const char *field_name) { struct _header_index *header_idx; header_idx = edit_mail_header_find(edmail, field_name); if (header_idx == NULL) { header_idx = i_new(struct _header_index, 1); header_idx->header = _header_create(field_name); DLLIST2_APPEND(&edmail->headers_head, &edmail->headers_tail, header_idx); } return header_idx; } static struct _header_index * edit_mail_header_clone(struct edit_mail *edmail, struct _header *header) { struct _header_index *header_idx; header_idx = edmail->headers_head; while (header_idx != NULL) { if (header_idx->header == header) return header_idx; header_idx = header_idx->next; } header_idx = i_new(struct _header_index, 1); header_idx->header = header; _header_ref(header); DLLIST2_APPEND(&edmail->headers_head, &edmail->headers_tail, header_idx); return header_idx; } static struct _header_field_index * edit_mail_header_field_create(struct edit_mail *edmail, const char *field_name, const char *value) { struct _header_index *header_idx; struct _header *header; struct _header_field_index *field_idx; struct _header_field *field; unsigned int lines; /* Get/create header index item */ header_idx = edit_mail_header_create(edmail, field_name); header = header_idx->header; /* Create new field index item */ field_idx = i_new(struct _header_field_index, 1); field_idx->header = header_idx; field_idx->field = field = _header_field_create(header); /* Create header field data (folded if necessary) */ T_BEGIN { string_t *enc_value, *data; enc_value = t_str_new(strlen(field_name) + strlen(value) + 64); data = t_str_new(strlen(field_name) + strlen(value) + 128); message_header_encode(value, enc_value); lines = rfc2822_header_append(data, field_name, str_c(enc_value), edmail->crlf, &field->body_offset); /* Copy to new field */ field->data = i_strndup(str_data(data), str_len(data)); field->size = str_len(data); field->virtual_size = (edmail->crlf ? field->size : field->size + lines); field->lines = lines; } T_END; /* Record original (utf8) value */ field->utf8_value = _header_value_unfold(value); return field_idx; } static void edit_mail_header_field_delete(struct edit_mail *edmail, struct _header_field_index *field_idx, bool update_index) { struct _header_index *header_idx = field_idx->header; struct _header_field *field = field_idx->field; i_assert(header_idx != NULL); edmail->hdr_size.physical_size -= field->size; edmail->hdr_size.virtual_size -= field->virtual_size; edmail->hdr_size.lines -= field->lines; header_idx->count--; if (update_index) { if (header_idx->count == 0) { DLLIST2_REMOVE(&edmail->headers_head, &edmail->headers_tail, header_idx); _header_unref(header_idx->header); i_free(header_idx); } else if (header_idx->first == field_idx) { struct _header_field_index *hfield = header_idx->first->next; while (hfield != NULL && hfield->header != header_idx) hfield = hfield->next; i_assert(hfield != NULL); header_idx->first = hfield; } else if (header_idx->last == field_idx) { struct _header_field_index *hfield = header_idx->last->prev; while (hfield != NULL && hfield->header != header_idx) hfield = hfield->prev; i_assert(hfield != NULL); header_idx->last = hfield; } } DLLIST2_REMOVE(&edmail->header_fields_head, &edmail->header_fields_tail, field_idx); _header_field_unref(field_idx->field); i_free(field_idx); } static struct _header_field_index * edit_mail_header_field_replace(struct edit_mail *edmail, struct _header_field_index *field_idx, const char *newname, const char *newvalue, bool update_index) { struct _header_field_index *field_idx_new; struct _header_index *header_idx = field_idx->header, *header_idx_new; struct _header_field *field = field_idx->field, *field_new; i_assert(header_idx != NULL); i_assert(newname != NULL || newvalue != NULL); if (newname == NULL) newname = header_idx->header->name; if (newvalue == NULL) newvalue = field_idx->field->utf8_value; field_idx_new = edit_mail_header_field_create( edmail, newname, newvalue); field_new = field_idx_new->field; header_idx_new = field_idx_new->header; edmail->hdr_size.physical_size -= field->size; edmail->hdr_size.virtual_size -= field->virtual_size; edmail->hdr_size.lines -= field->lines; edmail->hdr_size.physical_size += field_new->size; edmail->hdr_size.virtual_size += field_new->virtual_size; edmail->hdr_size.lines += field_new->lines; /* Replace header field index */ field_idx_new->prev = field_idx->prev; field_idx_new->next = field_idx->next; if (field_idx->prev != NULL) field_idx->prev->next = field_idx_new; if (field_idx->next != NULL) field_idx->next->prev = field_idx_new; if (edmail->header_fields_head == field_idx) edmail->header_fields_head = field_idx_new; if (edmail->header_fields_tail == field_idx) edmail->header_fields_tail = field_idx_new; if (header_idx_new == header_idx) { if (header_idx->first == field_idx) header_idx->first = field_idx_new; if (header_idx->last == field_idx) header_idx->last = field_idx_new; } else { header_idx->count--; header_idx_new->count++; if (update_index) { if (header_idx->count == 0) { DLLIST2_REMOVE(&edmail->headers_head, &edmail->headers_tail, header_idx); _header_unref(header_idx->header); i_free(header_idx); } else if (header_idx->first == field_idx) { struct _header_field_index *hfield = header_idx->first->next; while (hfield != NULL && hfield->header != header_idx) hfield = hfield->next; i_assert(hfield != NULL); header_idx->first = hfield; } else if (header_idx->last == field_idx) { struct _header_field_index *hfield = header_idx->last->prev; while (hfield != NULL && hfield->header != header_idx) hfield = hfield->prev; i_assert(hfield != NULL); header_idx->last = hfield; } if (header_idx_new->count > 0) { struct _header_field_index *hfield; hfield = edmail->header_fields_head; while (hfield != NULL && hfield->header != header_idx_new) hfield = hfield->next; i_assert(hfield != NULL); header_idx_new->first = hfield; hfield = edmail->header_fields_tail; while (hfield != NULL && hfield->header != header_idx_new) hfield = hfield->prev; i_assert(hfield != NULL); header_idx_new->last = hfield; } } } _header_field_unref(field_idx->field); i_free(field_idx); return field_idx_new; } static inline char * _header_decode(const unsigned char *hdr_data, size_t hdr_data_len) { string_t *str = t_str_new(512); /* hdr_data is already unfolded */ /* Decode MIME encoded-words. */ message_header_decode_utf8((const unsigned char *)hdr_data, hdr_data_len, str, NULL); return i_strdup(str_c(str)); } static int edit_mail_headers_parse(struct edit_mail *edmail) { struct message_header_parser_ctx *hparser; enum message_header_parser_flags hparser_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP | MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE; struct message_header_line *hdr; struct _header_index *header_idx; struct _header_field_index *head = NULL, *tail = NULL, *current; string_t *hdr_data; uoff_t offset = 0, body_offset = 0, vsize_diff = 0; unsigned int lines = 0; int ret; if (edmail->headers_parsed) return 1; i_stream_seek(edmail->wrapped_stream, 0); hparser = message_parse_header_init(edmail->wrapped_stream, NULL, hparser_flags); T_BEGIN { hdr_data = t_str_new(1024); while ((ret = message_parse_header_next(hparser, &hdr)) > 0) { struct _header_field_index *field_idx_new; struct _header_field *field; i_assert(hdr != NULL); if (hdr->eoh) { /* Record whether header ends in CRLF or LF */ edmail->eoh_crlf = hdr->crlf_newline; break; } /* Skip bad headers */ if (hdr->name_len == 0) continue; /* We deny the existence of any 'Content-Length:' header. This header is non-standard and it can wreak havok when the message is modified. */ if (strcasecmp(hdr->name, "Content-Length" ) == 0) continue; if (hdr->continued) { /* Continued line of folded header */ buffer_append(hdr_data, hdr->value, hdr->value_len); } else { /* First line of header */ offset = hdr->name_offset; body_offset = hdr->name_len + hdr->middle_len; str_truncate(hdr_data, 0); buffer_append(hdr_data, hdr->name, hdr->name_len); buffer_append(hdr_data, hdr->middle, hdr->middle_len); buffer_append(hdr_data, hdr->value, hdr->value_len); lines = 0; vsize_diff = 0; } if (!hdr->no_newline) { lines++; if (hdr->crlf_newline) { buffer_append(hdr_data, "\r\n", 2); } else { buffer_append(hdr_data, "\n", 1); vsize_diff++; } } if (hdr->continues) { hdr->use_full_value = TRUE; continue; } /* Create new header field index entry */ field_idx_new = i_new(struct _header_field_index, 1); header_idx = edit_mail_header_create(edmail, hdr->name); header_idx->count++; field_idx_new->header = header_idx; field_idx_new->field = field = _header_field_create(header_idx->header); i_assert(body_offset > 0); field->body_offset = body_offset; field->utf8_value = _header_decode(hdr->full_value, hdr->full_value_len); field->size = str_len(hdr_data); field->virtual_size = field->size + vsize_diff; field->data = i_strndup(str_data(hdr_data), field->size); field->offset = offset; field->lines = lines; DLLIST2_APPEND(&head, &tail, field_idx_new); edmail->hdr_size.physical_size += field->size; edmail->hdr_size.virtual_size += field->virtual_size; edmail->hdr_size.lines += lines; } } T_END; message_parse_header_deinit(&hparser); /* Blocking i/o required */ i_assert(ret != 0); if (ret < 0 && edmail->wrapped_stream->stream_errno != 0) { /* Error; clean up */ i_error("read(%s) failed: %s", i_stream_get_name(edmail->wrapped_stream), i_stream_get_error(edmail->wrapped_stream)); current = head; while (current != NULL) { struct _header_field_index *next = current->next; _header_field_unref(current->field); i_free(current); current = next; } return ret; } /* Insert header field index items in main list */ if (head != NULL && tail != NULL) { if (edmail->header_fields_appended != NULL) { if (edmail->header_fields_head != edmail->header_fields_appended) { edmail->header_fields_appended->prev->next = head; head->prev = edmail->header_fields_appended->prev; } else { edmail->header_fields_head = head; } tail->next = edmail->header_fields_appended; edmail->header_fields_appended->prev = tail; } else if (edmail->header_fields_tail != NULL) { edmail->header_fields_tail->next = head; head->prev = edmail->header_fields_tail; edmail->header_fields_tail = tail; } else { edmail->header_fields_head = head; edmail->header_fields_tail = tail; } } /* Rebuild header index */ current = edmail->header_fields_head; while (current != NULL) { if (current->header->first == NULL) current->header->first = current; current->header->last = current; current = current->next; } /* Clear appended headers */ edmail->header_fields_appended = NULL; edmail->appended_hdr_size.physical_size = 0; edmail->appended_hdr_size.virtual_size = 0; edmail->appended_hdr_size.lines = 0; /* Do not parse headers again */ edmail->headers_parsed = TRUE; return 1; } void edit_mail_header_add(struct edit_mail *edmail, const char *field_name, const char *value, bool last) { struct _header_index *header_idx; struct _header_field_index *field_idx; struct _header_field *field; edit_mail_modify(edmail); field_idx = edit_mail_header_field_create(edmail, field_name, value); header_idx = field_idx->header; field = field_idx->field; /* Add it to the header field index */ if (last) { DLLIST2_APPEND(&edmail->header_fields_head, &edmail->header_fields_tail, field_idx); header_idx->last = field_idx; if (header_idx->first == NULL) header_idx->first = field_idx; if (!edmail->headers_parsed) { if (edmail->header_fields_appended == NULL) { /* Record beginning of appended headers */ edmail->header_fields_appended = field_idx; } edmail->appended_hdr_size.physical_size += field->size; edmail->appended_hdr_size.virtual_size += field->virtual_size; edmail->appended_hdr_size.lines += field->lines; } } else { DLLIST2_PREPEND(&edmail->header_fields_head, &edmail->header_fields_tail, field_idx); header_idx->first = field_idx; if (header_idx->last == NULL) header_idx->last = field_idx; } header_idx->count++; edmail->hdr_size.physical_size += field->size; edmail->hdr_size.virtual_size += field->virtual_size; edmail->hdr_size.lines += field->lines; } int edit_mail_header_delete(struct edit_mail *edmail, const char *field_name, int index) { struct _header_index *header_idx; struct _header_field_index *field_idx; int pos = 0; int ret = 0; /* Make sure headers are parsed */ if (edit_mail_headers_parse(edmail) <= 0) return -1; /* Find the header entry */ header_idx = edit_mail_header_find(edmail, field_name); if (header_idx == NULL) { /* Not found */ return 0; } /* Signal modification */ edit_mail_modify(edmail); /* Iterate through all header fields and remove those that match */ field_idx = (index >= 0 ? header_idx->first : header_idx->last); while (field_idx != NULL) { struct _header_field_index *next = (index >= 0 ? field_idx->next : field_idx->prev); if (field_idx->field->header == header_idx->header) { bool final; if (index >= 0) { pos++; final = (header_idx->last == field_idx); } else { pos--; final = (header_idx->first == field_idx); } if (index == 0 || index == pos) { if (header_idx->first == field_idx) header_idx->first = NULL; if (header_idx->last == field_idx) header_idx->last = NULL; edit_mail_header_field_delete( edmail, field_idx, FALSE); ret++; } if (final || (index != 0 && index == pos)) break; } field_idx = next; } if (index == 0 || header_idx->count == 0) { DLLIST2_REMOVE(&edmail->headers_head, &edmail->headers_tail, header_idx); _header_unref(header_idx->header); i_free(header_idx); } else if (header_idx->first == NULL || header_idx->last == NULL) { struct _header_field_index *current = edmail->header_fields_head; while (current != NULL) { if (current->header == header_idx) { if (header_idx->first == NULL) header_idx->first = current; header_idx->last = current; } current = current->next; } } return ret; } int edit_mail_header_replace(struct edit_mail *edmail, const char *field_name, int index, const char *newname, const char *newvalue) { struct _header_index *header_idx, *header_idx_new; struct _header_field_index *field_idx, *field_idx_new; int pos = 0; int ret = 0; /* Make sure headers are parsed */ if (edit_mail_headers_parse(edmail) <= 0) return -1; /* Find the header entry */ header_idx = edit_mail_header_find(edmail, field_name); if (header_idx == NULL) { /* Not found */ return 0; } /* Signal modification */ edit_mail_modify(edmail); /* Iterate through all header fields and replace those that match */ field_idx = (index >= 0 ? header_idx->first : header_idx->last); field_idx_new = NULL; while (field_idx != NULL) { struct _header_field_index *next = (index >= 0 ? field_idx->next : field_idx->prev); if (field_idx->field->header == header_idx->header) { bool final; if (index >= 0) { pos++; final = (header_idx->last == field_idx); } else { pos--; final = (header_idx->first == field_idx); } if (index == 0 || index == pos) { if (header_idx->first == field_idx) header_idx->first = NULL; if (header_idx->last == field_idx) header_idx->last = NULL; field_idx_new = edit_mail_header_field_replace( edmail, field_idx, newname, newvalue, FALSE); ret++; } if (final || (index != 0 && index == pos)) break; } field_idx = next; } /* Update old header index */ if (header_idx->count == 0) { DLLIST2_REMOVE(&edmail->headers_head, &edmail->headers_tail, header_idx); _header_unref(header_idx->header); i_free(header_idx); } else if (header_idx->first == NULL || header_idx->last == NULL) { struct _header_field_index *current = edmail->header_fields_head; while (current != NULL) { if (current->header == header_idx) { if (header_idx->first == NULL) header_idx->first = current; header_idx->last = current; } current = current->next; } } /* Update new header index */ if (field_idx_new != NULL) { struct _header_field_index *current = edmail->header_fields_head; header_idx_new = field_idx_new->header; while (current != NULL) { if (current->header == header_idx_new) { if (header_idx_new->first == NULL) header_idx_new->first = current; header_idx_new->last = current; } current = current->next; } } return ret; } struct edit_mail_header_iter { struct edit_mail *mail; struct _header_index *header; struct _header_field_index *current; bool reverse:1; }; int edit_mail_headers_iterate_init(struct edit_mail *edmail, const char *field_name, bool reverse, struct edit_mail_header_iter **edhiter_r) { struct edit_mail_header_iter *edhiter; struct _header_index *header_idx = NULL; struct _header_field_index *current = NULL; /* Make sure headers are parsed */ if (edit_mail_headers_parse(edmail) <= 0) { /* Failure */ return -1; } header_idx = edit_mail_header_find(edmail, field_name); if (field_name != NULL && header_idx == NULL) { current = NULL; } else if (!reverse) { current = (header_idx != NULL ? header_idx->first : edmail->header_fields_head); } else { current = (header_idx != NULL ? header_idx->last : edmail->header_fields_tail); if (current->header == NULL) current = current->prev; } if (current == NULL) return 0; edhiter = i_new(struct edit_mail_header_iter, 1); edhiter->mail = edmail; edhiter->header = header_idx; edhiter->reverse = reverse; edhiter->current = current; *edhiter_r = edhiter; return 1; } void edit_mail_headers_iterate_deinit(struct edit_mail_header_iter **edhiter) { i_free(*edhiter); *edhiter = NULL; } void edit_mail_headers_iterate_get(struct edit_mail_header_iter *edhiter, const char **value_r) { const char *raw; int i; i_assert(edhiter->current != NULL && edhiter->current->header != NULL); raw = edhiter->current->field->utf8_value; for (i = strlen(raw)-1; i >= 0; i--) { if (raw[i] != ' ' && raw[i] != '\t') break; } *value_r = t_strndup(raw, i+1); } bool edit_mail_headers_iterate_next(struct edit_mail_header_iter *edhiter) { if (edhiter->current == NULL) return FALSE; do { edhiter->current = (!edhiter->reverse ? edhiter->current->next : edhiter->current->prev ); } while (edhiter->current != NULL && edhiter->current->header != NULL && edhiter->header != NULL && edhiter->current->header != edhiter->header); return (edhiter->current != NULL && edhiter->current->header != NULL); } bool edit_mail_headers_iterate_remove(struct edit_mail_header_iter *edhiter) { struct _header_field_index *field_idx; bool next; i_assert(edhiter->current != NULL && edhiter->current->header != NULL); edit_mail_modify(edhiter->mail); field_idx = edhiter->current; next = edit_mail_headers_iterate_next(edhiter); edit_mail_header_field_delete(edhiter->mail, field_idx, TRUE); return next; } bool edit_mail_headers_iterate_replace(struct edit_mail_header_iter *edhiter, const char *newname, const char *newvalue) { struct _header_field_index *field_idx; bool next; i_assert(edhiter->current != NULL && edhiter->current->header != NULL); edit_mail_modify(edhiter->mail); field_idx = edhiter->current; next = edit_mail_headers_iterate_next(edhiter); edit_mail_header_field_replace(edhiter->mail, field_idx, newname, newvalue, TRUE); return next; } /* Body modification */ // FIXME: implement /* * Mail API */ static void edit_mail_close(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.close(&edmail->wrapped->mail); } static void edit_mail_free(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.free(&edmail->wrapped->mail); edit_mail_unwrap(&edmail); } static void edit_mail_set_seq(struct mail *mail ATTR_UNUSED, uint32_t seq ATTR_UNUSED, bool saving ATTR_UNUSED) { i_panic("edit_mail_set_seq() not implemented"); } static bool ATTR_NORETURN edit_mail_set_uid(struct mail *mail ATTR_UNUSED, uint32_t uid ATTR_UNUSED) { i_panic("edit_mail_set_uid() not implemented"); } static void edit_mail_set_uid_cache_updates(struct mail *mail, bool set) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.set_uid_cache_updates(&edmail->wrapped->mail, set); } static void edit_mail_add_temp_wanted_fields( struct mail *mail ATTR_UNUSED, enum mail_fetch_field fields ATTR_UNUSED, struct mailbox_header_lookup_ctx *headers ATTR_UNUSED) { /* Nothing */ } static enum mail_flags edit_mail_get_flags(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_flags(&edmail->wrapped->mail); } static const char *const *edit_mail_get_keywords(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_keywords(&edmail->wrapped->mail); } static const ARRAY_TYPE(keyword_indexes) * edit_mail_get_keyword_indexes(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_keyword_indexes(&edmail->wrapped->mail); } static uint64_t edit_mail_get_modseq(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_modseq(&edmail->wrapped->mail); } static uint64_t edit_mail_get_pvt_modseq(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_pvt_modseq(&edmail->wrapped->mail); } static int edit_mail_get_parts(struct mail *mail, struct message_part **parts_r) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_parts(&edmail->wrapped->mail, parts_r); } static int edit_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_date(&edmail->wrapped->mail, date_r, timezone_r); } static int edit_mail_get_received_date(struct mail *mail, time_t *date_r) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_received_date(&edmail->wrapped->mail, date_r); } static int edit_mail_get_save_date(struct mail *mail, time_t *date_r) { struct edit_mail *edmail = (struct edit_mail *)mail; return edmail->wrapped->v.get_save_date(&edmail->wrapped->mail, date_r); } static int edit_mail_get_virtual_size(struct mail *mail, uoff_t *size_r) { struct edit_mail *edmail = (struct edit_mail *)mail; if (!edmail->headers_parsed) { *size_r = (edmail->wrapped_hdr_size.virtual_size + edmail->wrapped_body_size.virtual_size); if (!edmail->modified) return 0; } else { *size_r = edmail->wrapped_body_size.virtual_size + 2; } *size_r += (edmail->hdr_size.virtual_size + edmail->body_size.virtual_size); return 0; } static int edit_mail_get_physical_size(struct mail *mail, uoff_t *size_r) { struct edit_mail *edmail = (struct edit_mail *)mail; *size_r = 0; if (!edmail->headers_parsed) { *size_r = (edmail->wrapped_hdr_size.physical_size + edmail->wrapped_body_size.physical_size); if (!edmail->modified) return 0; } else { *size_r = (edmail->wrapped_body_size.physical_size + (edmail->eoh_crlf ? 2 : 1)); } *size_r += (edmail->hdr_size.physical_size + edmail->body_size.physical_size); return 0; } static int edit_mail_get_first_header(struct mail *mail, const char *field_name, bool decode_to_utf8, const char **value_r) { struct edit_mail *edmail = (struct edit_mail *)mail; struct _header_index *header_idx; struct _header_field *field; int ret; /* Check whether mail headers were modified at all */ if (!edmail->modified || edmail->headers_head == NULL) { /* Unmodified */ return edmail->wrapped->v.get_first_header( &edmail->wrapped->mail, field_name, decode_to_utf8, value_r); } /* Try to find modified header */ header_idx = edit_mail_header_find(edmail, field_name); if (header_idx == NULL || header_idx->count == 0 ) { if (!edmail->headers_parsed) { /* No new header */ return edmail->wrapped->v.get_first_header( &edmail->wrapped->mail, field_name, decode_to_utf8, value_r); } *value_r = NULL; return 0; } /* Get the first occurrence */ if (edmail->header_fields_appended == NULL) { /* There are no appended headers, so first is found directly */ field = header_idx->first->field; } else { struct _header_field_index *field_idx; /* Scan prepended headers */ field_idx = edmail->header_fields_head; while (field_idx != NULL) { if (field_idx->header == header_idx) break; if (field_idx == edmail->header_fields_appended) { field_idx = NULL; break; } field_idx = field_idx->next; } if (field_idx == NULL) { /* Check original message */ ret = edmail->wrapped->v.get_first_header( &edmail->wrapped->mail, field_name, decode_to_utf8, value_r); if (ret != 0) return ret; /* Use first (apparently appended) header */ field = header_idx->first->field; } else { field = field_idx->field; } } if (decode_to_utf8) *value_r = field->utf8_value; else *value_r = (const char *)(field->data + field->body_offset); return 1; } static int edit_mail_get_headers(struct mail *mail, const char *field_name, bool decode_to_utf8, const char *const **value_r) { struct edit_mail *edmail = (struct edit_mail *)mail; struct _header_index *header_idx; struct _header_field_index *field_idx; const char *const *headers; ARRAY(const char *) header_values; if (!edmail->modified || edmail->headers_head == NULL) { /* Unmodified */ return edmail->wrapped->v.get_headers( &edmail->wrapped->mail, field_name, decode_to_utf8, value_r); } header_idx = edit_mail_header_find(edmail, field_name); if (header_idx == NULL || header_idx->count == 0 ) { if (!edmail->headers_parsed) { /* No new header */ return edmail->wrapped->v.get_headers( &edmail->wrapped->mail, field_name, decode_to_utf8, value_r); } p_array_init(&header_values, edmail->mail.pool, 1); (void)array_append_space(&header_values); *value_r = array_idx(&header_values, 0); return 0; } /* Merge */ /* Read original headers too if message headers are not parsed */ headers = NULL; if (!edmail->headers_parsed && edmail->wrapped->v.get_headers(&edmail->wrapped->mail, field_name, decode_to_utf8, &headers) < 0) return -1; /* Fill result array */ p_array_init(&header_values, edmail->mail.pool, 32); field_idx = header_idx->first; while (field_idx != NULL) { /* If current field is the first appended one, we need to add original headers first. */ if (field_idx == edmail->header_fields_appended && headers != NULL) { while (*headers != NULL) { array_append(&header_values, headers, 1); headers++; } } /* Add modified header to the list */ if (field_idx->field->header == header_idx->header) { struct _header_field *field = field_idx->field; const char *value; if (decode_to_utf8) value = field->utf8_value; else { value = (const char *)(field->data + field->body_offset); } array_append(&header_values, &value, 1); if (field_idx == header_idx->last) break; } field_idx = field_idx->next; } /* Add original headers if necessary */ if (headers != NULL) { while (*headers != NULL) { array_append(&header_values, headers, 1); headers++; } } (void)array_append_space(&header_values); *value_r = array_idx(&header_values, 0); return 1; } static int ATTR_NORETURN edit_mail_get_header_stream( struct mail *mail ATTR_UNUSED, struct mailbox_header_lookup_ctx *headers ATTR_UNUSED, struct istream **stream_r ATTR_UNUSED) { // FIXME: implement! i_panic("edit_mail_get_header_stream() not implemented"); } static int edit_mail_get_stream(struct mail *mail, bool get_body ATTR_UNUSED, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct edit_mail *edmail = (struct edit_mail *)mail; if (edmail->stream == NULL) edmail->stream = edit_mail_istream_create(edmail); if (hdr_size != NULL) { *hdr_size = edmail->wrapped_hdr_size; hdr_size->physical_size += edmail->hdr_size.physical_size; hdr_size->virtual_size += edmail->hdr_size.virtual_size; hdr_size->lines += edmail->hdr_size.lines; } if (body_size != NULL) *body_size = edmail->wrapped_body_size; *stream_r = edmail->stream; i_stream_seek(edmail->stream, 0); return 0; } static int edit_mail_get_special(struct mail *mail, enum mail_fetch_field field, const char **value_r) { struct edit_mail *edmail = (struct edit_mail *)mail; if (edmail->modified) { /* Block certain fields when modified */ switch (field) { case MAIL_FETCH_GUID: /* This is in essence a new message */ *value_r = ""; return 0; case MAIL_FETCH_STORAGE_ID: /* Prevent hardlink copying */ *value_r = ""; return 0; default: break; } } return edmail->wrapped->v.get_special(&edmail->wrapped->mail, field, value_r); } static int edit_mail_get_backend_mail(struct mail *mail, struct mail **real_mail_r) { struct edit_mail *edmail = (struct edit_mail *)mail; *real_mail_r = edit_mail_get_mail(edmail); return 0; } static void edit_mail_update_flags(struct mail *mail, enum modify_type modify_type, enum mail_flags flags) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.update_flags(&edmail->wrapped->mail, modify_type, flags); } static void edit_mail_update_keywords(struct mail *mail, enum modify_type modify_type, struct mail_keywords *keywords) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.update_keywords(&edmail->wrapped->mail, modify_type, keywords); } static void edit_mail_update_modseq(struct mail *mail, uint64_t min_modseq) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.update_modseq(&edmail->wrapped->mail, min_modseq); } static void edit_mail_update_pvt_modseq(struct mail *mail, uint64_t min_pvt_modseq) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.update_pvt_modseq(&edmail->wrapped->mail, min_pvt_modseq); } static void edit_mail_update_pop3_uidl(struct mail *mail, const char *uidl) { struct edit_mail *edmail = (struct edit_mail *)mail; if (edmail->wrapped->v.update_pop3_uidl != NULL) { edmail->wrapped->v.update_pop3_uidl( &edmail->wrapped->mail, uidl); } } static void edit_mail_expunge(struct mail *mail ATTR_UNUSED) { /* NOOP */ } static void edit_mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field, const char *reason) { struct edit_mail *edmail = (struct edit_mail *)mail; edmail->wrapped->v.set_cache_corrupted(&edmail->wrapped->mail, field, reason); } static struct mail_vfuncs edit_mail_vfuncs = { edit_mail_close, edit_mail_free, edit_mail_set_seq, edit_mail_set_uid, edit_mail_set_uid_cache_updates, NULL, NULL, edit_mail_add_temp_wanted_fields, edit_mail_get_flags, edit_mail_get_keywords, edit_mail_get_keyword_indexes, edit_mail_get_modseq, edit_mail_get_pvt_modseq, edit_mail_get_parts, edit_mail_get_date, edit_mail_get_received_date, edit_mail_get_save_date, edit_mail_get_virtual_size, edit_mail_get_physical_size, edit_mail_get_first_header, edit_mail_get_headers, edit_mail_get_header_stream, edit_mail_get_stream, index_mail_get_binary_stream, edit_mail_get_special, edit_mail_get_backend_mail, edit_mail_update_flags, edit_mail_update_keywords, edit_mail_update_modseq, edit_mail_update_pvt_modseq, edit_mail_update_pop3_uidl, edit_mail_expunge, edit_mail_set_cache_corrupted, NULL, }; /* * Edit Mail Stream */ struct edit_mail_istream { struct istream_private istream; pool_t pool; struct edit_mail *mail; struct _header_field_index *cur_header; uoff_t cur_header_v_offset; bool parent_buffer:1; bool header_read:1; bool eof:1; }; static void edit_mail_istream_destroy(struct iostream_private *stream) { struct edit_mail_istream *edstream = (struct edit_mail_istream *)stream; i_stream_unref(&edstream->istream.parent); i_stream_free_buffer(&edstream->istream); pool_unref(&edstream->pool); } static ssize_t merge_from_parent(struct edit_mail_istream *edstream, uoff_t parent_v_offset, uoff_t parent_end_v_offset, uoff_t copy_v_offset) { struct istream_private *stream = &edstream->istream; uoff_t v_offset, append_v_offset; const unsigned char *data; size_t pos, cur_pos, parent_bytes_left; bool parent_buffer = edstream->parent_buffer; ssize_t ret; i_assert(parent_v_offset <= parent_end_v_offset); edstream->parent_buffer = FALSE; v_offset = stream->istream.v_offset; if (v_offset >= copy_v_offset) { i_assert((v_offset - copy_v_offset) <= parent_end_v_offset); if ((v_offset - copy_v_offset) == parent_end_v_offset) { /* Parent data is all read */ return 0; } } /* Determine where we are appending more data to the stream */ append_v_offset = v_offset + (stream->pos - stream->skip); if (v_offset >= copy_v_offset) { /* Parent buffer used */ cur_pos = (stream->pos - stream->skip); parent_v_offset += (v_offset - copy_v_offset); } else { cur_pos = 0; i_assert(append_v_offset >= copy_v_offset); parent_v_offset += (append_v_offset - copy_v_offset); } /* Seek parent to required position */ i_stream_seek(stream->parent, parent_v_offset); /* Read from parent */ data = i_stream_get_data(stream->parent, &pos); if (pos > cur_pos) ret = 0; else do { /* Use normal read here, since parent data can be returned directly to caller. */ ret = i_stream_read(stream->parent); stream->istream.stream_errno = stream->parent->stream_errno; stream->istream.eof = stream->parent->eof; edstream->eof = stream->parent->eof; data = i_stream_get_data(stream->parent, &pos); /* Check again, in case the parent stream had been seeked backwards and the previous read() didn't get us far enough. */ } while (pos <= cur_pos && ret > 0); /* Don't read beyond parent end offset */ if (parent_end_v_offset != (uoff_t)-1) { parent_bytes_left = (size_t)(parent_end_v_offset - parent_v_offset); if (pos >= parent_bytes_left) { pos = parent_bytes_left; } } if (v_offset < copy_v_offset || ret == -2 || (parent_buffer && (append_v_offset + 1) >= parent_end_v_offset)) { /* Merging with our local buffer; copying data from parent */ if (pos > 0) { size_t avail; if (parent_buffer) { stream->pos = stream->skip = 0; stream->buffer = NULL; } if (!i_stream_try_alloc(stream, pos, &avail)) return -2; pos = (pos > avail ? avail : pos); memcpy(stream->w_buffer + stream->pos, data, pos); stream->pos += pos; stream->buffer = stream->w_buffer; if (cur_pos >= pos) ret = 0; else ret = (ssize_t)(pos - cur_pos); } else { ret = (ret == 0 ? 0 : -1); } } else { /* Just passing buffers from parent; no copying */ ret = (pos > cur_pos ? (ssize_t)(pos - cur_pos) : (ret == 0 ? 0 : -1)); stream->buffer = data; stream->pos = pos; stream->skip = 0; edstream->parent_buffer = TRUE; } i_assert(ret != -1 || stream->istream.eof || stream->istream.stream_errno != 0); return ret; } static ssize_t merge_modified_headers(struct edit_mail_istream *edstream) { struct istream_private *stream = &edstream->istream; struct edit_mail *edmail = edstream->mail; uoff_t v_offset = stream->istream.v_offset, append_v_offset; size_t appended, written, avail, size; if (edstream->cur_header == NULL) { /* No (more) headers */ return 0; } /* Caller must already have committed remaining parent data to our stream buffer. */ i_assert(!edstream->parent_buffer); /* Add modified headers to buffer */ written = 0; while (edstream->cur_header != NULL) { size_t wsize; /* Determine what part of the header was already buffered */ append_v_offset = v_offset + (stream->pos - stream->skip); i_assert(append_v_offset >= edstream->cur_header_v_offset); if (append_v_offset >= edstream->cur_header_v_offset) appended = (size_t)(append_v_offset - edstream->cur_header_v_offset); else appended = 0; i_assert(appended <= edstream->cur_header->field->size); /* Determine how much we want to write */ size = edstream->cur_header->field->size - appended; if (size > 0) { /* Determine how much we can write */ if (!i_stream_try_alloc(stream, size, &avail)) { if (written == 0) return -2; break; } wsize = (size >= avail ? avail : size); /* Write (part of) the header to buffer */ memcpy(stream->w_buffer + stream->pos, edstream->cur_header->field->data + appended, wsize); stream->pos += wsize; stream->buffer = stream->w_buffer; written += wsize; if (wsize < size) { /* Could not write whole header; finish here */ break; } } /* Skip to next header */ edstream->cur_header_v_offset += edstream->cur_header->field->size; edstream->cur_header = edstream->cur_header->next; /* Stop at end of prepended headers if original header is left unparsed */ if (!edmail->headers_parsed && edstream->cur_header == edmail->header_fields_appended) edstream->cur_header = NULL; } if (edstream->cur_header == NULL) { /* Clear offset too, just to be tidy */ edstream->cur_header_v_offset = 0; } i_assert(written > 0); return (ssize_t)written; } static ssize_t edit_mail_istream_read(struct istream_private *stream) { struct edit_mail_istream *edstream = (struct edit_mail_istream *)stream; struct edit_mail *edmail = edstream->mail; uoff_t v_offset, append_v_offset; uoff_t parent_v_offset, parent_end_v_offset, copy_v_offset; uoff_t prep_hdr_size, hdr_size; ssize_t ret = 0; if (edstream->eof) { stream->istream.eof = TRUE; return -1; } if (edstream->parent_buffer && stream->skip == stream->pos) { edstream->parent_buffer = FALSE; stream->pos = stream->skip = 0; stream->buffer = NULL; } /* Merge prepended headers */ if (!edstream->parent_buffer) { ret = merge_modified_headers(edstream); if (ret != 0) return ret; } v_offset = stream->istream.v_offset; append_v_offset = v_offset + (stream->pos - stream->skip); if (!edmail->headers_parsed && edmail->header_fields_appended != NULL && !edstream->header_read) { /* Output headers from original stream */ /* Size of the prepended header */ i_assert(edmail->hdr_size.physical_size >= edmail->appended_hdr_size.physical_size); prep_hdr_size = (edmail->hdr_size.physical_size - edmail->appended_hdr_size.physical_size); /* Calculate offset of header end or appended header. Any final CR is dealt with later. */ hdr_size = (prep_hdr_size + edmail->wrapped_hdr_size.physical_size); if (hdr_size == 0) { /* Corner case that doesn't happen in practice (the original message is never empty). */ edstream->cur_header = edmail->header_fields_appended; edstream->cur_header_v_offset = v_offset; edstream->header_read = TRUE; } else if (append_v_offset <= (hdr_size - 1) && edmail->wrapped_hdr_size.physical_size > 0) { parent_v_offset = stream->parent_start_offset; parent_end_v_offset = (stream->parent_start_offset + edmail->wrapped_hdr_size.physical_size - 1); copy_v_offset = prep_hdr_size; ret = merge_from_parent(edstream, parent_v_offset, parent_end_v_offset, copy_v_offset); if (ret < 0) return ret; append_v_offset = (v_offset + (stream->pos - stream->skip)); i_assert(append_v_offset <= hdr_size - 1); if (append_v_offset == hdr_size - 1) { /* Strip final CR too when it is present */ if (stream->buffer != NULL && stream->buffer[stream->pos-1] == '\r') { stream->pos--; append_v_offset--; ret--; } i_assert(ret >= 0); edstream->cur_header = edmail->header_fields_appended; edstream->cur_header_v_offset = append_v_offset; if (!edstream->parent_buffer) edstream->header_read = TRUE; } if (ret != 0) return ret; } else { edstream->header_read = TRUE; } /* Merge appended headers */ ret = merge_modified_headers(edstream); if (ret != 0) return ret; } /* Header does not come from original mail at all */ if (edmail->headers_parsed) { parent_v_offset = (stream->parent_start_offset + edmail->wrapped_hdr_size.physical_size - (edmail->eoh_crlf ? 2 : 1)); copy_v_offset = edmail->hdr_size.physical_size; /* Corner case that doesn't happen in practice (the original message is never empty). */ } else if (edmail->wrapped_hdr_size.physical_size == 0) { parent_v_offset = stream->parent_start_offset; copy_v_offset = edmail->hdr_size.physical_size; /* Header comes partially from original mail and headers are added between header and body. */ } else if (edmail->header_fields_appended != NULL) { parent_v_offset = (stream->parent_start_offset + edmail->wrapped_hdr_size.physical_size - (edmail->eoh_crlf ? 2 : 1)); copy_v_offset = (edmail->hdr_size.physical_size + edmail->wrapped_hdr_size.physical_size - (edmail->eoh_crlf ? 2 : 1)); /* Header comes partially from original mail, but headers are only prepended. */ } else { parent_v_offset = stream->parent_start_offset; copy_v_offset = edmail->hdr_size.physical_size; } ret = merge_from_parent(edstream, parent_v_offset, (uoff_t)-1, copy_v_offset); if (ret != 0) return ret; stream->istream.eof = stream->parent->eof; edstream->eof = stream->parent->eof; return -1; } static void stream_reset_to(struct edit_mail_istream *edstream, uoff_t v_offset) { edstream->istream.istream.v_offset = v_offset; edstream->istream.skip = 0; edstream->istream.pos = 0; edstream->istream.buffer = NULL; edstream->parent_buffer = FALSE; edstream->eof = FALSE; i_stream_seek(edstream->istream.parent, 0); } static void edit_mail_istream_seek(struct istream_private *stream, uoff_t v_offset, bool mark ATTR_UNUSED) { struct edit_mail_istream *edstream = (struct edit_mail_istream *)stream; struct _header_field_index *cur_header; struct edit_mail *edmail = edstream->mail; uoff_t offset; edstream->header_read = FALSE; edstream->cur_header = NULL; edstream->cur_header_v_offset = 0; /* The beginning */ if (v_offset == 0) { stream_reset_to(edstream, 0); if (edmail->header_fields_head != edmail->header_fields_appended) edstream->cur_header = edmail->header_fields_head; return; } /* Inside (prepended) headers */ if (edmail->headers_parsed) { offset = edmail->hdr_size.physical_size; } else { offset = (edmail->hdr_size.physical_size - edmail->appended_hdr_size.physical_size); } if (v_offset < offset) { stream_reset_to(edstream, v_offset); /* Find the header */ cur_header = edmail->header_fields_head; i_assert(cur_header != NULL && cur_header != edmail->header_fields_appended); edstream->cur_header_v_offset = 0; offset = cur_header->field->size; while (v_offset > offset) { cur_header = cur_header->next; i_assert(cur_header != NULL && cur_header != edmail->header_fields_appended); edstream->cur_header_v_offset = offset; offset += cur_header->field->size; } edstream->cur_header = cur_header; return; } if (!edmail->headers_parsed) { /* Inside original header */ offset = (edmail->hdr_size.physical_size - edmail->appended_hdr_size.physical_size + edmail->wrapped_hdr_size.physical_size); if (v_offset < offset) { stream_reset_to(edstream, v_offset); return; } edstream->header_read = TRUE; /* Inside appended header */ offset = (edmail->hdr_size.physical_size + edmail->wrapped_hdr_size.physical_size); if (v_offset < offset) { stream_reset_to(edstream, v_offset); offset -= edmail->appended_hdr_size.physical_size; cur_header = edmail->header_fields_appended; i_assert(cur_header != NULL); edstream->cur_header_v_offset = offset; offset += cur_header->field->size; while (v_offset > offset) { cur_header = cur_header->next; i_assert(cur_header != NULL); edstream->cur_header_v_offset = offset; offset += cur_header->field->size; } edstream->cur_header = cur_header; return; } } stream_reset_to(edstream, v_offset); edstream->cur_header = NULL; } static void ATTR_NORETURN edit_mail_istream_sync(struct istream_private *stream ATTR_UNUSED) { i_panic("edit-mail istream sync() not implemented"); } static int edit_mail_istream_stat(struct istream_private *stream, bool exact) { struct edit_mail_istream *edstream = (struct edit_mail_istream *)stream; struct edit_mail *edmail = edstream->mail; const struct stat *st; /* Stat the original stream */ if (i_stream_stat(stream->parent, exact, &st) < 0) return -1; stream->statbuf = *st; if (st->st_size == -1 || !exact) return 0; if (!edmail->headers_parsed) { if (!edmail->modified) return 0; } else { stream->statbuf.st_size = (edmail->wrapped_body_size.physical_size + (edmail->eoh_crlf ? 2 : 1)); } stream->statbuf.st_size += (edmail->hdr_size.physical_size + edmail->body_size.physical_size); return 0; } struct istream *edit_mail_istream_create(struct edit_mail *edmail) { struct edit_mail_istream *edstream; struct istream *wrapped = edmail->wrapped_stream; edstream = i_new(struct edit_mail_istream, 1); edstream->pool = pool_alloconly_create(MEMPOOL_GROWING "edit mail stream", 4096); edstream->mail = edmail; edstream->istream.max_buffer_size = wrapped->real_stream->max_buffer_size; edstream->istream.iostream.destroy = edit_mail_istream_destroy; edstream->istream.read = edit_mail_istream_read; edstream->istream.seek = edit_mail_istream_seek; edstream->istream.sync = edit_mail_istream_sync; edstream->istream.stat = edit_mail_istream_stat; edstream->istream.istream.readable_fd = FALSE; edstream->istream.istream.blocking = wrapped->blocking; edstream->istream.istream.seekable = wrapped->seekable; if (edmail->header_fields_head != edmail->header_fields_appended) edstream->cur_header = edmail->header_fields_head; i_stream_seek(wrapped, 0); return i_stream_create(&edstream->istream, wrapped, -1, 0); } dovecot-pigeonhole-2.4.2/src/lib-sieve/util/mail-raw.h0000644000175100001700000000111215100335616024277 0ustar00buildbotbuildbot00000000000000#ifndef MAIL_RAW_H #define MAIL_RAW_H #include "lib.h" #include "master-service.h" struct mail_raw { pool_t pool; struct mail *mail; struct mailbox *box; struct mailbox_transaction_context *trans; }; struct mail_user *mail_raw_user_create(struct mail_user *mail_user); struct mail_raw * mail_raw_open_stream(struct mail_user *ruser, struct istream *input); struct mail_raw * mail_raw_open_file(struct mail_user *ruser, const char *path); struct mail_raw * mail_raw_open_data(struct mail_user *ruser, string_t *mail_data); void mail_raw_close(struct mail_raw **mailr); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/util/mail-raw.c0000644000175100001700000001351115100335616024300 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "istream.h" #include "istream-seekable.h" #include "str.h" #include "str-sanitize.h" #include "strescape.h" #include "safe-mkstemp.h" #include "path-util.h" #include "message-address.h" #include "mbox-from.h" #include "raw-storage.h" #include "mail-storage-service.h" #include "mail-namespace.h" #include "master-service.h" #include "master-service-settings.h" #include "settings-parser.h" #include "mail-raw.h" #include #include #include #include /* * Configuration */ #define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON" /* After buffer grows larger than this, create a temporary file to /tmp where to read the mail. */ #define MAIL_MAX_MEMORY_BUFFER (1024*128) static const char *wanted_headers[] = { "From", "Message-ID", "Subject", "Return-Path", NULL }; /* * Global data */ struct mail_raw_user { struct mail_namespace *ns; struct mail_user *mail_user; }; /* * Raw mail implementation */ static int seekable_fd_callback(const char **path_r, void *context) { struct mail_user *ruser = (struct mail_user *)context; string_t *path; int fd; path = t_str_new(128); mail_user_set_get_temp_prefix(path, ruser->set); fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); if (fd == -1) { i_error("safe_mkstemp(%s) failed: %m", str_c(path)); return -1; } /* we just want the fd, unlink it */ if (i_unlink(str_c(path)) < 0) { /* shouldn't happen.. */ i_close_fd(&fd); return -1; } *path_r = str_c(path); return fd; } static struct istream * mail_raw_create_stream(struct mail_user *ruser, int fd, time_t *mtime_r, const char **sender) { struct istream *input, *input2, *input_list[2]; const unsigned char *data; size_t i, size; int ret, tz; char *env_sender = NULL; *mtime_r = (time_t)-1; fd_set_nonblock(fd, FALSE); input = i_stream_create_fd(fd, 4096); input->blocking = TRUE; /* If input begins with a From-line, drop it */ ret = i_stream_read_bytes(input, &data, &size, 5); if (ret > 0 && memcmp(data, "From ", 5) == 0) { /* Skip until the first LF */ i_stream_skip(input, 5); while (i_stream_read_more(input, &data, &size) > 0) { for (i = 0; i < size; i++) { if (data[i] == '\n') break; } if (i != size) { (void)mbox_from_parse(data, i, mtime_r, &tz, &env_sender); i_stream_skip(input, i + 1); break; } i_stream_skip(input, size); } } if (env_sender != NULL && sender != NULL) *sender = t_strdup(env_sender); i_free(env_sender); if (input->v_offset == 0) { input2 = input; i_stream_ref(input2); } else { input2 = i_stream_create_limit(input, (uoff_t)-1); } i_stream_unref(&input); input_list[0] = input2; input_list[1] = NULL; input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER, seekable_fd_callback, ruser); i_stream_unref(&input2); return input; } /* * Init/Deinit */ struct mail_user *mail_raw_user_create(struct mail_user *mail_user) { struct mail_storage_service_ctx *storage_service = mail_storage_service_user_get_service_ctx( mail_user->service_user); struct settings_instance *set_instance = mail_storage_service_user_get_settings_instance(mail_user->service_user); return raw_storage_create_from_set(storage_service, set_instance); } /* * Open raw mail data */ static struct mail_raw * mail_raw_create(struct mail_user *ruser, struct istream *input, const char *mailfile, const char *sender, time_t mtime) { struct mail_raw *mailr; struct mailbox_header_lookup_ctx *headers_ctx; const char *envelope_sender, *error; int ret; if (mailfile != NULL && *mailfile != '/') { if (t_abspath(mailfile, &mailfile, &error) < 0) i_fatal("t_abspath(%s) failed: %s", mailfile, error); } mailr = i_new(struct mail_raw, 1); envelope_sender = sender != NULL ? sender : DEFAULT_ENVELOPE_SENDER; if (mailfile == NULL) { ret = raw_mailbox_alloc_stream(ruser, input, mtime, envelope_sender, &mailr->box); } else { ret = raw_mailbox_alloc_path(ruser, mailfile, (time_t)-1, envelope_sender, &mailr->box); } if (ret < 0) { if (mailfile == NULL) { i_fatal("Can't open delivery mail as raw: %s", mailbox_get_last_internal_error( mailr->box, NULL)); } else { i_fatal("Can't open delivery mail as raw (file=%s): %s", mailfile, mailbox_get_last_internal_error( mailr->box, NULL)); } } mailr->trans = mailbox_transaction_begin(mailr->box, 0, __func__); headers_ctx = mailbox_header_lookup_init(mailr->box, wanted_headers); mailr->mail = mail_alloc(mailr->trans, 0, headers_ctx); mailbox_header_lookup_unref(&headers_ctx); mail_set_seq(mailr->mail, 1); return mailr; } struct mail_raw * mail_raw_open_stream(struct mail_user *ruser, struct istream *input) { struct mail_raw *mailr; i_assert(input->seekable); i_stream_set_name(input, "data"); mailr = mail_raw_create(ruser, input, NULL, NULL, (time_t)-1); return mailr; } struct mail_raw * mail_raw_open_data(struct mail_user *ruser, string_t *mail_data) { struct mail_raw *mailr; struct istream *input; input = i_stream_create_from_data(str_data(mail_data), str_len(mail_data)); mailr = mail_raw_open_stream(ruser, input); i_stream_unref(&input); return mailr; } struct mail_raw *mail_raw_open_file(struct mail_user *ruser, const char *path) { struct mail_raw *mailr; struct istream *input = NULL; time_t mtime = (time_t)-1; const char *sender = NULL; if (path == NULL || strcmp(path, "-") == 0) { path = NULL; input = mail_raw_create_stream(ruser, 0, &mtime, &sender); } mailr = mail_raw_create(ruser, input, path, sender, mtime); i_stream_unref(&input); return mailr; } void mail_raw_close(struct mail_raw **mailr) { mail_free(&(*mailr)->mail); mailbox_transaction_rollback(&(*mailr)->trans); mailbox_free(&(*mailr)->box); i_free(*mailr); *mailr = NULL; } dovecot-pigeonhole-2.4.2/src/lib-sieve/util/test-edit-mail.c0000644000175100001700000010347415100335616025421 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "test-common.h" #include "path-util.h" #include "buffer.h" #include "str.h" #include "istream.h" #include "istream-concat.h" #include "istream-crlf.h" #include "unlink-directory.h" #include "master-service.h" #include "master-service-settings.h" #include "istream-header-filter.h" #include "mail-storage.h" #include "mail-storage-service.h" #include "mail-user.h" #include "mail-raw.h" #include "edit-mail.h" #include static pool_t test_pool; static struct mail_storage_service_ctx *mail_storage_service = NULL; static struct mail_user *test_mail_user = NULL; static struct mail_storage_service_user *test_service_user = NULL; static const char *mail_home; static char *test_dir; static struct mail_user *test_raw_mail_user = NULL; static void str_append_no_cr(string_t *str, const char *cstr) { const char *p, *poff; poff = p = cstr; while (*p != '\0') { if (*p == '\r') { str_append_data(str, poff, (p - poff)); poff = p+1; } p++; } str_append_data(str, poff, (p - poff)); } static int test_init_mail_user(void) { const char *error; mail_home = p_strdup_printf(test_pool, "%s/test_user.%ld.%ld", test_dir, (long)time(NULL), (long)getpid()); struct mail_storage_service_input input = { .userdb_fields = (const char*const[]){ "mail_driver=maildir", "mail_path=~/", t_strdup_printf("home=%s", mail_home), NULL }, .username = "test@example.com", .no_userdb_lookup = TRUE, .debug = TRUE, }; mail_storage_service = mail_storage_service_init( master_service, (MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS | MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT | MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS)); if (mail_storage_service_lookup(mail_storage_service, &input, &test_service_user, &error) < 0) { i_error("Cannot lookup test user: %s", error); return -1; } if (mail_storage_service_next(mail_storage_service, test_service_user, &test_mail_user, &error) < 0) { i_error("Cannot lookup test user: %s", error); return -1; } return 0; } static void test_deinit_mail_user() { const char *error; mail_user_unref(&test_mail_user); mail_storage_service_user_unref(&test_service_user); mail_storage_service_deinit(&mail_storage_service); if (unlink_directory(mail_home, UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0) i_error("unlink_directory(%s) failed: %s", mail_home, error); } static void test_init(void) { test_pool = pool_alloconly_create(MEMPOOL_GROWING"test pool", 128); test_init_mail_user(); test_raw_mail_user = mail_raw_user_create(test_mail_user); } static void test_deinit(void) { mail_user_unref(&test_raw_mail_user); test_deinit_mail_user(); pool_unref(&test_pool); } static void test_stream_data(struct istream *input, buffer_t *buffer) { const unsigned char *data; size_t size; while (i_stream_read_more(input, &data, &size) > 0) { buffer_append(buffer, data, size); i_stream_skip(input, size); } test_assert(!i_stream_have_bytes_left(input)); test_assert(input->stream_errno == 0); } static void test_stream_data_slow(struct istream *input, buffer_t *buffer) { const unsigned char *data; size_t size; int ret; ret = i_stream_read(input); while (ret > 0 || i_stream_have_bytes_left(input) || ret == -2) { data = i_stream_get_data(input, &size); buffer_append(buffer, data, 1); i_stream_skip(input, 1); ret = i_stream_read(input); } test_assert(!i_stream_have_bytes_left(input)); test_assert(input->stream_errno == 0); } static void test_edit_mail_concatenated(void) { static const char *hide_headers[] = { "Return-Path", "X-Sieve", "X-Sieve-Redirected-From" }; static const char *msg_part1 = "Received: from example.com ([127.0.0.1] helo=example.com)\r\n" " by example.org with LMTP (Dovecot)\r\n" " (envelope-from )\r\n" " id 1er3e8-0015df-QO\r\n" " for timo@example.org;\r\n" " Sat, 03 Mar 2018 10:40:05 +0100\r\n"; static const char *msg_part2 = "Return-Path: \r\n"; static const char *msg_part3 = "Delivered-To: \r\n"; static const char *msg_part4 = "From: \r\n" "To: \r\n" "Subject: Sieve editheader breaks with LMTP\r\n" "\r\n" "Hi,\r\n" "\r\n" "Sieve editheader seems to be broken when used from LMTP\r\n" "\r\n" "Regards,\r\n" "\r\n" "Stephan.\r\n"; static const char *msg_added = "X-Filter-Junk-Type: NONE\r\n" "X-Filter-Junk-Flag: NO\r\n"; struct istream *inputs[5], *input_msg, *input_filt, *input_mail, *input; buffer_t *buffer; struct mail_raw *rawmail; struct edit_mail *edmail; struct mail *mail; string_t *expected; const char *value; test_begin("edit-mail - concatenated"); test_init(); /* Compose the message */ inputs[0] = i_stream_create_from_data(msg_part1, strlen(msg_part1)); inputs[1] = i_stream_create_from_data(msg_part2, strlen(msg_part2)); inputs[2] = i_stream_create_from_data(msg_part3, strlen(msg_part3)); inputs[3] = i_stream_create_from_data(msg_part4, strlen(msg_part4)); inputs[4] = NULL; input_msg = i_stream_create_concat(inputs); i_stream_unref(&inputs[0]); i_stream_unref(&inputs[1]); i_stream_unref(&inputs[2]); i_stream_unref(&inputs[3]); rawmail = mail_raw_open_stream(test_raw_mail_user, input_msg); /* Add headers */ edmail = edit_mail_wrap(rawmail->mail); edit_mail_header_add(edmail, "X-Filter-Junk-Flag", "NO", FALSE); edit_mail_header_add(edmail, "X-Filter-Junk-Type", "NONE", FALSE); mail = edit_mail_get_mail(edmail); /* Evaluate modified header */ test_assert(mail_get_first_header_utf8(mail, "Subject", &value) > 0); test_assert(strcmp(value, "Sieve editheader breaks with LMTP") == 0); test_assert(mail_get_first_header_utf8(mail, "X-Filter-Junk-Flag", &value) > 0); test_assert(strcmp(value, "NO") == 0); test_assert(mail_get_first_header_utf8(mail, "X-Filter-Junk-Type", &value) > 0); test_assert(strcmp(value, "NONE") == 0); test_assert(mail_get_first_header_utf8(mail, "Delivered-To", &value) > 0); /* Prepare tests */ if (mail_get_stream(mail, NULL, NULL, &input_mail) < 0) { i_fatal("Failed to open mail stream: %s", mailbox_get_last_internal_error(mail->box, NULL)); } buffer = buffer_create_dynamic(default_pool, 1024); expected = t_str_new(1024); /* Added */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); input = input_mail; test_stream_data(input_mail, buffer); str_truncate(expected, 0); str_append(expected, msg_added); str_append(expected, msg_part1); str_append(expected, msg_part2); str_append(expected, msg_part3); str_append(expected, msg_part4); test_out("added", strcmp(str_c(buffer), str_c(expected)) == 0); /* Added, slow */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); test_stream_data_slow(input_mail, buffer); str_truncate(expected, 0); str_append(expected, msg_added); str_append(expected, msg_part1); str_append(expected, msg_part2); str_append(expected, msg_part3); str_append(expected, msg_part4); test_out("added, slow", strcmp(str_c(buffer), str_c(expected)) == 0); /* Added, filtered */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); input_filt = i_stream_create_header_filter( input_mail, (HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR), hide_headers, N_ELEMENTS(hide_headers), *null_header_filter_callback, NULL); input = i_stream_create_lf(input_filt); i_stream_unref(&input_filt); test_stream_data(input, buffer); test_assert(!i_stream_have_bytes_left(input_mail)); test_assert(input_mail->stream_errno == 0); str_truncate(expected, 0); str_append_no_cr(expected, msg_added); str_append_no_cr(expected, msg_part1); str_append_no_cr(expected, msg_part3); str_append_no_cr(expected, msg_part4); test_out("added, filtered", strcmp(str_c(buffer), str_c(expected)) == 0); i_stream_unref(&input); /* Added, filtered, slow */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); input_filt = i_stream_create_header_filter( input_mail, (HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR), hide_headers, N_ELEMENTS(hide_headers), *null_header_filter_callback, NULL); input = i_stream_create_lf(input_filt); i_stream_unref(&input_filt); test_stream_data_slow(input, buffer); test_assert(!i_stream_have_bytes_left(input_mail)); test_assert(input_mail->stream_errno == 0); str_truncate(expected, 0); str_append_no_cr(expected, msg_added); str_append_no_cr(expected, msg_part1); str_append_no_cr(expected, msg_part3); str_append_no_cr(expected, msg_part4); test_out("added, filtered, slow", strcmp(str_c(buffer), str_c(expected)) == 0); i_stream_unref(&input); /* Delete header */ edit_mail_header_delete(edmail, "Delivered-To", 0); /* Evaluate modified header */ test_assert(mail_get_first_header_utf8(mail, "Subject", &value) > 0); test_assert(strcmp(value, "Sieve editheader breaks with LMTP") == 0); test_assert(mail_get_first_header_utf8(mail, "X-Filter-Junk-Flag", &value) > 0); test_assert(strcmp(value, "NO") == 0); test_assert(mail_get_first_header_utf8(mail, "X-Filter-Junk-Type", &value) > 0); test_assert(strcmp(value, "NONE") == 0); test_assert(mail_get_first_header_utf8(mail, "Delivered-To", &value) == 0); /* Deleted */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); input = input_mail; test_stream_data(input_mail, buffer); str_truncate(expected, 0); str_append(expected, msg_added); str_append(expected, msg_part1); str_append(expected, msg_part2); str_append(expected, msg_part4); test_out("deleted", strcmp(str_c(buffer), str_c(expected)) == 0); /* Deleted, slow */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); test_stream_data_slow(input_mail, buffer); str_truncate(expected, 0); str_append(expected, msg_added); str_append(expected, msg_part1); str_append(expected, msg_part2); str_append(expected, msg_part4); test_out("deleted, slow", strcmp(str_c(buffer), str_c(expected)) == 0); /* Deleted, filtered */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); input_filt = i_stream_create_header_filter( input_mail, (HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR), hide_headers, N_ELEMENTS(hide_headers), *null_header_filter_callback, NULL); input = i_stream_create_lf(input_filt); i_stream_unref(&input_filt); test_stream_data(input, buffer); test_assert(!i_stream_have_bytes_left(input_mail)); test_assert(input_mail->stream_errno == 0); str_truncate(expected, 0); str_append_no_cr(expected, msg_added); str_append_no_cr(expected, msg_part1); str_append_no_cr(expected, msg_part4); test_out("deleted, filtered", strcmp(str_c(buffer), str_c(expected)) == 0); i_stream_unref(&input); /* Deleted, filtered, slow */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); input_filt = i_stream_create_header_filter(input_mail, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hide_headers, N_ELEMENTS(hide_headers), *null_header_filter_callback, NULL); input = i_stream_create_lf(input_filt); i_stream_unref(&input_filt); test_stream_data_slow(input, buffer); test_assert(!i_stream_have_bytes_left(input_mail)); test_assert(input_mail->stream_errno == 0); str_truncate(expected, 0); str_append_no_cr(expected, msg_added); str_append_no_cr(expected, msg_part1); str_append_no_cr(expected, msg_part4); test_out("deleted, filtered, slow", strcmp(str_c(buffer), str_c(expected)) == 0); i_stream_unref(&input); /* clean up */ buffer_free(&buffer); edit_mail_unwrap(&edmail); mail_raw_close(&rawmail); i_stream_unref(&input_msg); test_deinit(); test_end(); } static const char *big_header = "X-A: AAAA\n" "X-Big-One: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" " AAAAAAAAAAAAAAAAAAAAAAAAA\n" "X-B: BBBB\n" "\n" "Frop!\n"; static void test_edit_mail_big_header(void) { struct istream *input_msg, *input_mail; buffer_t *buffer; struct mail_raw *rawmail; struct edit_mail *edmail; struct mail *mail; const char *value; test_begin("edit-mail - big header"); test_init(); /* compose the message */ input_msg = i_stream_create_from_data(big_header, strlen(big_header)); rawmail = mail_raw_open_stream(test_raw_mail_user, input_msg); edmail = edit_mail_wrap(rawmail->mail); /* delete header */ edit_mail_header_delete(edmail, "X-B", 0); mail = edit_mail_get_mail(edmail); /* prepare tests */ if (mail_get_stream(mail, NULL, NULL, &input_mail) < 0) { i_fatal("Failed to open mail stream: %s", mailbox_get_last_internal_error(mail->box, NULL)); } buffer = buffer_create_dynamic(default_pool, 1024); /* evaluate modified header */ test_assert(mail_get_first_header_utf8(mail, "X-B", &value) == 0); /* deleted */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); test_stream_data(input_mail, buffer); /* clean up */ buffer_free(&buffer); edit_mail_unwrap(&edmail); mail_raw_close(&rawmail); i_stream_unref(&input_msg); test_deinit(); test_end(); } static void test_edit_mail_small_buffer(void) { static const char *message = "X-A: AAAA\n" "X-B: BBBB\n" "\n" "Frop!\n"; struct istream *input_msg, *input_mail; buffer_t *buffer; struct mail_raw *rawmail; struct edit_mail *edmail; struct mail *mail; const char *value; unsigned int i; test_begin("edit-mail - small buffer"); test_init(); /* compose the message */ input_msg = i_stream_create_from_data(message, strlen(message)); i_stream_set_max_buffer_size(input_msg, 16); rawmail = mail_raw_open_stream(test_raw_mail_user, input_msg); edmail = edit_mail_wrap(rawmail->mail); /* add headers */ for (i = 0; i < 16; i++) { edit_mail_header_add(edmail, "X-F", "FF", FALSE); edit_mail_header_add(edmail, "X-L", "LL", TRUE); } mail = edit_mail_get_mail(edmail); /* prepare tests */ if (mail_get_stream(mail, NULL, NULL, &input_mail) < 0) { i_fatal("Failed to open mail stream: %s", mailbox_get_last_internal_error(mail->box, NULL)); } buffer = buffer_create_dynamic(default_pool, 1024); /* evaluate modified header */ test_assert(mail_get_first_header_utf8(mail, "X-F", &value) > 0); test_assert(mail_get_first_header_utf8(mail, "X-A", &value) > 0); test_assert(mail_get_first_header_utf8(mail, "X-B", &value) > 0); test_assert(mail_get_first_header_utf8(mail, "X-L", &value) > 0); /* check stream read */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); test_stream_data(input_mail, buffer); /* clean up */ buffer_free(&buffer); edit_mail_unwrap(&edmail); mail_raw_close(&rawmail); i_stream_unref(&input_msg); test_deinit(); test_end(); } static void test_edit_mail_empty(void) { struct istream *input_msg, *input_mail; buffer_t *buffer; struct mail_raw *rawmail; struct edit_mail *edmail; struct mail *mail; const char *value; test_begin("edit-mail - empty message"); test_init(); /* Compose the message */ input_msg = i_stream_create_from_data("", 0); rawmail = mail_raw_open_stream(test_raw_mail_user, input_msg); edmail = edit_mail_wrap(rawmail->mail); /* Add header */ edit_mail_header_add(edmail, "X-B", "Frop", TRUE); mail = edit_mail_get_mail(edmail); /* Prepare tests */ if (mail_get_stream(mail, NULL, NULL, &input_mail) < 0) { i_fatal("Failed to open mail stream: %s", mailbox_get_last_error(mail->box, NULL)); } buffer = buffer_create_dynamic(default_pool, 1024); /* Evaluate modified header */ test_assert(mail_get_first_header_utf8(mail, "X-B", &value) > 0 && strcmp(value, "Frop") == 0); /* Added */ i_stream_seek(input_mail, 0); buffer_set_used_size(buffer, 0); test_stream_data(input_mail, buffer); /* Clean up */ buffer_free(&buffer); edit_mail_unwrap(&edmail); mail_raw_close(&rawmail); i_stream_unref(&input_msg); test_deinit(); test_end(); } int main(int argc, char *argv[]) { static void (*test_functions[])(void) = { test_edit_mail_concatenated, test_edit_mail_big_header, test_edit_mail_small_buffer, test_edit_mail_empty, NULL }; const enum master_service_flags service_flags = MASTER_SERVICE_FLAG_STANDALONE | MASTER_SERVICE_FLAG_DONT_SEND_STATS | MASTER_SERVICE_FLAG_CONFIG_BUILTIN; const char *cwd, *error; int ret; master_service = master_service_init("test-edit-header", service_flags, &argc, &argv, ""); if (master_service_settings_read_simple(master_service, &error) < 0) i_fatal("%s", error); master_service_init_finish(master_service); if (t_get_working_dir(&cwd, &error) < 0) i_fatal("getcwd() failed: %s", error); test_dir = i_strdup(cwd); ret = test_run(test_functions); i_free(test_dir); master_service_deinit(&master_service); return ret; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-address-parts.c0000644000175100001700000003207715100335616025507 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "compat.h" #include "mempool.h" #include "hash.h" #include "array.h" #include "str-sanitize.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-address.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "sieve-address-parts.h" #include /* * Default address parts */ const struct sieve_address_part_def *sieve_core_address_parts[] = { &all_address_part, &local_address_part, &domain_address_part }; const unsigned int sieve_core_address_parts_count = N_ELEMENTS(sieve_core_address_parts); /* * Address-part 'extension' */ static bool addrp_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def address_part_extension = { .name = "@address-parts", .validator_load = addrp_validator_load }; /* * Validator context: * name-based address-part registry. */ static struct sieve_validator_object_registry * _get_object_registry(struct sieve_validator *valdtr) { struct sieve_instance *svinst; const struct sieve_extension *adrp_ext; svinst = sieve_validator_svinst(valdtr); adrp_ext = sieve_get_address_part_extension(svinst); return sieve_validator_object_registry_get(valdtr, adrp_ext); } void sieve_address_part_register( struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_address_part_def *addrp_def) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); sieve_validator_object_registry_add(regs, ext, &addrp_def->obj_def); } static bool sieve_address_part_exists(struct sieve_validator *valdtr, const char *identifier) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); return sieve_validator_object_registry_find(regs, identifier, NULL); } static const struct sieve_address_part * sieve_address_part_create_instance(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier) { struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); struct sieve_object object; struct sieve_address_part *addrp; if (!sieve_validator_object_registry_find(regs, identifier, &object)) return NULL; addrp = p_new(sieve_command_pool(cmd), struct sieve_address_part, 1); addrp->object = object; addrp->def = (const struct sieve_address_part_def *) object.def; return addrp; } static bool addrp_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct sieve_validator_object_registry *regs = sieve_validator_object_registry_init(valdtr, ext); unsigned int i; /* Register core address-parts */ for (i = 0; i < sieve_core_address_parts_count; i++) { sieve_validator_object_registry_add( regs, NULL, &(sieve_core_address_parts[i]->obj_def)); } return TRUE; } void sieve_address_parts_link_tags(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code) { struct sieve_instance *svinst; const struct sieve_extension *adrp_ext; svinst = sieve_validator_svinst(valdtr); adrp_ext = sieve_get_address_part_extension(svinst); sieve_validator_register_tag(valdtr, cmd_reg, adrp_ext, &address_part_tag, id_code); } /* * Address-part tagged argument */ /* Forward declarations */ static bool tag_address_part_is_instance_of(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext, const char *identifier, void **data); static bool tag_address_part_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_address_part_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); /* Argument object */ const struct sieve_argument_def address_part_tag = { .identifier = "ADDRESS-PART", .is_instance_of = tag_address_part_is_instance_of, .validate = tag_address_part_validate, .generate = tag_address_part_generate }; /* Argument implementation */ static bool tag_address_part_is_instance_of(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext ATTR_UNUSED, const char *identifier, void **data) { const struct sieve_address_part *addrp; if (data == NULL) return sieve_address_part_exists(valdtr, identifier); if ((addrp = sieve_address_part_create_instance( valdtr, cmd, identifier)) == NULL) return FALSE; *data = (void *)addrp; return TRUE; } static bool tag_address_part_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd ATTR_UNUSED) { /* NOTE: Currenly trivial, but might need to allow for further validation for future extensions. */ /* Syntax: ":localpart" / ":domain" / ":all" (subject to extension) */ /* Skip tag */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool tag_address_part_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { struct sieve_address_part *addrp = (struct sieve_address_part *)arg->argument->data; sieve_opr_address_part_emit(cgenv->sblock, addrp); return TRUE; } /* * Address-part operand */ const struct sieve_operand_class sieve_address_part_operand_class = { "address part" }; static const struct sieve_extension_objects core_address_parts = SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_address_parts); const struct sieve_operand_def address_part_operand = { .name = "address-part", .code = SIEVE_OPERAND_ADDRESS_PART, .class = &sieve_address_part_operand_class, .interface = &core_address_parts }; /* * Address-part string list */ static int sieve_address_part_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void sieve_address_part_stringlist_reset(struct sieve_stringlist *_strlist); static int sieve_address_part_stringlist_get_length(struct sieve_stringlist *_strlist); static void sieve_address_part_stringlist_set_trace(struct sieve_stringlist *_strlist, bool trace); struct sieve_address_part_stringlist { struct sieve_stringlist strlist; const struct sieve_address_part *addrp; struct sieve_address_list *addresses; }; struct sieve_stringlist * sieve_address_part_stringlist_create(const struct sieve_runtime_env *renv, const struct sieve_address_part *addrp, struct sieve_address_list *addresses) { struct sieve_address_part_stringlist *strlist; strlist = t_new(struct sieve_address_part_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.next_item = sieve_address_part_stringlist_next_item; strlist->strlist.reset = sieve_address_part_stringlist_reset; strlist->strlist.get_length = sieve_address_part_stringlist_get_length; strlist->strlist.set_trace = sieve_address_part_stringlist_set_trace; strlist->addrp = addrp; strlist->addresses = addresses; return &strlist->strlist; } static int sieve_address_part_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct sieve_address_part_stringlist *strlist = (struct sieve_address_part_stringlist *)_strlist; struct smtp_address item; string_t *item_unparsed; int ret; *str_r = NULL; while (*str_r == NULL) { if ((ret = sieve_address_list_next_item( strlist->addresses, &item, &item_unparsed)) <= 0) return ret; if (item.localpart == NULL) { if (item_unparsed != NULL) { if (_strlist->trace) { sieve_runtime_trace( _strlist->runenv, 0, "extracting '%s' part from non-address value '%s'", sieve_address_part_name(strlist->addrp), str_sanitize(str_c(item_unparsed), 80)); } if (str_len(item_unparsed) == 0 || sieve_address_part_is(strlist->addrp, all_address_part)) *str_r = item_unparsed; } } else { const struct sieve_address_part *addrp = strlist->addrp; const char *part = NULL; if (_strlist->trace) { sieve_runtime_trace( _strlist->runenv, 0, "extracting '%s' part from address %s", sieve_address_part_name(strlist->addrp), smtp_address_encode_path(&item)); } if (addrp->def != NULL && addrp->def->extract_from != NULL) part = addrp->def->extract_from(addrp, &item); if (part != NULL) *str_r = t_str_new_const(part, strlen(part)); } } return 1; } static void sieve_address_part_stringlist_reset(struct sieve_stringlist *_strlist) { struct sieve_address_part_stringlist *strlist = (struct sieve_address_part_stringlist *)_strlist; sieve_address_list_reset(strlist->addresses); } static int sieve_address_part_stringlist_get_length(struct sieve_stringlist *_strlist) { struct sieve_address_part_stringlist *strlist = (struct sieve_address_part_stringlist *)_strlist; return sieve_address_list_get_length(strlist->addresses); } static void sieve_address_part_stringlist_set_trace(struct sieve_stringlist *_strlist, bool trace) { struct sieve_address_part_stringlist *strlist = (struct sieve_address_part_stringlist *)_strlist; sieve_address_list_set_trace(strlist->addresses, trace); } /* * Default ADDRESS-PART, MATCH-TYPE, COMPARATOR access */ int sieve_addrmatch_opr_optional_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, signed int *opt_code) { signed int _opt_code = 0; bool final = FALSE, opok = TRUE; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } while (opok) { int opt; if ((opt = sieve_opr_optional_dump( denv, address, opt_code)) <= 0) return opt; switch (*opt_code) { case SIEVE_MATCH_OPT_COMPARATOR: opok = sieve_opr_comparator_dump(denv, address); break; case SIEVE_MATCH_OPT_MATCH_TYPE: opok = sieve_opr_match_type_dump(denv, address); break; case SIEVE_AM_OPT_ADDRESS_PART: opok = sieve_opr_address_part_dump(denv, address); break; default: return (final ? -1 : 1); } } return -1; } int sieve_addrmatch_opr_optional_read(const struct sieve_runtime_env *renv, sieve_size_t *address, signed int *opt_code, int *exec_status, struct sieve_address_part *addrp, struct sieve_match_type *mtch, struct sieve_comparator *cmp) { signed int _opt_code = 0; bool final = FALSE; int status = SIEVE_EXEC_OK; if (opt_code == NULL) { opt_code = &_opt_code; final = TRUE; } if (exec_status != NULL) *exec_status = SIEVE_EXEC_OK; while (status == SIEVE_EXEC_OK) { int opt; if ((opt = sieve_opr_optional_read( renv, address, opt_code)) <= 0){ if (opt < 0 && exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return opt; } switch (*opt_code) { case SIEVE_MATCH_OPT_COMPARATOR: if (cmp == NULL) { sieve_runtime_trace_error( renv, "unexpected comparator operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } status = sieve_opr_comparator_read(renv, address, cmp); break; case SIEVE_MATCH_OPT_MATCH_TYPE: if (mtch == NULL) { sieve_runtime_trace_error( renv, "unexpected match-type operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } status = sieve_opr_match_type_read(renv, address, mtch); break; case SIEVE_AM_OPT_ADDRESS_PART: if (addrp == NULL) { sieve_runtime_trace_error( renv, "unexpected address-part operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } status = sieve_opr_address_part_read( renv, address, addrp); break; default: if (final) { sieve_runtime_trace_error( renv, "invalid optional operand"); if (exec_status != NULL) *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } return 1; } } if (exec_status != NULL) *exec_status = status; return -1; } /* * Core address-part modifiers */ static const char * addrp_all_extract_from(const struct sieve_address_part *addrp ATTR_UNUSED, const struct smtp_address *address) { if (address->localpart == NULL) return NULL; return smtp_address_encode(address); } static const char * addrp_domain_extract_from(const struct sieve_address_part *addrp ATTR_UNUSED, const struct smtp_address *address) { return address->domain; } static const char * addrp_localpart_extract_from(const struct sieve_address_part *addrp ATTR_UNUSED, const struct smtp_address *address) { return address->localpart; } const struct sieve_address_part_def all_address_part = { SIEVE_OBJECT("all", &address_part_operand, SIEVE_ADDRESS_PART_ALL), .extract_from = addrp_all_extract_from }; const struct sieve_address_part_def local_address_part = { SIEVE_OBJECT("localpart", &address_part_operand, SIEVE_ADDRESS_PART_LOCAL), .extract_from = addrp_localpart_extract_from }; const struct sieve_address_part_def domain_address_part = { SIEVE_OBJECT("domain", &address_part_operand, SIEVE_ADDRESS_PART_DOMAIN), .extract_from = addrp_domain_extract_from }; dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-lexer.c0000644000175100001700000005272615100335616024055 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "compat.h" #include "str.h" #include "str-sanitize.h" #include "istream.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-error.h" #include "sieve-script.h" #include "sieve-lexer.h" #include #include #include #include #include #include /* * Useful macros */ #define DIGIT_VAL(c) (c - '0') /* * Lexer object */ struct sieve_lexical_scanner { pool_t pool; struct sieve_instance *svinst; struct sieve_script *script; struct istream *input; struct sieve_error_handler *ehandler; /* Currently scanned data */ const unsigned char *buffer; size_t buffer_size; size_t buffer_pos; struct sieve_lexer lexer; int current_line; }; const struct sieve_lexer * sieve_lexer_create(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r) { struct sieve_lexical_scanner *scanner; struct sieve_instance *svinst = sieve_script_svinst(script); struct istream *stream; const struct stat *st; /* Open script as stream */ if (sieve_script_get_stream(script, &stream, error_code_r) < 0) return NULL; /* Check script size */ if (i_stream_stat(stream, TRUE, &st) >= 0 && st->st_size > 0 && svinst->set->max_script_size > 0 && (uoff_t)st->st_size > svinst->set->max_script_size) { sieve_error(ehandler, sieve_script_name(script), "sieve script is too large (max %zu bytes)", svinst->set->max_script_size); if (error_code_r != NULL) *error_code_r = SIEVE_ERROR_NOT_POSSIBLE; return NULL; } scanner = i_new(struct sieve_lexical_scanner, 1); scanner->lexer.scanner = scanner; scanner->ehandler = ehandler; sieve_error_handler_ref(ehandler); scanner->input = stream; i_stream_ref(scanner->input); scanner->script = script; sieve_script_ref(script); scanner->buffer = NULL; scanner->buffer_size = 0; scanner->buffer_pos = 0; scanner->lexer.token_type = STT_NONE; scanner->lexer.token_str_value = str_new(default_pool, 256); scanner->lexer.token_int_value = 0; scanner->lexer.token_line = 1; scanner->current_line = 1; return &scanner->lexer; } void sieve_lexer_free(const struct sieve_lexer **_lexer) { const struct sieve_lexer *lexer = *_lexer; struct sieve_lexical_scanner *scanner = lexer->scanner; i_stream_unref(&scanner->input); sieve_script_unref(&scanner->script); sieve_error_handler_unref(&scanner->ehandler); str_free(&scanner->lexer.token_str_value); i_free(scanner); *_lexer = NULL; } /* * Internal error handling */ inline static void ATTR_FORMAT(4, 5) sieve_lexer_error(const struct sieve_lexer *lexer, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { struct sieve_lexical_scanner *scanner = lexer->scanner; struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); T_BEGIN { params.location = sieve_error_script_location(scanner->script, scanner->current_line); sieve_logv(scanner->ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #define sieve_lexer_error(lexer, ...) \ sieve_lexer_error(lexer, __FILE__, __LINE__, __VA_ARGS__) inline static void ATTR_FORMAT(4, 5) sieve_lexer_warning(const struct sieve_lexer *lexer, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { struct sieve_lexical_scanner *scanner = lexer->scanner; struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); T_BEGIN { params.location = sieve_error_script_location(scanner->script, scanner->current_line); sieve_logv(scanner->ehandler, ¶ms, fmt, args); } T_END; va_end(args); } #define sieve_lexer_warning(lexer, ...) \ sieve_lexer_warning(lexer, __FILE__, __LINE__, __VA_ARGS__) const char *sieve_lexer_token_description(const struct sieve_lexer *lexer) { switch (lexer->token_type) { case STT_NONE: return "no token (bug)"; case STT_WHITESPACE: return "whitespace (bug)"; case STT_EOF: return "end of file"; case STT_NUMBER: return "number"; case STT_IDENTIFIER: return "identifier"; case STT_TAG: return "tag"; case STT_STRING: return "string"; case STT_RBRACKET: return "')'"; case STT_LBRACKET: return "'('"; case STT_RCURLY: return "'}'"; case STT_LCURLY: return "'{'"; case STT_RSQUARE: return "']'"; case STT_LSQUARE: return "'['"; case STT_SEMICOLON: return "';'"; case STT_COMMA: return "','"; case STT_SLASH: return "'/'"; case STT_COLON: return "':'"; case STT_GARBAGE: return "unknown characters"; case STT_ERROR: return "error token (bug)"; } return "unknown token (bug)"; } /* * Debug */ void sieve_lexer_token_print(const struct sieve_lexer *lexer) { switch (lexer->token_type) { case STT_NONE: printf("??NONE?? "); break; case STT_WHITESPACE: printf("??WHITESPACE?? "); break; case STT_EOF: printf("EOF\n"); break; case STT_NUMBER: printf("NUMBER "); break; case STT_IDENTIFIER: printf("IDENTIFIER "); break; case STT_TAG: printf("TAG "); break; case STT_STRING: printf("STRING "); break; case STT_RBRACKET: printf(") "); break; case STT_LBRACKET: printf("( "); break; case STT_RCURLY: printf("}\n"); break; case STT_LCURLY: printf("{\n"); break; case STT_RSQUARE: printf("] "); break; case STT_LSQUARE: printf("[ "); break; case STT_SEMICOLON: printf(";\n"); break; case STT_COMMA: printf(", "); break; case STT_SLASH: printf("/ "); break; case STT_COLON: printf(": "); break; case STT_GARBAGE: printf(">>GARBAGE<<"); break; case STT_ERROR: printf(">>ERROR<<"); break; default: printf("UNKNOWN "); break; } } /* * Lexical scanning */ static void sieve_lexer_shift(struct sieve_lexical_scanner *scanner) { if (scanner->buffer_size > 0 && scanner->buffer[scanner->buffer_pos] == '\n') scanner->current_line++; if (scanner->buffer_size > 0 && scanner->buffer_pos + 1 < scanner->buffer_size) scanner->buffer_pos++; else { if (scanner->buffer_size > 0) i_stream_skip(scanner->input, scanner->buffer_size); scanner->buffer = i_stream_get_data(scanner->input, &scanner->buffer_size); if (scanner->buffer_size == 0 && i_stream_read(scanner->input) > 0) { scanner->buffer = i_stream_get_data( scanner->input, &scanner->buffer_size); } scanner->buffer_pos = 0; } } static inline int sieve_lexer_curchar(struct sieve_lexical_scanner *scanner) { if (scanner->buffer_size == 0) return -1; return scanner->buffer[scanner->buffer_pos]; } static inline const char *_char_sanitize(int ch) { if (ch > 31 && ch < 127) return t_strdup_printf("'%c'", ch); return t_strdup_printf("0x%02x", ch); } static bool sieve_lexer_scan_number(struct sieve_lexical_scanner *scanner) { struct sieve_lexer *lexer = &scanner->lexer; uintmax_t value; string_t *str; bool overflow = FALSE; str_truncate(lexer->token_str_value,0); str = lexer->token_str_value; while (i_isdigit(sieve_lexer_curchar(scanner))) { str_append_c(str, sieve_lexer_curchar(scanner)); sieve_lexer_shift(scanner); } if (str_to_uintmax(str_c(str), &value) < 0 || value > (sieve_number_t)-1) { overflow = TRUE; } else { switch (sieve_lexer_curchar(scanner)) { case 'k': case 'K': /* Kilo */ if (value > (SIEVE_MAX_NUMBER >> 10)) overflow = TRUE; else value = value << 10; sieve_lexer_shift(scanner); break; case 'm': case 'M': /* Mega */ if (value > (SIEVE_MAX_NUMBER >> 20)) overflow = TRUE; else value = value << 20; sieve_lexer_shift(scanner); break; case 'g': case 'G': /* Giga */ if (value > (SIEVE_MAX_NUMBER >> 30)) overflow = TRUE; else value = value << 30; sieve_lexer_shift(scanner); break; default: /* Next token */ break; } } /* Check for integer overflow */ if (overflow) { sieve_lexer_error(lexer, "number exceeds integer limits (max %llu)", (long long) SIEVE_MAX_NUMBER); lexer->token_type = STT_ERROR; return FALSE; } lexer->token_type = STT_NUMBER; lexer->token_int_value = (sieve_number_t)value; return TRUE; } static bool sieve_lexer_scan_hash_comment(struct sieve_lexical_scanner *scanner) { struct sieve_lexer *lexer = &scanner->lexer; while (sieve_lexer_curchar(scanner) != '\n') { switch(sieve_lexer_curchar(scanner)) { case -1: if (!scanner->input->eof) { lexer->token_type = STT_ERROR; return FALSE; } sieve_lexer_warning(lexer, "no newline (CRLF) at end of hash comment at end of file"); lexer->token_type = STT_WHITESPACE; return TRUE; case '\0': sieve_lexer_error(lexer, "encountered NUL character in hash comment"); lexer->token_type = STT_ERROR; return FALSE; default: break; } /* Stray CR is ignored */ sieve_lexer_shift(scanner); } sieve_lexer_shift(scanner); lexer->token_type = STT_WHITESPACE; return TRUE; } /* sieve_lexer_scan_raw_token: * Scans valid tokens and whitespace */ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) { struct sieve_lexer *lexer = &scanner->lexer; string_t *str; int ret; /* Read first character */ if (lexer->token_type == STT_NONE) { if ((ret = i_stream_read(scanner->input)) < 0) { i_assert(ret != -2); if (!scanner->input->eof) { lexer->token_type = STT_ERROR; return FALSE; } } sieve_lexer_shift(scanner); } lexer->token_line = scanner->current_line; switch (sieve_lexer_curchar(scanner)) { /* whitespace */ // hash-comment = ( "#" *CHAR-NOT-CRLF CRLF ) case '#': sieve_lexer_shift(scanner); return sieve_lexer_scan_hash_comment(scanner); // bracket-comment = "/*" *(CHAR-NOT-STAR / ("*" CHAR-NOT-SLASH)) "*/" // ;; No */ allowed inside a comment. // ;; (No * is allowed unless it is the last character, // ;; or unless it is followed by a character that isn't a // ;; slash.) case '/': sieve_lexer_shift(scanner); if (sieve_lexer_curchar(scanner) == '*') { sieve_lexer_shift(scanner); while (TRUE) { switch (sieve_lexer_curchar(scanner)) { case -1: if (scanner->input->eof) { sieve_lexer_error(lexer, "end of file before end of bracket comment " "('/* ... */') " "started at line %d", lexer->token_line); } lexer->token_type = STT_ERROR; return FALSE; case '*': sieve_lexer_shift(scanner); if (sieve_lexer_curchar(scanner) == '/') { sieve_lexer_shift(scanner); lexer->token_type = STT_WHITESPACE; return TRUE; } else if (sieve_lexer_curchar(scanner) == -1) { sieve_lexer_error(lexer, "end of file before end of bracket comment " "('/* ... */') " "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; } break; case '\0': sieve_lexer_error(lexer, "encountered NUL character in bracket comment"); lexer->token_type = STT_ERROR; return FALSE; default: sieve_lexer_shift(scanner); } } i_unreached(); } lexer->token_type = STT_SLASH; return TRUE; // comment = bracket-comment / hash-comment // white-space = 1*(SP / CRLF / HTAB) / comment case '\t': case '\r': case '\n': case ' ': sieve_lexer_shift(scanner); while (sieve_lexer_curchar(scanner) == '\t' || sieve_lexer_curchar(scanner) == '\r' || sieve_lexer_curchar(scanner) == '\n' || sieve_lexer_curchar(scanner) == ' ') { sieve_lexer_shift(scanner); } lexer->token_type = STT_WHITESPACE; return TRUE; /* quoted-string */ case '"': sieve_lexer_shift(scanner); str_truncate(lexer->token_str_value, 0); str = lexer->token_str_value; while (sieve_lexer_curchar(scanner) != '"') { if (sieve_lexer_curchar(scanner) == '\\') sieve_lexer_shift(scanner); switch (sieve_lexer_curchar(scanner)) { /* End of file */ case -1: if (scanner->input->eof) { sieve_lexer_error(lexer, "end of file before end of quoted string " "started at line %d", lexer->token_line); } lexer->token_type = STT_ERROR; return FALSE; /* NUL character */ case '\0': sieve_lexer_error(lexer, "encountered NUL character in quoted string " "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; /* CR .. check for LF */ case '\r': sieve_lexer_shift(scanner); if (sieve_lexer_curchar(scanner) != '\n') { sieve_lexer_error(lexer, "found stray carriage-return (CR) character " "in quoted string started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; } if (str_len(str) <= SIEVE_MAX_STRING_LEN) str_append(str, "\r\n"); break; /* Loose LF is allowed (non-standard) and converted to CRLF */ case '\n': if (str_len(str) <= SIEVE_MAX_STRING_LEN) str_append(str, "\r\n"); break; /* Other characters */ default: if (str_len(str) <= SIEVE_MAX_STRING_LEN) str_append_c(str, sieve_lexer_curchar(scanner)); } sieve_lexer_shift(scanner); } sieve_lexer_shift(scanner); if (str_len(str) > SIEVE_MAX_STRING_LEN) { sieve_lexer_error(lexer, "quoted string started at line %d is too long " "(longer than %llu bytes)", lexer->token_line, (long long) SIEVE_MAX_STRING_LEN); lexer->token_type = STT_ERROR; return FALSE; } lexer->token_type = STT_STRING; return TRUE; /* single character tokens */ case ']': sieve_lexer_shift(scanner); lexer->token_type = STT_RSQUARE; return TRUE; case '[': sieve_lexer_shift(scanner); lexer->token_type = STT_LSQUARE; return TRUE; case '}': sieve_lexer_shift(scanner); lexer->token_type = STT_RCURLY; return TRUE; case '{': sieve_lexer_shift(scanner); lexer->token_type = STT_LCURLY; return TRUE; case ')': sieve_lexer_shift(scanner); lexer->token_type = STT_RBRACKET; return TRUE; case '(': sieve_lexer_shift(scanner); lexer->token_type = STT_LBRACKET; return TRUE; case ';': sieve_lexer_shift(scanner); lexer->token_type = STT_SEMICOLON; return TRUE; case ',': sieve_lexer_shift(scanner); lexer->token_type = STT_COMMA; return TRUE; /* EOF */ case -1: if (!scanner->input->eof) { lexer->token_type = STT_ERROR; return FALSE; } lexer->token_type = STT_EOF; return TRUE; default: /* number */ if (i_isdigit(sieve_lexer_curchar(scanner))) { return sieve_lexer_scan_number(scanner); /* identifier / tag */ } else if (i_isalpha(sieve_lexer_curchar(scanner)) || sieve_lexer_curchar(scanner) == '_' || sieve_lexer_curchar(scanner) == ':') { enum sieve_token_type type = STT_IDENTIFIER; str_truncate(lexer->token_str_value,0); str = lexer->token_str_value; /* If it starts with a ':' it is a tag and not an identifier */ if (sieve_lexer_curchar(scanner) == ':') { sieve_lexer_shift(scanner); // discard colon type = STT_TAG; /* First character still can't be a DIGIT */ if (i_isalpha(sieve_lexer_curchar(scanner)) || sieve_lexer_curchar(scanner) == '_') { str_append_c(str, sieve_lexer_curchar(scanner)); sieve_lexer_shift(scanner); } else { /* Hmm, otherwise it is just a spurious colon */ lexer->token_type = STT_COLON; return TRUE; } } else { str_append_c(str, sieve_lexer_curchar(scanner)); sieve_lexer_shift(scanner); } /* Scan the rest of the identifier */ while (i_isalnum(sieve_lexer_curchar(scanner)) || sieve_lexer_curchar(scanner) == '_') { if (str_len(str) <= SIEVE_MAX_IDENTIFIER_LEN) { str_append_c(str, sieve_lexer_curchar(scanner)); } sieve_lexer_shift(scanner); } /* Is this in fact a multiline text string ? */ if (sieve_lexer_curchar(scanner) == ':' && type == STT_IDENTIFIER && str_len(str) == 4 && str_begins_icase_with(str_c(str), "text")) { sieve_lexer_shift(scanner); // discard colon /* Discard SP and HTAB whitespace */ while (sieve_lexer_curchar(scanner) == ' ' || sieve_lexer_curchar(scanner) == '\t') sieve_lexer_shift(scanner); /* Discard hash comment or handle single CRLF */ if (sieve_lexer_curchar(scanner) == '\r') sieve_lexer_shift(scanner); switch (sieve_lexer_curchar(scanner)) { case '#': if (!sieve_lexer_scan_hash_comment(scanner)) return FALSE; if (scanner->input->eof) { sieve_lexer_error(lexer, "end of file before end of multi-line string"); lexer->token_type = STT_ERROR; return FALSE; } else if (scanner->input->stream_errno != 0) { lexer->token_type = STT_ERROR; return FALSE; } break; case '\n': sieve_lexer_shift(scanner); break; case -1: if (scanner->input->eof) { sieve_lexer_error(lexer, "end of file before end of multi-line string"); } lexer->token_type = STT_ERROR; return FALSE; default: sieve_lexer_error(lexer, "invalid character %s after 'text:' in multiline string", _char_sanitize(sieve_lexer_curchar(scanner))); lexer->token_type = STT_ERROR; return FALSE; } /* Start over */ str_truncate(str, 0); /* Parse literal lines */ while (TRUE) { bool cr_shifted = FALSE; /* Remove dot-stuffing or detect end of text */ if (sieve_lexer_curchar(scanner) == '.') { sieve_lexer_shift(scanner); /* Check for CR.. */ if (sieve_lexer_curchar(scanner) == '\r') { sieve_lexer_shift(scanner); cr_shifted = TRUE; } /* ..LF */ if (sieve_lexer_curchar(scanner) == '\n') { sieve_lexer_shift(scanner); /* End of multi-line string */ /* Check whether length limit was violated */ if (str_len(str) > SIEVE_MAX_STRING_LEN) { sieve_lexer_error(lexer, "multi-line string started at line %d is too long " "(longer than %llu bytes)", lexer->token_line, (long long) SIEVE_MAX_STRING_LEN); lexer->token_type = STT_ERROR; return FALSE; } lexer->token_type = STT_STRING; return TRUE; } else if (cr_shifted) { /* Seen CR, but no LF */ if (sieve_lexer_curchar(scanner) != -1 || !scanner->input->eof) { sieve_lexer_error(lexer, "found stray carriage-return (CR) character " "in multi-line string started at line %d", lexer->token_line); } lexer->token_type = STT_ERROR; return FALSE; } /* Handle dot-stuffing */ if (str_len(str) <= SIEVE_MAX_STRING_LEN) str_append_c(str, '.'); if (sieve_lexer_curchar(scanner) == '.') sieve_lexer_shift(scanner); } /* Scan the rest of the line */ while (sieve_lexer_curchar(scanner) != '\n' && sieve_lexer_curchar(scanner) != '\r') { switch (sieve_lexer_curchar(scanner)) { case -1: if (scanner->input->eof) { sieve_lexer_error(lexer, "end of file before end of multi-line string"); } lexer->token_type = STT_ERROR; return FALSE; case '\0': sieve_lexer_error(lexer, "encountered NUL character in quoted string " "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; default: if (str_len(str) <= SIEVE_MAX_STRING_LEN) str_append_c(str, sieve_lexer_curchar(scanner)); } sieve_lexer_shift(scanner); } /* If exited loop due to CR, skip it */ if (sieve_lexer_curchar(scanner) == '\r') sieve_lexer_shift(scanner); /* Now we must see an LF */ if (sieve_lexer_curchar(scanner) != '\n') { if (sieve_lexer_curchar(scanner) != -1 || !scanner->input->eof) { sieve_lexer_error(lexer, "found stray carriage-return (CR) character " "in multi-line string started at line %d", lexer->token_line); } lexer->token_type = STT_ERROR; return FALSE; } if (str_len(str) <= SIEVE_MAX_STRING_LEN) str_append(str, "\r\n"); sieve_lexer_shift(scanner); } i_unreached(); } if (str_len(str) > SIEVE_MAX_IDENTIFIER_LEN) { sieve_lexer_error(lexer, "encountered impossibly long %s%s'", (type == STT_TAG ? "tag identifier ':" : "identifier '"), str_sanitize(str_c(str), SIEVE_MAX_IDENTIFIER_LEN)); lexer->token_type = STT_ERROR; return FALSE; } lexer->token_type = type; return TRUE; } /* Error (unknown character and EOF handled already) */ if (lexer->token_type != STT_GARBAGE) { sieve_lexer_error(lexer, "unexpected character(s) starting with %s", _char_sanitize(sieve_lexer_curchar(scanner))); } sieve_lexer_shift(scanner); lexer->token_type = STT_GARBAGE; return FALSE; } } void sieve_lexer_skip_token(const struct sieve_lexer *lexer) { /* Scan token while skipping whitespace */ do { struct sieve_lexical_scanner *scanner = lexer->scanner; if (!sieve_lexer_scan_raw_token(scanner)) { if (!scanner->input->eof && scanner->input->stream_errno != 0) { sieve_critical(scanner->svinst, scanner->ehandler, sieve_error_script_location(scanner->script, scanner->current_line), "error reading script", "error reading script during lexical analysis: %s", i_stream_get_error(scanner->input)); } return; } } while (lexer->token_type == STT_WHITESPACE); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary-dumper.c0000644000175100001700000001673215100335616025511 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "ostream.h" #include "array.h" #include "buffer.h" #include "time-util.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-dump.h" #include "sieve-script.h" #include "sieve-binary-private.h" /* * Binary dumper object */ struct sieve_binary_dumper { pool_t pool; /* Dumptime environment */ struct sieve_dumptime_env dumpenv; }; struct sieve_binary_dumper * sieve_binary_dumper_create(struct sieve_binary *sbin) { pool_t pool; struct sieve_binary_dumper *dumper; pool = pool_alloconly_create("sieve_binary_dumper", 4096); dumper = p_new(pool, struct sieve_binary_dumper, 1); dumper->pool = pool; dumper->dumpenv.dumper = dumper; dumper->dumpenv.sbin = sbin; sieve_binary_ref(sbin); dumper->dumpenv.svinst = sieve_binary_svinst(sbin); return dumper; } void sieve_binary_dumper_free(struct sieve_binary_dumper **dumper) { sieve_binary_unref(&(*dumper)->dumpenv.sbin); pool_unref(&((*dumper)->pool)); *dumper = NULL; } pool_t sieve_binary_dumper_pool(struct sieve_binary_dumper *dumper) { return dumper->pool; } /* * Formatted output */ void sieve_binary_dumpf(const struct sieve_dumptime_env *denv, const char *fmt, ...) { string_t *outbuf = t_str_new(128); va_list args; va_start(args, fmt); str_vprintfa(outbuf, fmt, args); va_end(args); o_stream_nsend(denv->stream, str_data(outbuf), str_len(outbuf)); } void sieve_binary_dump_sectionf(const struct sieve_dumptime_env *denv, const char *fmt, ...) { string_t *outbuf = t_str_new(128); va_list args; va_start(args, fmt); str_printfa(outbuf, "\n* "); str_vprintfa(outbuf, fmt, args); str_printfa(outbuf, ":\n\n"); va_end(args); o_stream_nsend(denv->stream, str_data(outbuf), str_len(outbuf)); } /* * Dumping the binary */ bool sieve_binary_dumper_run(struct sieve_binary_dumper *dumper, struct ostream *stream, bool verbose) { struct sieve_binary *sbin = dumper->dumpenv.sbin; struct sieve_script *script = sieve_binary_script(sbin); struct sieve_dumptime_env *denv = &(dumper->dumpenv); const struct sieve_binary_header *header = &sbin->header; struct sieve_binary_block *sblock; bool success = TRUE; sieve_size_t offset; int count, i; dumper->dumpenv.stream = stream; /* Dump header */ sieve_binary_dump_sectionf(denv, "Header"); sieve_binary_dumpf(denv, "version = %"PRIu16".%"PRIu16"\n" "flags = 0x%08"PRIx32"\n", header->version_major, header->version_minor, header->flags); if (header->resource_usage.update_time != 0) { time_t update_time = (time_t)header->resource_usage.update_time; sieve_binary_dumpf(denv, "resource usage:\n" " update time = %s\n" " cpu time = %"PRIu32" ms\n", t_strflocaltime("%Y-%m-%d %H:%M:%S", update_time), header->resource_usage.cpu_time_msecs); } /* Dump list of binary blocks */ if (verbose) { count = sieve_binary_block_count(sbin); sieve_binary_dump_sectionf(denv, "Binary blocks (count: %d)", count); for (i = 0; i < count; i++) { struct sieve_binary_block *sblock = sieve_binary_block_get(sbin, i); if (sblock == NULL) return FALSE; sieve_binary_dumpf( denv, "%3d: size: %zu bytes\n", i, sieve_binary_block_get_size(sblock)); } } /* Dump script metadata */ sieve_binary_dump_sectionf(denv, "Script metadata (block: %d)", SBIN_SYSBLOCK_SCRIPT_DATA); sblock = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_SCRIPT_DATA); if (sblock == NULL) return FALSE; T_BEGIN { offset = 0; success = sieve_script_binary_dump_metadata( script, denv, sblock, &offset); } T_END; if (!success) return FALSE; /* Dump list of used extensions */ count = sieve_binary_extensions_count(sbin); if (count > 0) { sieve_binary_dump_sectionf( denv, "Required extensions (block: %d)", SBIN_SYSBLOCK_EXTENSIONS); for (i = 0; i < count; i++) { const struct sieve_extension *ext = sieve_binary_extension_get_by_index(sbin, i); sblock = sieve_binary_extension_get_block(sbin, ext); if (sblock == NULL) { sieve_binary_dumpf( denv, "%3d: %s (id: %d)\n", i, sieve_extension_name(ext), ext->id); } else { sieve_binary_dumpf( denv, "%3d: %s (id: %d; block: %d)\n", i, sieve_extension_name(ext), ext->id, sieve_binary_block_get_id(sblock)); } } } /* Dump extension-specific elements of the binary */ count = sieve_binary_extensions_count(sbin); if (count > 0) { for (i = 0; i < count; i++) { success = TRUE; T_BEGIN { const struct sieve_extension *ext = sieve_binary_extension_get_by_index( sbin, i); if (ext->def != NULL && ext->def->binary_dump != NULL) { success = ext->def->binary_dump( ext, denv); } } T_END; if (!success) return FALSE; } } /* Dump main program */ sieve_binary_dump_sectionf(denv, "Main program (block: %d)", SBIN_SYSBLOCK_MAIN_PROGRAM); dumper->dumpenv.sblock = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM); if (dumper->dumpenv.sblock == NULL) return FALSE; dumper->dumpenv.cdumper = sieve_code_dumper_create(&(dumper->dumpenv)); if (dumper->dumpenv.cdumper != NULL) { sieve_code_dumper_run(dumper->dumpenv.cdumper); sieve_code_dumper_free(&dumper->dumpenv.cdumper); } /* Finish with empty line */ sieve_binary_dumpf(denv, "\n"); return TRUE; } /* * Hexdump production */ bool sieve_binary_dumper_hexdump(struct sieve_binary_dumper *dumper, struct ostream *stream) { struct sieve_binary *sbin = dumper->dumpenv.sbin; struct sieve_dumptime_env *denv = &(dumper->dumpenv); int count, i; dumper->dumpenv.stream = stream; count = sieve_binary_block_count(sbin); /* Block overview */ sieve_binary_dump_sectionf(denv, "Binary blocks (count: %d)", count); for (i = 0; i < count; i++) { struct sieve_binary_block *sblock = sieve_binary_block_get(sbin, i); if (sblock == NULL) return FALSE; sieve_binary_dumpf(denv, "%3d: size: %zu bytes\n", i, sieve_binary_block_get_size(sblock)); } /* Hexdump for each block */ for (i = 0; i < count; i++) { struct sieve_binary_block *sblock = sieve_binary_block_get(sbin, i); buffer_t *blockbuf = sieve_binary_block_get_buffer(sblock); string_t *line; size_t data_size; const unsigned char *data; size_t offset; data = buffer_get_data(blockbuf, &data_size); // FIXME: calculate offset more nicely. sieve_binary_dump_sectionf( denv, "Block %d (%zu bytes, file offset %08llx)", i, data_size, (unsigned long long int)sblock->offset + 8); line = t_str_new(128); offset = 0; while (offset < data_size) { size_t len = (data_size - offset >= 16 ? 16 : data_size - offset); size_t b; str_printfa(line, "%08llx ", (unsigned long long)offset); for (b = 0; b < len; b++) { str_printfa(line, "%02x ", data[offset+b]); if (b == 7) str_append_c(line, ' '); } if (len < 16) { if (len <= 7) str_append_c(line, ' '); for (b = len; b < 16; b++) str_append(line, " "); } str_append(line, " |"); for (b = 0; b < len; b++) { const unsigned char c = data[offset+b]; if (c >= 32 && c <= 126) str_append_c(line, (const char)c); else str_append_c(line, '.'); } str_append(line, "|\n"); o_stream_nsend(stream, str_data(line), str_len(line)); str_truncate(line, 0); offset += len; } str_printfa(line, "%08llx\n", (unsigned long long)offset); o_stream_nsend(stream, str_data(line), str_len(line)); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-plugins.h0000644000175100001700000000036515100335616024414 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_PLUGINS_H #define SIEVE_PLUGINS_H #include "sieve-common.h" int sieve_plugins_load(struct sieve_instance *svinst, const char *path, const char *plugins); void sieve_plugins_unload(struct sieve_instance *svinst); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-extensions.h0000644000175100001700000001233315100335616025130 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXTENSIONS_H #define SIEVE_EXTENSIONS_H #include "lib.h" #include "sieve-common.h" /* * Per-extension object registry */ struct sieve_extension_objects { const void *objects; unsigned int count; }; /* * Extension definition */ struct sieve_extension_def { const char *name; /* Version */ unsigned int version; /* Registration */ int (*load)(const struct sieve_extension *ext, void **context_r); void (*unload)(const struct sieve_extension *ext); /* Compilation */ bool (*validator_load)(const struct sieve_extension *ext, struct sieve_validator *validator); bool (*generator_load)(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); bool (*interpreter_load)(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); bool (*binary_load)(const struct sieve_extension *ext, struct sieve_binary *binary); /* Code dump */ bool (*binary_dump)(const struct sieve_extension *ext, struct sieve_dumptime_env *denv); bool (*code_dump)(const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address); /* Objects */ struct sieve_extension_objects operations; struct sieve_extension_objects operands; }; /* Defining opcodes and operands */ #define SIEVE_EXT_DEFINE_NO_OBJECTS \ { NULL, 0 } #define SIEVE_EXT_DEFINE_OBJECT(OBJ) \ { &OBJ, 1 } #define SIEVE_EXT_DEFINE_OBJECTS(OBJS) \ { OBJS, N_ELEMENTS(OBJS) } #define SIEVE_EXT_GET_OBJECTS_COUNT(ext, field) \ ext->field->count; #define SIEVE_EXT_DEFINE_NO_OPERATIONS \ .operations = SIEVE_EXT_DEFINE_NO_OBJECTS #define SIEVE_EXT_DEFINE_OPERATION(OP) \ .operations = SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_OPERATIONS(OPS) \ .operations = SIEVE_EXT_DEFINE_OBJECTS(OPS) #define SIEVE_EXT_DEFINE_NO_OPERANDS \ .operands = SIEVE_EXT_DEFINE_NO_OBJECTS #define SIEVE_EXT_DEFINE_OPERAND(OP) \ .operands = SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_OPERANDS(OPS) \ .operands = SIEVE_EXT_DEFINE_OBJECTS(OPS) /* * Extension instance */ struct sieve_extension { const struct sieve_extension_def *def; int id; struct sieve_instance *svinst; void *context; bool required:1; bool loaded:1; bool enabled:1; bool dummy:1; bool global:1; bool implicit:1; bool overridden:1; }; #define sieve_extension_is(ext, definition) \ ((ext)->def == &(definition)) #define sieve_extension_name(ext) \ ((ext)->def->name) #define sieve_extension_name_is(ext, _name) \ ( strcmp((ext)->def->name, (_name)) == 0 ) #define sieve_extension_version(ext) \ ((ext)->def->version) #define sieve_extension_version_is(ext, _version) \ ((ext)->def->version == (_version)) /* * Extensions init/deinit */ int sieve_extensions_init(struct sieve_instance *svinst); int sieve_extensions_load(struct sieve_instance *svinst); void sieve_extensions_deinit(struct sieve_instance *svinst); /* * Pre-loaded extensions */ const struct sieve_extension *const * sieve_extensions_get_preloaded(struct sieve_instance *svinst, unsigned int *count_r); /* * Extension registry */ int sieve_extension_register(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, const struct sieve_extension **ext_r); int sieve_extension_require(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, const struct sieve_extension **ext_r); int sieve_extension_reload(const struct sieve_extension *ext); void sieve_extension_unregister(const struct sieve_extension *ext); int sieve_extension_replace(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, bool load, const struct sieve_extension **ext_r); void sieve_extension_override(struct sieve_instance *svinst, const char *name, const struct sieve_extension *ext); unsigned int sieve_extensions_get_count(struct sieve_instance *svinst); const struct sieve_extension *const * sieve_extensions_get_all(struct sieve_instance *svinst, unsigned int *count_r); const struct sieve_extension * sieve_extension_get_by_id(struct sieve_instance *svinst, unsigned int ext_id); const struct sieve_extension * sieve_extension_get_by_name(struct sieve_instance *svinst, const char *name); const char *sieve_extensions_get_string(struct sieve_instance *svinst); int sieve_extensions_set_string(struct sieve_instance *svinst, const char *ext_string, bool global, bool implicit); const struct sieve_extension * sieve_get_match_type_extension(struct sieve_instance *svinst); const struct sieve_extension * sieve_get_comparator_extension(struct sieve_instance *svinst); const struct sieve_extension * sieve_get_address_part_extension(struct sieve_instance *svinst); void sieve_enable_debug_extension(struct sieve_instance *svinst); /* * Capability registries */ struct sieve_extension_capabilities { const char *name; const char *(*get_string)(const struct sieve_extension *ext); }; void sieve_extension_capabilities_register( const struct sieve_extension *ext, const struct sieve_extension_capabilities *cap); void sieve_extension_capabilities_unregister(const struct sieve_extension *ext); const char * sieve_extension_capabilities_get_string(struct sieve_instance *svinst, const char *cap_name); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-address-source.c0000644000175100001700000000543015100335616025647 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-address.h" #include "sieve-message.h" #include "sieve-address-source.h" bool sieve_address_source_parse(pool_t pool, const char *value, struct sieve_address_source *asrc) { struct smtp_address *address; const char *error; size_t val_len; i_zero(asrc); value = t_str_trim(value, "\t "); value = t_str_lcase(value); val_len = strlen(value); if (val_len > 0) { if (strcmp(value, "default") == 0) { asrc->type = SIEVE_ADDRESS_SOURCE_DEFAULT; } else if (strcmp(value, "sender") == 0) { asrc->type = SIEVE_ADDRESS_SOURCE_SENDER; } else if (strcmp(value, "recipient") == 0) { asrc->type = SIEVE_ADDRESS_SOURCE_RECIPIENT; } else if (strcmp(value, "orig_recipient") == 0) { asrc->type = SIEVE_ADDRESS_SOURCE_ORIG_RECIPIENT; } else if (strcmp(value, "user_email") == 0) { asrc->type = SIEVE_ADDRESS_SOURCE_USER_EMAIL; } else if (strcmp(value, "postmaster") == 0) { asrc->type = SIEVE_ADDRESS_SOURCE_POSTMASTER; } else if (smtp_address_parse_path( pool_datastack_create(), value, SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY, &address, &error) >= 0) { asrc->type = SIEVE_ADDRESS_SOURCE_EXPLICIT; asrc->address = smtp_address_clone(pool, address); } else { return FALSE; } } return TRUE; } int sieve_address_source_get_address(struct sieve_address_source *asrc, struct sieve_instance *svinst, const struct sieve_script_env *senv, struct sieve_message_context *msgctx, enum sieve_execute_flags flags, const struct smtp_address **addr_r) { enum sieve_address_source_type type = asrc->type; if (type == SIEVE_ADDRESS_SOURCE_USER_EMAIL && svinst->set->parsed.user_email == NULL) type = SIEVE_ADDRESS_SOURCE_RECIPIENT; if ((flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0) { switch (type) { case SIEVE_ADDRESS_SOURCE_SENDER: case SIEVE_ADDRESS_SOURCE_RECIPIENT: case SIEVE_ADDRESS_SOURCE_ORIG_RECIPIENT: /* We have no envelope */ type = SIEVE_ADDRESS_SOURCE_DEFAULT; break; default: break; } } switch (type) { case SIEVE_ADDRESS_SOURCE_SENDER: *addr_r = sieve_message_get_sender(msgctx); return 1; case SIEVE_ADDRESS_SOURCE_RECIPIENT: *addr_r = sieve_message_get_final_recipient(msgctx); return 1; case SIEVE_ADDRESS_SOURCE_ORIG_RECIPIENT: *addr_r = sieve_message_get_orig_recipient(msgctx); return 1; case SIEVE_ADDRESS_SOURCE_USER_EMAIL: *addr_r = svinst->set->parsed.user_email; return 1; case SIEVE_ADDRESS_SOURCE_POSTMASTER: *addr_r = sieve_get_postmaster_smtp(senv); return 1; case SIEVE_ADDRESS_SOURCE_EXPLICIT: *addr_r = asrc->address; return 1; case SIEVE_ADDRESS_SOURCE_DEFAULT: break; } return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/mcht-matches.c0000644000175100001700000002745715100335616024205 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Match-type ':matches' */ #include "lib.h" #include "str.h" #include "sieve-match-types.h" #include "sieve-comparators.h" #include "sieve-match.h" #include #include /* * Forward declarations */ static int mcht_matches_match_key(struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size); /* * Match-type object */ const struct sieve_match_type_def matches_match_type = { SIEVE_OBJECT("matches", &match_type_operand, SIEVE_MATCH_TYPE_MATCHES), .validate_context = sieve_match_substring_validate_context, .match_key = mcht_matches_match_key }; /* * Match-type implementation */ /* Quick 'n dirty debug */ //#define MATCH_DEBUG #ifdef MATCH_DEBUG #define debug_printf(...) printf ("match debug: " __VA_ARGS__) #else #define debug_printf(...) #endif /* FIXME: Naive implementation, substitute this with dovecot src/lib/str-find.c */ static inline bool _string_find(const struct sieve_comparator *cmp, const char **valp, const char *vend, const char **keyp, const char *kend) { while ((*valp < vend) && (*keyp < kend)) { if (!cmp->def->char_match(cmp, valp, vend, keyp, kend)) (*valp)++; } return (*keyp == kend); } static char _scan_key_section(string_t *section, const char **wcardp, const char *key_end) { /* Find next wildcard and resolve escape sequences */ str_truncate(section, 0); while (*wcardp < key_end && **wcardp != '*' && **wcardp != '?') { if (**wcardp == '\\') (*wcardp)++; str_append_c(section, **wcardp); (*wcardp)++; } /* Record wildcard character or \0 */ if (*wcardp < key_end) { return **wcardp; } i_assert(*wcardp == key_end); return '\0'; } static int mcht_matches_match_key(struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size) { const struct sieve_comparator *cmp = mctx->comparator; struct sieve_match_values *mvalues; string_t *mvalue = NULL, *mchars = NULL; string_t *section, *subsection; const char *vend, *kend, *vp, *kp, *wp, *pvp; bool backtrack = FALSE; /* TRUE: match of '?'-connected sections failed */ char wcard = '\0'; /* Current wildcard */ char next_wcard = '\0'; /* Next widlcard */ unsigned int key_offset = 0; if (cmp->def == NULL || cmp->def->char_match == NULL) return 0; /* Key sections */ section = t_str_new(32); /* Section (after beginning or *) */ subsection = t_str_new(32); /* Sub-section (after ?) */ /* Mark end of value and key */ vend = (const char *) val + val_size; kend = (const char *) key + key_size; /* Initialize pointers */ vp = val; /* Value pointer */ kp = key; /* Key pointer */ wp = key; /* Wildcard (key) pointer */ /* Start match values list if requested */ if ((mvalues = sieve_match_values_start(mctx->runenv)) != NULL) { /* Skip ${0} for now; added when match succeeds */ sieve_match_values_add(mvalues, NULL); mvalue = t_str_new(32); /* Match value (*) */ mchars = t_str_new(32); /* Match characters (.?..?.??) */ } /* Match the pattern: =
*
*
...
= ??... Escape sequences \? and \* need special attention. */ debug_printf("=== Start ===\n"); debug_printf(" key: %s\n", t_strdup_until(key, kend)); debug_printf(" value: %s\n", t_strdup_until(val, vend)); /* Loop until either key or value ends */ while (kp < kend && vp < vend) { const char *needle, *nend; if (!backtrack) { /* Search the next '*' wildcard in the key string */ wcard = next_wcard; /* Find the needle to look for in the string */ key_offset = 0; for (;;) { next_wcard = _scan_key_section(section, &wp, kend); if (wcard == '\0' || str_len(section) > 0) break; if (next_wcard == '*') break; if (wp < kend) wp++; else break; key_offset++; } debug_printf("found wildcard '%c' at pos [%d]\n", next_wcard, (int) (wp-key)); if (mvalues != NULL) str_truncate(mvalue, 0); } else { /* Backtracked; '*' wildcard is retained */ debug_printf("backtracked"); backtrack = FALSE; } /* Determine what we are looking for */ needle = str_c(section); nend = PTR_OFFSET(needle, str_len(section)); debug_printf(" section needle: '%s'\n", t_strdup_until(needle, nend)); debug_printf(" section key: '%s'\n", t_strdup_until(kp, kend)); debug_printf(" section remnant: '%s'\n", t_strdup_until(wp, kend)); debug_printf(" value remnant: '%s'\n", t_strdup_until(vp, vend)); debug_printf(" key offset: %d\n", key_offset); pvp = vp; if (next_wcard == '\0') { if (wcard == '\0') { /* No current wildcard; match needs to happen right at the beginning */ debug_printf("next_wcard = NULL && wcard = NUL; " "needle should be equal to value.\n"); if ((vend - vp) != (nend - needle) || !cmp->def->char_match(cmp, &vp, vend, &needle, nend)) { debug_printf(" key not equal to value\n"); break; } } else { const char *qp, *qend; size_t slen; /* No more wildcards; find the needle substring at the end of string */ debug_printf("next_wcard = NUL; " "must find needle at end\n"); /* Check if the value is still large enough */ slen = str_len(section); if ((vp + slen) > vend) { debug_printf(" wont match: " "value is too short\n"); break; } /* Move value pointer to where the needle should be */ vp = vend - slen; /* Record match values */ qend = vp; qp = vp - key_offset; /* Compare needle to end of value string */ if (!cmp->def->char_match(cmp, &vp, vend, &needle, nend)) { debug_printf(" match at end failed\n"); break; } /* Add match values */ if (mvalues != NULL) { i_assert(qp >= pvp); str_append_data(mvalue, pvp, qp-pvp); /* Append '*' match value */ sieve_match_values_add(mvalues, mvalue); /* Append any initial '?' match values */ for (; qp < qend; qp++) { sieve_match_values_add_char( mvalues, *qp); } } } /* Finish match */ kp = kend; vp = vend; debug_printf(" matched end of value\n"); break; } else { /* Next wildcard found; match needle before next wildcard */ /* Stored value pointer for backtrack */ const char *prv = NULL; /* Stored key pointer for backtrack */ const char *prk = NULL; /* Stored wildcard pointer for backtrack */ const char *prw = NULL; const char *chars; /* Reset '?' match values */ if (mvalues != NULL) str_truncate(mchars, 0); if (wcard == '\0') { /* No current wildcard; match needs to happen right at the beginning */ debug_printf("wcard = NUL; " "needle should be found at the beginning.\n"); debug_printf(" begin needle: '%s'\n", t_strdup_until(needle, nend)); debug_printf(" begin value: '%s'\n", t_strdup_until(vp, vend)); if (!cmp->def->char_match(cmp, &vp, vend, &needle, nend)) { debug_printf(" failed to find needle at beginning\n"); break; } } else { /* Current wildcard present; match needle between current and next wildcard */ debug_printf("wcard != NUL; " "must find needle at an offset (>= %d).\n", key_offset); /* Match may happen at any offset (>= key offset): find substring */ vp += key_offset; if ((vp >= vend) || !_string_find(cmp, &vp, vend, &needle, nend)) { debug_printf(" failed to find needle at an offset\n"); break; } prv = vp - str_len(section); prk = kp; prw = wp; /* Append match values */ if (mvalues != NULL) { const char *qend = vp - str_len(section); const char *qp = qend - key_offset; /* Append '*' match value */ str_append_data(mvalue, pvp, qp-pvp); /* Append any initial '?' match values (those that caused the key offset). */ for (; qp < qend; qp++) str_append_c(mchars, *qp); } } /* Update wildcard and key pointers for next wildcard scan */ if (wp < kend) wp++; kp = wp; /* Scan successive '?' wildcards */ while (next_wcard == '?') { debug_printf("next_wcard = '?'; " "need to match arbitrary character\n"); /* Add match value */ if (mvalues != NULL) str_append_c(mchars, *vp); vp++; /* Scan for next '?' wildcard */ next_wcard = _scan_key_section(subsection, &wp, kend); debug_printf("found next wildcard '%c' at pos [%d] " "(fixed match)\n", next_wcard, (int) (wp-key)); /* Determine what we are looking for */ needle = str_c(subsection); nend = needle + str_len(subsection); debug_printf(" sub key: '%s'\n", t_strdup_until(needle, nend)); debug_printf(" value remnant: '%s'\n", vp <= vend ? t_strdup_until(vp, vend) : ""); /* Try matching the needle at fixed position */ if ((needle == nend && next_wcard == '\0' && vp < vend) || !cmp->def->char_match(cmp, &vp, vend, &needle, nend)) { /* Match failed: now we have a problem. We need to backtrack to the previous '*' wildcard occurrence and start scanning for the next possible match. */ debug_printf(" failed fixed match\n"); /* Start backtrack */ if (prv != NULL && prv + 1 < vend) { /* Restore pointers */ vp = prv; kp = prk; wp = prw; /* Skip forward one value character to scan the next possible match */ if (mvalues != NULL) str_append_c(mvalue, *vp); vp++; /* Set wildcard state appropriately */ wcard = '*'; next_wcard = '?'; /* Backtrack */ backtrack = TRUE; debug_printf(" BACKTRACK\n"); } /* Break '?' wildcard scanning loop */ break; } /* Update wildcard and key pointers for next wildcard scan */ if (wp < kend) wp++; kp = wp; } if (!backtrack) { unsigned int i; if (next_wcard == '?') { debug_printf("failed to match '?'\n"); break; } if (mvalues != NULL) { if (prv != NULL) sieve_match_values_add(mvalues, mvalue); chars = (const char *) str_data(mchars); for (i = 0; i < str_len(mchars); i++) sieve_match_values_add_char(mvalues, chars[i]); } if (next_wcard != '*') { debug_printf("failed to match at end of string\n"); break; } } } /* Check whether string ends in a wildcard (avoid scanning the rest of the string) */ if (kp == kend && next_wcard == '*') { /* Add the rest of the string as match value */ if (mvalues != NULL) { str_truncate(mvalue, 0); str_append_data(mvalue, vp, vend-vp); sieve_match_values_add(mvalues, mvalue); } /* Finish match */ kp = kend; vp = vend; debug_printf("key ends with '*'\n"); break; } debug_printf("== Loop ==\n"); } /* Eat away a trailing series of *s */ if (vp == vend) { while (kp < kend && *kp == '*') kp++; } /* By definition, the match is only successful if both value and key pattern are exhausted. */ debug_printf("=== Finish ===\n"); debug_printf(" result: %s\n", (kp == kend && vp == vend) ? "true" : "false"); if (kp == kend && vp == vend) { /* Activate new match values after successful match */ if (mvalues != NULL) { /* Set ${0} */ string_t *matched = str_new_const( pool_datastack_create(), val, val_size); sieve_match_values_set(mvalues, 0, matched); /* Commit new match values */ sieve_match_values_commit(mctx->runenv, &mvalues); } return 1; } /* No match; drop collected match values */ sieve_match_values_abort(&mvalues); return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-interpreter.c0000644000175100001700000007464415100335616025304 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "ostream.h" #include "mempool.h" #include "array.h" #include "hash.h" #include "cpu-limit.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-script.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-message.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-actions.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-result.h" #include "sieve-comparators.h" #include "sieve-runtime-trace.h" #include "sieve-interpreter.h" #include static struct event_category event_category_sieve_runtime = { .parent = &event_category_sieve, .name = "sieve-runtime", }; /* * Interpreter extension */ struct sieve_interpreter_extension_reg { const struct sieve_interpreter_extension *intext; const struct sieve_extension *ext; void *context; bool deferred:1; bool started:1; }; /* * Code loop */ struct sieve_interpreter_loop { unsigned int level; sieve_size_t begin, end; const struct sieve_extension_def *ext_def; pool_t pool; void *context; }; /* * Interpreter */ struct sieve_interpreter { pool_t pool; struct sieve_interpreter *parent; /* Runtime data for extensions */ ARRAY(struct sieve_interpreter_extension_reg) extensions; sieve_size_t reset_vector; /* Execution status */ sieve_size_t pc; /* Program counter */ /* Loop stack */ ARRAY(struct sieve_interpreter_loop) loop_stack; sieve_size_t loop_limit; unsigned int parent_loop_level; /* Runtime environment */ struct sieve_runtime_env runenv; struct sieve_runtime_trace trace; struct sieve_resource_usage rusage; /* Current operation */ struct sieve_operation oprtn; /* Location information */ struct sieve_binary_debug_reader *dreader; unsigned int command_line; bool running:1; /* Interpreter is running (may be interrupted) */ bool interrupted:1; /* Interpreter interrupt requested */ bool test_result:1; /* Result of previous test command */ }; static struct sieve_interpreter * _sieve_interpreter_create(struct sieve_binary *sbin, struct sieve_binary_block *sblock, struct sieve_script *script, struct sieve_interpreter *parent, const struct sieve_execute_env *eenv, struct sieve_error_handler *ehandler) ATTR_NULL(3, 4) { const struct sieve_script_env *senv = eenv->scriptenv; unsigned int i, ext_count; struct sieve_interpreter *interp; pool_t pool; struct sieve_instance *svinst; const struct sieve_extension *const *ext_preloaded; unsigned int debug_block_id; sieve_size_t *address; bool success = TRUE; pool = pool_alloconly_create("sieve_interpreter", 4096); interp = p_new(pool, struct sieve_interpreter, 1); interp->parent = parent; interp->pool = pool; interp->runenv.ehandler = ehandler; sieve_error_handler_ref(ehandler); interp->runenv.exec_env = eenv; interp->runenv.interp = interp; interp->runenv.oprtn = &interp->oprtn; interp->runenv.sbin = sbin; interp->runenv.sblock = sblock; sieve_binary_ref(sbin); interp->runenv.event = event_create(eenv->event); event_add_category(interp->runenv.event, &event_category_sieve_runtime); event_add_str(interp->runenv.event, "script_name", sieve_binary_script_name(sbin)); event_add_str(interp->runenv.event, "script_location", sieve_binary_script_location(sbin)); event_add_str(interp->runenv.event, "binary_path", sieve_binary_path(sbin)); svinst = sieve_binary_svinst(sbin); if (senv->trace_log != NULL) { interp->trace.log = senv->trace_log; interp->trace.config = senv->trace_config; interp->trace.indent = 0; interp->runenv.trace = &interp->trace; } if (script == NULL) interp->runenv.script = sieve_binary_script(sbin); else interp->runenv.script = script; interp->runenv.pc = 0; address = &(interp->runenv.pc); sieve_runtime_trace_begin(&(interp->runenv)); p_array_init(&interp->extensions, pool, sieve_extensions_get_count(svinst)); interp->parent_loop_level = 0; if (parent != NULL && array_is_created(&parent->loop_stack)) { interp->parent_loop_level = parent->parent_loop_level + array_count(&parent->loop_stack); } /* Pre-load core language features implemented as 'extensions' */ ext_preloaded = sieve_extensions_get_preloaded(svinst, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_extension_def *ext_def = ext_preloaded[i]->def; if (ext_def != NULL && ext_def->interpreter_load != NULL) { (void)ext_def->interpreter_load(ext_preloaded[i], &interp->runenv, address); } } /* Load debug block */ if (sieve_binary_read_unsigned(sblock, address, &debug_block_id)) { struct sieve_binary_block *debug_block = sieve_binary_block_get(sbin, debug_block_id); if (debug_block == NULL) { sieve_runtime_trace_error(&interp->runenv, "invalid id for debug block"); success = FALSE; } else { /* Initialize debug reader */ interp->dreader = sieve_binary_debug_reader_init(debug_block); } } /* Load other extensions listed in code */ if (success && sieve_binary_read_unsigned(sblock, address, &ext_count)) { for (i = 0; i < ext_count; i++) { unsigned int code = 0, deferred; struct sieve_interpreter_extension_reg *reg; const struct sieve_extension *ext; if (!sieve_binary_read_extension(sblock, address, &code, &ext) || !sieve_binary_read_byte(sblock, address, &deferred)) { success = FALSE; break; } if (deferred > 0 && ext->id >= 0) { reg = array_idx_get_space( &interp->extensions, (unsigned int)ext->id); reg->deferred = TRUE; } if (ext->def != NULL) { if (ext->global && (eenv->flags & SIEVE_EXECUTE_FLAG_NOGLOBAL) != 0) { sieve_runtime_error(&interp->runenv, NULL, "failed to enable extension '%s': " "its use is restricted to global scripts", sieve_extension_name(ext)); success = FALSE; break; } if (ext->def->interpreter_load != NULL && !ext->def->interpreter_load(ext, &interp->runenv, address)) { success = FALSE; break; } } } } else { success = FALSE; } if (!success) { sieve_interpreter_free(&interp); interp = NULL; } else { interp->reset_vector = *address; } return interp; } struct sieve_interpreter * sieve_interpreter_create(struct sieve_binary *sbin, struct sieve_interpreter *parent, const struct sieve_execute_env *eenv, struct sieve_error_handler *ehandler) { struct sieve_binary_block *sblock; if ((sblock = sieve_binary_block_get( sbin, SBIN_SYSBLOCK_MAIN_PROGRAM)) == NULL) return NULL; return _sieve_interpreter_create(sbin, sblock, NULL, parent, eenv, ehandler); } struct sieve_interpreter * sieve_interpreter_create_for_block(struct sieve_binary_block *sblock, struct sieve_script *script, struct sieve_interpreter *parent, const struct sieve_execute_env *eenv, struct sieve_error_handler *ehandler) { if (sblock == NULL) return NULL; return _sieve_interpreter_create(sieve_binary_block_get_binary(sblock), sblock, script, parent, eenv, ehandler); } void sieve_interpreter_free(struct sieve_interpreter **_interp) { struct sieve_interpreter *interp = *_interp; struct sieve_runtime_env *renv = &interp->runenv; const struct sieve_interpreter_extension_reg *eregs; struct sieve_interpreter_loop *loops; unsigned int count, i; if (interp->running) { struct event_passthrough *e = event_create_passthrough(interp->runenv.event)-> set_name("sieve_runtime_script_finished")-> add_str("error", "Aborted"); e_debug(e->event(), "Aborted running script '%s'", sieve_binary_source(interp->runenv.sbin)); interp->running = FALSE; } if (array_is_created(&interp->loop_stack)) { loops = array_get_modifiable(&interp->loop_stack, &count); for (i = 0; i < count; i++) pool_unref(&loops[i].pool); } interp->trace.indent = 0; sieve_runtime_trace_end(renv); /* Signal registered extensions that the interpreter is being destroyed */ eregs = array_get(&interp->extensions, &count); for (i = 0; i < count; i++) { if (eregs[i].intext != NULL && eregs[i].intext->free != NULL) { eregs[i].intext->free(eregs[i].ext, interp, eregs[i].context); } } sieve_binary_debug_reader_deinit(&interp->dreader); sieve_binary_unref(&renv->sbin); sieve_result_unref(&interp->runenv.result); sieve_error_handler_unref(&renv->ehandler); event_unref(&renv->event); pool_unref(&interp->pool); *_interp = NULL; } /* * Accessors */ pool_t sieve_interpreter_pool(struct sieve_interpreter *interp) { return interp->pool; } struct sieve_interpreter * sieve_interpreter_get_parent(struct sieve_interpreter *interp) { return interp->parent; } struct sieve_script *sieve_interpreter_script(struct sieve_interpreter *interp) { return interp->runenv.script; } struct sieve_error_handler * sieve_interpreter_get_error_handler(struct sieve_interpreter *interp) { return interp->runenv.ehandler; } struct sieve_instance * sieve_interpreter_svinst(struct sieve_interpreter *interp) { return interp->runenv.exec_env->svinst; } /* Do not use this function for normal sieve extensions. This is intended for * the testsuite only. */ void sieve_interpreter_set_result(struct sieve_interpreter *interp, struct sieve_result *result) { sieve_result_unref(&interp->runenv.result); interp->runenv.result = result; interp->runenv.msgctx = sieve_result_get_message_context(result); sieve_result_ref(result); } /* * Source location */ unsigned int sieve_runtime_get_source_location(const struct sieve_runtime_env *renv, sieve_size_t code_address) { struct sieve_interpreter *interp = renv->interp; if (interp->dreader == NULL) return 0; if (interp->command_line == 0) { interp->command_line = sieve_binary_debug_read_line(interp->dreader, renv->oprtn->address); } return sieve_binary_debug_read_line(interp->dreader, code_address); } unsigned int sieve_runtime_get_command_location(const struct sieve_runtime_env *renv) { struct sieve_interpreter *interp = renv->interp; if (interp->dreader == NULL) return 0; if (interp->command_line == 0) { interp->command_line = sieve_binary_debug_read_line(interp->dreader, renv->oprtn->address); } return interp->command_line; } const char * sieve_runtime_get_full_command_location(const struct sieve_runtime_env *renv) { return sieve_error_script_location( renv->script, sieve_runtime_get_command_location(renv)); } /* * Extension support */ void sieve_interpreter_extension_register( struct sieve_interpreter *interp, const struct sieve_extension *ext, const struct sieve_interpreter_extension *intext, void *context) { struct sieve_interpreter_extension_reg *reg; if (ext->id < 0) return; reg = array_idx_get_space(&interp->extensions, (unsigned int) ext->id); reg->intext = intext; reg->ext = ext; reg->context = context; } void sieve_interpreter_extension_set_context(struct sieve_interpreter *interp, const struct sieve_extension *ext, void *context) { struct sieve_interpreter_extension_reg *reg; if (ext->id < 0) return; reg = array_idx_get_space(&interp->extensions, (unsigned int) ext->id); reg->context = context; } void *sieve_interpreter_extension_get_context(struct sieve_interpreter *interp, const struct sieve_extension *ext) { const struct sieve_interpreter_extension_reg *reg; if (ext->id < 0 || ext->id >= (int) array_count(&interp->extensions)) return NULL; reg = array_idx(&interp->extensions, (unsigned int) ext->id); return reg->context; } int sieve_interpreter_extension_start(struct sieve_interpreter *interp, const struct sieve_extension *ext) { struct sieve_interpreter_extension_reg *reg; int ret; i_assert(ext->id >= 0); if (ext->id >= (int) array_count(&interp->extensions)) return SIEVE_EXEC_OK; reg = array_idx_modifiable(&interp->extensions, (unsigned int)ext->id); if (!reg->deferred) return SIEVE_EXEC_OK; reg->deferred = FALSE; reg->started = TRUE; if (reg->intext != NULL && reg->intext->run != NULL && (ret = reg->intext->run(ext, &interp->runenv, reg->context, TRUE)) <= 0) return ret; return SIEVE_EXEC_OK; } /* * Loop handling */ int sieve_interpreter_loop_start(struct sieve_interpreter *interp, sieve_size_t loop_end, const struct sieve_extension_def *ext_def, struct sieve_interpreter_loop **loop_r) { const struct sieve_runtime_env *renv = &interp->runenv; struct sieve_interpreter_loop *loop; i_assert(loop_end > interp->runenv.pc); /* Check supplied end offset */ if (loop_end > sieve_binary_block_get_size(renv->sblock)) { sieve_runtime_trace_error(renv, "loop end offset out of range"); return SIEVE_EXEC_BIN_CORRUPT; } /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { unsigned int line = sieve_runtime_get_source_location(renv, loop_end); if (sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES)) { sieve_runtime_trace(renv, 0, "loop ends at line %d [%08llx]", line, (long long unsigned int) loop_end); } else { sieve_runtime_trace(renv, 0, "loop ends at line %d", line); } } /* Check loop nesting limit */ if (!array_is_created(&interp->loop_stack)) p_array_init(&interp->loop_stack, interp->pool, 8); if ((interp->parent_loop_level + array_count(&interp->loop_stack)) >= SIEVE_MAX_LOOP_DEPTH) { /* Should normally be caught at compile time */ sieve_runtime_error(renv, NULL, "new program loop exceeds " "the nesting limit (<= %u levels)", SIEVE_MAX_LOOP_DEPTH); return SIEVE_EXEC_FAILURE; } /* Create new loop */ loop = array_append_space(&interp->loop_stack); loop->level = array_count(&interp->loop_stack)-1; loop->ext_def = ext_def; loop->begin = interp->runenv.pc; loop->end = loop_end; loop->pool = pool_alloconly_create("sieve_interpreter", 128); /* Set new loop limit */ interp->loop_limit = loop_end; *loop_r = loop; return SIEVE_EXEC_OK; } struct sieve_interpreter_loop * sieve_interpreter_loop_get(struct sieve_interpreter *interp, sieve_size_t loop_end, const struct sieve_extension_def *ext_def) { struct sieve_interpreter_loop *loops; unsigned int count, i; if (!array_is_created(&interp->loop_stack)) return NULL; loops = array_get_modifiable(&interp->loop_stack, &count); for (i = count; i > 0; i--) { /* We're really making sure our loop matches */ if (loops[i-1].end == loop_end && loops[i-1].ext_def == ext_def) return &loops[i-1]; } return NULL; } int sieve_interpreter_loop_next(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop, sieve_size_t loop_begin) { const struct sieve_runtime_env *renv = &interp->runenv; struct sieve_interpreter_loop *loops; unsigned int count; /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { unsigned int line = sieve_runtime_get_source_location(renv, loop_begin); if (sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES)) { sieve_runtime_trace(renv, 0, "looping back to line %d [%08llx]", line, (long long unsigned int) loop_begin); } else { sieve_runtime_trace(renv, 0, "looping back to line %d", line); } } /* Check the code for corruption */ if (loop->begin != loop_begin) { sieve_runtime_trace_error(renv, "loop begin offset invalid"); return SIEVE_EXEC_BIN_CORRUPT; } /* Check invariants */ i_assert(array_is_created(&interp->loop_stack)); loops = array_get_modifiable(&interp->loop_stack, &count); i_assert(&loops[count-1] == loop); /* Return to beginning */ interp->runenv.pc = loop_begin; return SIEVE_EXEC_OK; } int sieve_interpreter_loop_break(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop) { const struct sieve_runtime_env *renv = &interp->runenv; struct sieve_interpreter_loop *loops; sieve_size_t loop_end = loop->end; unsigned int count, i; /* Find the loop */ i_assert(array_is_created(&interp->loop_stack)); loops = array_get_modifiable(&interp->loop_stack, &count); i_assert(count > 0); i = count; do { pool_unref(&loops[i-1].pool); i--; } while (i > 0 && &loops[i] != loop); i_assert(&loops[i] == loop); /* Set new loop limit */ if (i > 0) interp->loop_limit = loops[i].end; else interp->loop_limit = 0; /* Delete it and all deeper loops */ array_delete(&interp->loop_stack, i, count - i); /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { unsigned int jmp_line = sieve_runtime_get_source_location(renv, loop_end); if (sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES)) { sieve_runtime_trace(renv, 0, "exiting loops at line %d [%08llx]", jmp_line, (long long unsigned int) loop_end); } else { sieve_runtime_trace(renv, 0, "exiting loops at line %d", jmp_line); } } /* Exit loop */ interp->runenv.pc = loop->end; return SIEVE_EXEC_OK; } static int sieve_interpreter_loop_break_out(struct sieve_interpreter *interp, sieve_size_t target) { struct sieve_interpreter_loop *loops; unsigned int count, i; if (!array_is_created(&interp->loop_stack)) return SIEVE_EXEC_OK; loops = array_get_modifiable(&interp->loop_stack, &count); for (i = count; i > 0; i--) { /* We're really making sure our loop matches */ if (loops[i-1].end > target) break; } if (i == count) return SIEVE_EXEC_OK; return sieve_interpreter_loop_break(interp, &loops[i]); } struct sieve_interpreter_loop * sieve_interpreter_loop_get_local(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop, const struct sieve_extension_def *ext_def) { struct sieve_interpreter_loop *loops; unsigned int count, i; if (!array_is_created(&interp->loop_stack)) return NULL; loops = array_get_modifiable(&interp->loop_stack, &count); i_assert(loop == NULL || loop->level < count); for (i = (loop == NULL ? count : loop->level); i > 0; i--) { if (ext_def == NULL || loops[i-1].ext_def == ext_def) return &loops[i-1]; } return NULL; } struct sieve_interpreter_loop * sieve_interpreter_loop_get_global(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop, const struct sieve_extension_def *ext_def) { struct sieve_interpreter_loop *result; while (interp != NULL) { result = sieve_interpreter_loop_get_local(interp, loop, ext_def); if (result != NULL) return result; interp = interp->parent; } return NULL; } pool_t sieve_interpreter_loop_get_pool(struct sieve_interpreter_loop *loop) { return loop->pool; } void *sieve_interpreter_loop_get_context(struct sieve_interpreter_loop *loop) { return loop->context; } void sieve_interpreter_loop_set_context(struct sieve_interpreter_loop *loop, void *context) { loop->context = context; } /* * Program flow */ void sieve_interpreter_reset(struct sieve_interpreter *interp) { interp->runenv.pc = interp->reset_vector; interp->interrupted = FALSE; interp->test_result = FALSE; sieve_result_unref(&interp->runenv.result); } void sieve_interpreter_interrupt(struct sieve_interpreter *interp) { interp->interrupted = TRUE; } sieve_size_t sieve_interpreter_program_counter(struct sieve_interpreter *interp) { return interp->runenv.pc; } static int sieve_interpreter_check_program_jump(struct sieve_interpreter *interp, sieve_size_t jmp_target, bool break_loops) { const struct sieve_runtime_env *renv = &interp->runenv; sieve_size_t loop_limit = (break_loops ? 0 : interp->loop_limit); if (jmp_target == 0 || jmp_target > sieve_binary_block_get_size(renv->sblock) || (loop_limit > 0 && jmp_target >= loop_limit)) { if (interp->loop_limit != 0) { sieve_runtime_trace_error( renv, "jump target crosses loop boundary"); } else { sieve_runtime_trace_error( renv, "jump target out of range"); } return SIEVE_EXEC_BIN_CORRUPT; } return SIEVE_EXEC_OK; } static int sieve_interpreter_do_program_jump(struct sieve_interpreter *interp, sieve_size_t jmp_target, bool break_loops) { const struct sieve_runtime_env *renv = &interp->runenv; sieve_size_t *address = &(interp->runenv.pc); int ret; if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { unsigned int jmp_line = sieve_runtime_get_source_location(renv, jmp_target); if (sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES)) { sieve_runtime_trace(renv, 0, "jumping to line %d [%08llx]", jmp_line, (long long unsigned int)jmp_target); } else { sieve_runtime_trace(renv, 0, "jumping to line %d", jmp_line); } } if (break_loops && (ret = sieve_interpreter_loop_break_out(interp, jmp_target)) <= 0) return ret; *address = jmp_target; return SIEVE_EXEC_OK; } int sieve_interpreter_program_jump_to(struct sieve_interpreter *interp, sieve_size_t jmp_target, bool break_loops) { int ret; ret = sieve_interpreter_check_program_jump(interp, jmp_target, break_loops); if (ret <= 0) return ret; return sieve_interpreter_do_program_jump( interp, jmp_target, break_loops); } int sieve_interpreter_program_jump(struct sieve_interpreter *interp, bool jump, bool break_loops) { const struct sieve_runtime_env *renv = &interp->runenv; sieve_size_t *address = &(interp->runenv.pc); sieve_size_t jmp_start = *address, jmp_target; sieve_offset_t jmp_offset; int ret; if (!sieve_binary_read_offset(renv->sblock, address, &jmp_offset)) { sieve_runtime_trace_error(renv, "invalid jump offset"); return SIEVE_EXEC_BIN_CORRUPT; } jmp_target = jmp_start + jmp_offset; ret = sieve_interpreter_check_program_jump(interp, jmp_target, break_loops); if (ret <= 0) return ret; if (!jump) { sieve_runtime_trace(renv, 0, "not jumping"); return SIEVE_EXEC_OK; } return sieve_interpreter_do_program_jump( interp, jmp_target, break_loops); } /* * Test results */ void sieve_interpreter_set_test_result(struct sieve_interpreter *interp, bool result) { interp->test_result = result; } bool sieve_interpreter_get_test_result(struct sieve_interpreter *interp) { return interp->test_result; } /* * Code execute */ static int sieve_interpreter_operation_execute(struct sieve_interpreter *interp) { struct sieve_operation *oprtn = &(interp->oprtn); sieve_size_t *address = &(interp->runenv.pc); sieve_runtime_trace_toplevel(&interp->runenv); /* Read the operation */ if (sieve_operation_read(interp->runenv.sblock, address, oprtn)) { const struct sieve_operation_def *op = oprtn->def; int result = SIEVE_EXEC_OK; /* Reset cached command location */ interp->command_line = 0; /* Execute the operation */ if (op->execute != NULL) { /* Noop ? */ T_BEGIN { result = op->execute(&(interp->runenv), address); } T_END; } else { sieve_runtime_trace(&interp->runenv, SIEVE_TRLVL_COMMANDS, "OP: %s (NOOP)", sieve_operation_mnemonic(oprtn)); } return result; } /* Binary corrupt */ sieve_runtime_trace_error(&interp->runenv, "Encountered invalid operation"); return SIEVE_EXEC_BIN_CORRUPT; } int sieve_interpreter_continue(struct sieve_interpreter *interp, bool *interrupted) { const struct sieve_runtime_env *renv = &interp->runenv; const struct sieve_execute_env *eenv = renv->exec_env; struct cpu_limit *climit = NULL; sieve_size_t *address = &(interp->runenv.pc); struct sieve_instance *svinst = eenv->svinst; struct sieve_exec_status *exec_status = eenv->exec_status; struct sieve_resource_usage rusage; int ret = SIEVE_EXEC_OK; interp->interrupted = FALSE; if (interrupted != NULL) *interrupted = FALSE; if (svinst->set->max_cpu_time > 0) { climit = cpu_limit_init(svinst->set->max_cpu_time, CPU_LIMIT_TYPE_USER); } while (ret == SIEVE_EXEC_OK && !interp->interrupted && *address < sieve_binary_block_get_size(renv->sblock)) { if (climit != NULL && cpu_limit_exceeded(climit)) { sieve_runtime_error( renv, NULL, "execution exceeded CPU time limit"); ret = SIEVE_EXEC_RESOURCE_LIMIT; break; } if (interp->loop_limit != 0 && *address > interp->loop_limit) { sieve_runtime_trace_error( renv, "program crossed loop boundary"); ret = SIEVE_EXEC_BIN_CORRUPT; break; } ret = sieve_interpreter_operation_execute(interp); } if (climit != NULL) { sieve_resource_usage_init(&rusage); rusage.cpu_time_msecs = cpu_limit_get_usage_msecs(climit, CPU_LIMIT_TYPE_USER); sieve_resource_usage_add(&interp->rusage, &rusage); cpu_limit_deinit(&climit); } if (ret != SIEVE_EXEC_OK) { sieve_runtime_trace(&interp->runenv, SIEVE_TRLVL_NONE, "[[EXECUTION ABORTED]]"); } if (interrupted != NULL) *interrupted = interp->interrupted; if (!interp->interrupted) { exec_status->resource_usage = interp->rusage; struct event_passthrough *e = event_create_passthrough(interp->runenv.event)-> set_name("sieve_runtime_script_finished"); switch (ret) { case SIEVE_EXEC_OK: break; case SIEVE_EXEC_FAILURE: e->add_str("error", "Failed"); break; case SIEVE_EXEC_TEMP_FAILURE: e->add_str("error", "Failed temporarily"); break; case SIEVE_EXEC_BIN_CORRUPT: e->add_str("error", "Binary corrupt"); break; case SIEVE_EXEC_RESOURCE_LIMIT: e->add_str("error", "Resource limit exceeded"); break; case SIEVE_EXEC_KEEP_FAILED: /* Not supposed to occur at runtime */ i_unreached(); } e_debug(e->event(), "Finished running script '%s' " "(status=%s, resource usage: %s)", sieve_binary_source(interp->runenv.sbin), sieve_execution_exitcode_to_str(ret), sieve_resource_usage_get_summary(&interp->rusage)); interp->running = FALSE; } return ret; } int sieve_interpreter_start(struct sieve_interpreter *interp, struct sieve_result *result, bool *interrupted) { struct sieve_interpreter_extension_reg *eregs; unsigned int ext_count, i; int ret; struct event_passthrough *e = event_create_passthrough(interp->runenv.event)-> set_name("sieve_runtime_script_started"); e_debug(e->event(), "Started running script '%s'", sieve_binary_source(interp->runenv.sbin)); interp->running = TRUE; interp->runenv.result = result; interp->runenv.msgctx = sieve_result_get_message_context(result); sieve_result_ref(result); sieve_resource_usage_init(&interp->rusage); /* Signal registered extensions that the interpreter is being run */ eregs = array_get_modifiable(&interp->extensions, &ext_count); for (i = 0; i < ext_count; i++) { if (!eregs[i].deferred) { eregs[i].started = TRUE; if (eregs[i].intext != NULL && eregs[i].intext->run != NULL && (ret = eregs[i].intext->run( eregs[i].ext, &interp->runenv, eregs[i].context, FALSE)) <= 0) return ret; } } return sieve_interpreter_continue(interp, interrupted); } int sieve_interpreter_run(struct sieve_interpreter *interp, struct sieve_result *result) { sieve_interpreter_reset(interp); return sieve_interpreter_start(interp, result, NULL); } /* * Error handling */ static inline void ATTR_FORMAT(3, 0) sieve_runtime_logv(const struct sieve_runtime_env *renv, const struct sieve_error_params *params, const char *fmt, va_list args) { struct sieve_error_params new_params = *params; new_params.event = renv->event; T_BEGIN { if (new_params.location == NULL) { new_params.location = sieve_runtime_get_full_command_location(renv); } sieve_logv(renv->ehandler, params, fmt, args); } T_END; } #undef sieve_runtime_error void sieve_runtime_error(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); sieve_runtime_logv(renv, ¶ms, fmt, args); va_end(args); } #undef sieve_runtime_warning void sieve_runtime_warning(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); sieve_runtime_logv(renv, ¶ms, fmt, args); va_end(args); } #undef sieve_runtime_log void sieve_runtime_log(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_INFO, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); sieve_runtime_logv(renv, ¶ms, fmt, args); va_end(args); } #undef sieve_runtime_debug void sieve_runtime_debug(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_DEBUG, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); sieve_runtime_logv(renv, ¶ms, fmt, args); va_end(args); } #undef sieve_runtime_critical void sieve_runtime_critical(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *user_prefix, const char *fmt, ...) { const struct sieve_execute_env *eenv = renv->exec_env; struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, .location = location, }; va_list args; va_start(args, fmt); params.event = renv->event; T_BEGIN { if (params.location == NULL) { params.location = sieve_runtime_get_full_command_location(renv); } sieve_criticalv(eenv->svinst, renv->ehandler, ¶ms, user_prefix, fmt, args); } T_END; va_end(args); } #undef sieve_runtime_mail_error int sieve_runtime_mail_error(const struct sieve_runtime_env *renv, struct mail *mail, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { const char *error_msg, *user_prefix; va_list args; error_msg = mailbox_get_last_internal_error(mail->box, NULL); va_start(args, fmt); user_prefix = t_strdup_vprintf(fmt, args); sieve_runtime_critical(renv, csrc_filename, csrc_linenum, NULL, user_prefix, "%s: %s", user_prefix, error_msg); va_end(args); return SIEVE_EXEC_TEMP_FAILURE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-storage-sync.c0000644000175100001700000001112215100335616025335 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str-sanitize.h" #include "home-expand.h" #include "eacces-error.h" #include "mkdir-parents.h" #include "ioloop.h" #include "mail-storage-private.h" #include "sieve-common.h" #include "sieve-error-private.h" #include "sieve-script-private.h" #include "sieve-storage-private.h" /* * Synchronization */ int sieve_storage_sync_init(struct sieve_storage *storage, struct mail_user *user) { enum sieve_storage_flags sflags = storage->flags; if ((sflags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 && (sflags & SIEVE_STORAGE_FLAG_READWRITE) == 0) return 0; if (!storage->allows_synchronization) { if ((sflags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) return -1; return 0; } e_debug(storage->event, "sync: Synchronization active"); storage->sync_inbox_ns = mail_namespace_find_inbox(user->namespaces); return 0; } void sieve_storage_sync_deinit(struct sieve_storage *storage ATTR_UNUSED) { /* nothing */ } /* * Sync attributes */ static int sieve_storage_sync_transaction_begin( struct sieve_storage *storage, struct mailbox_transaction_context **trans_r) { enum mailbox_flags mflags = MAILBOX_FLAG_IGNORE_ACLS; struct mail_namespace *ns = storage->sync_inbox_ns; struct mailbox *inbox; enum mail_error error; if (ns == NULL) return 0; inbox = mailbox_alloc(ns->list, "INBOX", mflags); if (mailbox_open(inbox) < 0) { e_warning(storage->event, "sync: " "Failed to open user INBOX for attribute modifications: %s", mailbox_get_last_internal_error(inbox, &error)); mailbox_free(&inbox); return -1; } *trans_r = mailbox_transaction_begin(inbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL, __func__); return 1; } static int sieve_storage_sync_transaction_finish( struct sieve_storage *storage, struct mailbox_transaction_context **trans) { struct mailbox *inbox; int ret; inbox = mailbox_transaction_get_mailbox(*trans); if ((ret = mailbox_transaction_commit(trans)) < 0) { enum mail_error error; e_warning(storage->event, "sync: " "Failed to update INBOX attributes: %s", mail_storage_get_last_error( mailbox_get_storage(inbox), &error)); } mailbox_free(&inbox); return ret; } int sieve_storage_sync_script_save(struct sieve_storage *storage, const char *name) { struct mailbox_transaction_context *trans; const char *key; int ret; if ((ret = sieve_storage_sync_transaction_begin(storage, &trans)) <= 0) return ret; key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL); mail_index_attribute_set(trans->itrans, TRUE, key, ioloop_time, 0); return sieve_storage_sync_transaction_finish(storage, &trans); } int sieve_storage_sync_script_rename(struct sieve_storage *storage, const char *oldname, const char *newname) { struct mailbox_transaction_context *trans; const char *oldkey, *newkey; int ret; if ((ret = sieve_storage_sync_transaction_begin(storage, &trans)) <= 0) return ret; oldkey = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, oldname, NULL); newkey = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, newname, NULL); mail_index_attribute_unset(trans->itrans, TRUE, oldkey, ioloop_time); mail_index_attribute_set(trans->itrans, TRUE, newkey, ioloop_time, 0); return sieve_storage_sync_transaction_finish(storage, &trans); } int sieve_storage_sync_script_delete(struct sieve_storage *storage, const char *name) { struct mailbox_transaction_context *trans; const char *key; int ret; if ((ret = sieve_storage_sync_transaction_begin(storage, &trans)) <= 0) return ret; key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL); mail_index_attribute_unset(trans->itrans, TRUE, key, ioloop_time); return sieve_storage_sync_transaction_finish(storage, &trans); } int sieve_storage_sync_script_activate(struct sieve_storage *storage) { struct mailbox_transaction_context *trans; int ret; if ((ret = sieve_storage_sync_transaction_begin(storage, &trans)) <= 0) return ret; mail_index_attribute_set(trans->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time, 0); return sieve_storage_sync_transaction_finish(storage, &trans); } int sieve_storage_sync_deactivate(struct sieve_storage *storage) { struct mailbox_transaction_context *trans; int ret; if ((ret = sieve_storage_sync_transaction_begin(storage, &trans)) <= 0) return ret; mail_index_attribute_unset(trans->itrans, TRUE, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT, ioloop_time); return sieve_storage_sync_transaction_finish(storage, &trans); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-types.h0000644000175100001700000001721715100335616024103 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_TYPES_H #define SIEVE_TYPES_H #include "lib.h" #include "smtp-address.h" #include /* * Forward declarations */ struct smtp_params_mail; struct smtp_params_rcpt; struct sieve_instance; struct sieve_callbacks; struct sieve_script; struct sieve_binary; struct sieve_message_data; struct sieve_script_env; struct sieve_exec_status; struct sieve_trace_log; /* * System environment */ enum sieve_flag { /* Relative paths are resolved to HOME */ SIEVE_FLAG_HOME_RELATIVE = (1 << 0), /* Sieve is running in command line tool */ SIEVE_FLAG_COMMAND_LINE = (1 << 1), }; /* Sieve evaluation can be performed at various different points as messages are processed. */ enum sieve_env_location { /* Unknown */ SIEVE_ENV_LOCATION_UNKNOWN = 0, /* "MDA" - evaluation is being performed by a Mail Delivery Agent */ SIEVE_ENV_LOCATION_MDA, /* "MTA" - the Sieve script is being evaluated by a Message Transfer Agent */ SIEVE_ENV_LOCATION_MTA, /* "MS" - evaluation is being performed by a Message Store */ SIEVE_ENV_LOCATION_MS, }; /* The point relative to final delivery where the Sieve script is being evaluated. */ enum sieve_delivery_phase { SIEVE_DELIVERY_PHASE_UNKNOWN = 0, SIEVE_DELIVERY_PHASE_PRE, SIEVE_DELIVERY_PHASE_DURING, SIEVE_DELIVERY_PHASE_POST, }; struct sieve_environment { const char *hostname; const char *domainname; const char *base_dir; const char *username; const char *home_dir; const char *temp_dir; struct event *event_parent; enum sieve_flag flags; enum sieve_env_location location; enum sieve_delivery_phase delivery_phase; }; /* * Callbacks */ struct sieve_callbacks { const char * (*get_homedir)(struct sieve_instance *svinst, void *context); }; /* * Errors */ enum sieve_error { SIEVE_ERROR_NONE = 0, /* Temporary internal error */ SIEVE_ERROR_TEMP_FAILURE, /* It's not possible to do the wanted operation */ SIEVE_ERROR_NOT_POSSIBLE, /* Invalid parameters (eg. script name not valid) */ SIEVE_ERROR_BAD_PARAMS, /* No permission to do the request */ SIEVE_ERROR_NO_PERMISSION, /* Out of disk space */ SIEVE_ERROR_NO_QUOTA, /* Item (e.g. script or binary) cannot be found */ SIEVE_ERROR_NOT_FOUND, /* Item (e.g. script or binary) already exists */ SIEVE_ERROR_EXISTS, /* Referenced item (e.g. script or binary) is not valid or currupt */ SIEVE_ERROR_NOT_VALID, /* Not allowed to perform the operation because the item is in active use */ SIEVE_ERROR_ACTIVE, /* Operation exceeds resource limit */ SIEVE_ERROR_RESOURCE_LIMIT, }; /* * Compile flags */ enum sieve_compile_flags { /* No global extensions are allowed * (as marked by sieve_global_extensions setting) */ SIEVE_COMPILE_FLAG_NOGLOBAL = (1<<0), /* Script is being uploaded (usually through ManageSieve) */ SIEVE_COMPILE_FLAG_UPLOADED = (1<<1), /* Script is being activated (usually through ManageSieve) */ SIEVE_COMPILE_FLAG_ACTIVATED = (1<<2), /* Compiled for environment with no access to envelope */ SIEVE_COMPILE_FLAG_NO_ENVELOPE = (1<<3), }; /* * Message data * * - The mail message + envelope data */ struct sieve_message_data { struct mail *mail; const char *auth_user; const char *id; struct { const struct smtp_address *mail_from; const struct smtp_params_mail *mail_params; const struct smtp_address *rcpt_to; const struct smtp_params_rcpt *rcpt_params; } envelope; }; /* * Runtime flags */ enum sieve_execute_flags { /* No global extensions are allowed * (as marked by sieve_global_extensions setting) */ SIEVE_EXECUTE_FLAG_NOGLOBAL = (1<<0), /* Do not execute (implicit keep) at the end */ SIEVE_EXECUTE_FLAG_DEFER_KEEP = (1<<1), /* There is no envelope */ SIEVE_EXECUTE_FLAG_NO_ENVELOPE = (1<<2), /* Skip sending responses */ SIEVE_EXECUTE_FLAG_SKIP_RESPONSES = (1<<3), /* Log result as info (when absent, only debug logging is performed) */ SIEVE_EXECUTE_FLAG_LOG_RESULT = (1<<4), }; /* * Runtime trace settings */ typedef enum { SIEVE_TRLVL_NONE = 0, SIEVE_TRLVL_ACTIONS, SIEVE_TRLVL_COMMANDS, SIEVE_TRLVL_TESTS, SIEVE_TRLVL_MATCHING, } sieve_trace_level_t; enum { SIEVE_TRFLG_DEBUG = (1 << 0), SIEVE_TRFLG_ADDRESSES = (1 << 1), }; struct sieve_trace_config { sieve_trace_level_t level; unsigned int flags; }; /* * Duplicate checking */ enum sieve_duplicate_check_result { SIEVE_DUPLICATE_CHECK_RESULT_EXISTS = 1, SIEVE_DUPLICATE_CHECK_RESULT_NOT_FOUND = 0, SIEVE_DUPLICATE_CHECK_RESULT_FAILURE = -1, SIEVE_DUPLICATE_CHECK_RESULT_TEMP_FAILURE = -2, }; /* * Script invocation cause */ #define SIEVE_SCRIPT_CAUSE_ANY "any" #define SIEVE_SCRIPT_CAUSE_DELIVERY "delivery" /* * Script environment * * - Environment for currently executing script */ struct sieve_script_env { /* Mail-related */ struct mail_user *user; const struct message_address *postmaster_address; const char *default_mailbox; bool mailbox_autocreate; bool mailbox_autosubscribe; /* External context data */ void *script_context; /* Callbacks */ /* Interface for sending mail */ void *(*smtp_start)(const struct sieve_script_env *senv, const struct smtp_address *mail_from); /* Add a new recipient */ void (*smtp_add_rcpt)(const struct sieve_script_env *senv, void *handle, const struct smtp_address *rcpt_to); /* Get an output stream where the message can be written to. The recipients must already be added before calling this. */ struct ostream *(*smtp_send)(const struct sieve_script_env *senv, void *handle); /* Abort the SMTP transaction after smtp_send() is already issued */ void (*smtp_abort)(const struct sieve_script_env *senv, void *handle); /* Returns 1 on success, 0 on permanent failure, -1 on temporary failure. */ int (*smtp_finish)(const struct sieve_script_env *senv, void *handle, const char **error_r); /* Interface for marking and checking duplicates */ void *(*duplicate_transaction_begin)( const struct sieve_script_env *senv); void (*duplicate_transaction_commit)(void **_dup_trans); void (*duplicate_transaction_rollback)(void **_dup_trans); enum sieve_duplicate_check_result (*duplicate_check)(void *dup_trans, const struct sieve_script_env *senv, const void *id, size_t id_size); void (*duplicate_mark)(void *dup_trans, const struct sieve_script_env *senv, const void *id, size_t id_size, time_t time); /* Interface for rejecting mail */ int (*reject_mail)(const struct sieve_script_env *senv, const struct smtp_address *recipient, const char *reason); /* Interface for amending result messages */ const char * (*result_amend_log_message)(const struct sieve_script_env *senv, enum log_type log_type, const char *message); /* Execution status record */ struct sieve_exec_status *exec_status; /* Runtime trace*/ struct sieve_trace_log *trace_log; struct sieve_trace_config trace_config; }; #define SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) \ (senv->default_mailbox == NULL ? "INBOX" : senv->default_mailbox ) /* * Resource usage */ struct sieve_resource_usage { /* The total amount of system + user CPU time consumed while executing the Sieve script. */ unsigned int cpu_time_msecs; }; /* * Script execution status */ struct sieve_exec_status { struct mail_storage *last_storage; struct sieve_resource_usage resource_usage; bool message_saved:1; bool message_forwarded:1; bool tried_default_save:1; bool keep_original:1; bool store_failed:1; bool significant_action_executed:1; }; /* * Execution exit codes */ enum sieve_execution_exitcode { SIEVE_EXEC_OK = 1, SIEVE_EXEC_FAILURE = 0, SIEVE_EXEC_TEMP_FAILURE = -1, SIEVE_EXEC_BIN_CORRUPT = -2, SIEVE_EXEC_KEEP_FAILED = -3, SIEVE_EXEC_RESOURCE_LIMIT = -4, }; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-settings.h0000644000175100001700000000202415100335616024565 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_SETTINGS_H #define SIEVE_SETTINGS_H #include "smtp-address.h" #include "sieve-config.h" #include "sieve-address-source.h" struct sieve_address_source; struct sieve_settings { pool_t pool; bool enabled; uoff_t max_script_size; unsigned int max_actions; unsigned int max_redirects; unsigned int max_cpu_time; unsigned int resource_usage_timeout; const char* redirect_envelope_from; unsigned int redirect_duplicate_period; const char *user_email; const char *user_log_path; const char *trace_dir; const char *trace_level; bool trace_debug; bool trace_addresses; ARRAY_TYPE(const_string) plugins; const char *plugin_dir; ARRAY_TYPE(const_string) extensions; ARRAY_TYPE(const_string) global_extensions; ARRAY_TYPE(const_string) implicit_extensions; struct { struct sieve_address_source redirect_envelope_from; const struct smtp_address *user_email; } parsed; }; extern const struct sieve_settings sieve_default_settings; extern const struct setting_parser_info sieve_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/0000755000175100001700000000000015100335670023126 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/0000755000175100001700000000000015100335670024561 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/Makefile.am0000644000175100001700000000066215100335616026621 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_mailbox.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tags = \ tag-mailbox-create.c tests = \ tst-mailboxexists.c libsieve_ext_mailbox_la_SOURCES = \ $(tags) \ $(tests) \ ext-mailbox.c public_headers = \ sieve-ext-mailbox.h headers = \ ext-mailbox-common.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h0000644000175100001700000000104115100335616030445 0ustar00buildbotbuildbot00000000000000#ifndef EXT_MAILBOX_COMMON_H #define EXT_MAILBOX_COMMON_H #include "sieve-common.h" #include "sieve-ext-mailbox.h" /* * Tagged arguments */ extern const struct sieve_argument_def mailbox_create_tag; /* * Commands */ extern const struct sieve_command_def mailboxexists_test; /* * Operands */ extern const struct sieve_operand_def mailbox_create_operand; /* * Operations */ extern const struct sieve_operation_def mailboxexists_operation; /* * Extension */ extern const struct sieve_extension_def mailbox_extension; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/Makefile.in0000644000175100001700000006143115100335630026627 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/mailbox ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(pkginc_lib_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_mailbox_la_LIBADD = am__objects_1 = tag-mailbox-create.lo am__objects_2 = tst-mailboxexists.lo am_libsieve_ext_mailbox_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ ext-mailbox.lo libsieve_ext_mailbox_la_OBJECTS = \ $(am_libsieve_ext_mailbox_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-mailbox.Plo \ ./$(DEPDIR)/tag-mailbox-create.Plo \ ./$(DEPDIR)/tst-mailboxexists.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_mailbox_la_SOURCES) DIST_SOURCES = $(libsieve_ext_mailbox_la_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(noinst_HEADERS) $(pkginc_lib_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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_mailbox.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tags = \ tag-mailbox-create.c tests = \ tst-mailboxexists.c libsieve_ext_mailbox_la_SOURCES = \ $(tags) \ $(tests) \ ext-mailbox.c public_headers = \ sieve-ext-mailbox.h headers = \ ext-mailbox-common.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/mailbox/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/mailbox/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_mailbox.la: $(libsieve_ext_mailbox_la_OBJECTS) $(libsieve_ext_mailbox_la_DEPENDENCIES) $(EXTRA_libsieve_ext_mailbox_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_mailbox_la_OBJECTS) $(libsieve_ext_mailbox_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-mailbox.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-mailbox-create.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-mailboxexists.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-mailbox.Plo -rm -f ./$(DEPDIR)/tag-mailbox-create.Plo -rm -f ./$(DEPDIR)/tst-mailboxexists.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-mailbox.Plo -rm -f ./$(DEPDIR)/tag-mailbox-create.Plo -rm -f ./$(DEPDIR)/tst-mailboxexists.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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-pkginc_libHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/ext-mailbox.c0000644000175100001700000000336515100335616027165 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension mailbox * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5490 * Implementation: full * Status: testing * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "ext-mailbox-common.h" /* * Tag registration */ void sieve_ext_mailbox_register_create_tag (struct sieve_validator *valdtr, const struct sieve_extension *mailbox_ext, const char *command) { if ( sieve_validator_extension_loaded(valdtr, mailbox_ext) ) { sieve_validator_register_external_tag(valdtr, command, mailbox_ext, &mailbox_create_tag, SIEVE_OPT_SIDE_EFFECT); } } /* * Extension */ static bool ext_mailbox_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def mailbox_extension = { .name = "mailbox", .validator_load = ext_mailbox_validator_load, SIEVE_EXT_DEFINE_OPERATION(mailboxexists_operation), SIEVE_EXT_DEFINE_OPERAND(mailbox_create_operand) }; static bool ext_mailbox_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register :create tag with fileinto command and we don't care whether this * command is registered or even whether it will be registered at all. The * validator handles either situation gracefully */ sieve_validator_register_external_tag (valdtr, "fileinto", ext, &mailbox_create_tag, SIEVE_OPT_SIDE_EFFECT); /* Register new test */ sieve_validator_register_command(valdtr, ext, &mailboxexists_test); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/sieve-ext-mailbox.h0000644000175100001700000000115415100335616030275 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXT_MAILBOX_H #define SIEVE_EXT_MAILBOX_H /* sieve_ext_mailbox_get_extension(): * Get the extension struct for the mailbox extension. */ static inline const struct sieve_extension *sieve_ext_mailbox_get_extension (struct sieve_instance *svinst) { return sieve_extension_get_by_name(svinst, "mailbox"); } /* sieve_ext_mailbox_register_create_tag(): * Register the :create tagged argument for a command other than fileinto and * redirect. */ void sieve_ext_mailbox_register_create_tag (struct sieve_validator *valdtr, const struct sieve_extension *mailbox_ext, const char *command); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c0000644000175100001700000001106315100335616030373 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-code.h" #include "sieve-actions.h" #include "sieve-result.h" #include "sieve-generator.h" #include "ext-mailbox-common.h" /* * Tagged argument */ static bool tag_mailbox_create_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_mailbox_create_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); const struct sieve_argument_def mailbox_create_tag = { .identifier = "create", .validate = tag_mailbox_create_validate, .generate = tag_mailbox_create_generate }; /* * Side effect */ static void seff_mailbox_create_print(const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int seff_mailbox_create_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context ATTR_UNUSED); const struct sieve_side_effect_def mailbox_create_side_effect = { SIEVE_OBJECT("create", &mailbox_create_operand, 0), .precedence = 100, .to_action = &act_store, .print = seff_mailbox_create_print, .pre_execute = seff_mailbox_create_pre_execute }; /* * Operand */ static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(mailbox_create_side_effect); const struct sieve_operand_def mailbox_create_operand = { .name = "create operand", .ext_def = &mailbox_extension, .class = &sieve_side_effect_operand_class, .interface = &ext_side_effects }; /* * Tag validation */ static bool tag_mailbox_create_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd ATTR_UNUSED) { *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Code generation */ static bool tag_mailbox_create_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context ATTR_UNUSED) { if (sieve_ast_argument_type(arg) != SAAT_TAG) return FALSE; sieve_opr_side_effect_emit(cgenv->sblock, arg->argument->ext, &mailbox_create_side_effect); return TRUE; } /* * Side effect implementation */ static void seff_mailbox_create_print(const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { sieve_result_seffect_printf( rpenv, "create mailbox if it does not exist"); } static int seff_mailbox_create_pre_execute( const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context ATTR_UNUSED) { struct act_store_transaction *trans = tr_context; const struct sieve_execute_env *eenv = aenv->exec_env; struct mailbox *box = trans->box; /* Check whether creation is necessary */ if (box == NULL || trans->disabled) return SIEVE_EXEC_OK; eenv->exec_status->last_storage = mailbox_get_storage(box); /* Open the mailbox (may already be open) */ if (trans->error_code == MAIL_ERROR_NONE) { if (mailbox_open(box) < 0) sieve_act_store_get_storage_error(aenv, trans); } /* Check whether creation has a chance of working */ switch (trans->error_code) { case MAIL_ERROR_NONE: return SIEVE_EXEC_OK; case MAIL_ERROR_NOTFOUND: break; case MAIL_ERROR_TEMP: return SIEVE_EXEC_TEMP_FAILURE; default: return SIEVE_EXEC_FAILURE; } trans->error = NULL; trans->error_code = MAIL_ERROR_NONE; /* Create mailbox */ if (mailbox_create(box, NULL, FALSE) < 0) { sieve_act_store_get_storage_error(aenv, trans); if (trans->error_code == MAIL_ERROR_EXISTS) { trans->error = NULL; trans->error_code = MAIL_ERROR_NONE; } else { return (trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } } /* Subscribe to it if necessary */ if (eenv->scriptenv->mailbox_autosubscribe) { (void)mailbox_list_set_subscribed( mailbox_get_namespace(box)->list, mailbox_get_name(box), TRUE); } /* Try opening again */ if (mailbox_open(box) < 0) { /* Failed definitively */ sieve_act_store_get_storage_error(aenv, trans); return (trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c0000644000175100001700000001453015100335616030433 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-actions.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-mailbox-common.h" /* * Mailboxexists command * * Syntax: * mailboxexists */ static bool tst_mailboxexists_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_mailboxexists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def mailboxexists_test = { .identifier = "mailboxexists", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_mailboxexists_validate, .generate = tst_mailboxexists_generate, }; /* * Mailboxexists operation */ static bool tst_mailboxexists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_mailboxexists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def mailboxexists_operation = { .mnemonic = "MAILBOXEXISTS", .ext_def = &mailbox_extension, .dump = tst_mailboxexists_operation_dump, .execute = tst_mailboxexists_operation_execute, }; /* * Test validation */ struct _validate_context { struct sieve_validator *valdtr; struct sieve_command *tst; }; static int tst_mailboxexists_mailbox_validate(void *context, struct sieve_ast_argument *arg) { struct _validate_context *valctx = (struct _validate_context *)context; if (sieve_argument_is_string_literal(arg)) { const char *mailbox = sieve_ast_argument_strc(arg), *error; if (!sieve_mailbox_check_name(mailbox, &error)) { sieve_argument_validate_warning( valctx->valdtr, arg, "%s test: " "invalid mailbox name '%s' specified: %s", sieve_command_identifier(valctx->tst), str_sanitize(mailbox, 256), error); } } return 1; } static bool tst_mailboxexists_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *aarg; struct _validate_context valctx; if (!sieve_validate_positional_argument( valdtr, tst, arg, "mailbox-names", 1, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; aarg = arg; i_zero(&valctx); valctx.valdtr = valdtr; valctx.tst = tst; return (sieve_ast_stringlist_map( &aarg, &valctx, tst_mailboxexists_mailbox_validate) >= 0); } /* * Test generation */ static bool tst_mailboxexists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { sieve_operation_emit(cgenv->sblock, tst->ext, &mailboxexists_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_mailboxexists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "MAILBOXEXISTS"); sieve_code_descend(denv); return sieve_opr_stringlist_dump(denv, address, "mailbox-names"); } /* * Code execution */ static int tst_mailboxexists_test_mailbox(const struct sieve_runtime_env *renv, const char *mailbox, bool trace, bool *all_exist_r) { const struct sieve_execute_env *eenv = renv->exec_env; struct mailbox *box; const char *error; /* Check validity of mailbox name */ if (!sieve_mailbox_check_name(mailbox, &error)) { sieve_runtime_warning( renv, NULL, "mailboxexists test: " "invalid mailbox name '%s' specified: %s", str_sanitize(mailbox, 256), error); *all_exist_r = FALSE; return SIEVE_EXEC_OK; } /* Open the box */ box = mailbox_alloc_for_user(eenv->scriptenv->user, mailbox, MAILBOX_FLAG_POST_SESSION); if (mailbox_open(box) < 0) { if (trace) { sieve_runtime_trace( renv, 0, "mailbox '%s' cannot be opened", str_sanitize(mailbox, 80)); } mailbox_free(&box); *all_exist_r = FALSE; return SIEVE_EXEC_OK; } /* Also fail when it is readonly */ if (mailbox_is_readonly(box)) { if (trace) { sieve_runtime_trace( renv, 0, "mailbox '%s' is read-only", str_sanitize(mailbox, 80)); } mailbox_free(&box); *all_exist_r = FALSE; return SIEVE_EXEC_OK; } /* FIXME: check acl for 'p' or 'i' ACL permissions as required by RFC */ if (trace) { sieve_runtime_trace( renv, 0, "mailbox '%s' exists", str_sanitize(mailbox, 80)); } /* Close mailbox */ mailbox_free(&box); return SIEVE_EXEC_OK; } static int tst_mailboxexists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_execute_env *eenv = renv->exec_env; struct sieve_stringlist *mailbox_names; string_t *mailbox_item; bool trace = FALSE; bool all_exist = TRUE; int ret; /* * Read operands */ /* Read notify uris */ ret = sieve_opr_stringlist_read(renv, address, "mailbox-names", &mailbox_names); if (ret <= 0) return ret; /* * Perform operation */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS)) { sieve_runtime_trace(renv, 0, "mailboxexists test"); sieve_runtime_trace_descend(renv); trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); } if (eenv->scriptenv->user == NULL) { sieve_runtime_trace(renv, 0, "no mail user; yield true"); sieve_interpreter_set_test_result(renv->interp, TRUE); return SIEVE_EXEC_OK; } mailbox_item = NULL; while (all_exist && (ret = sieve_stringlist_next_item(mailbox_names, &mailbox_item)) > 0) { const char *mailbox = str_c(mailbox_item); ret = tst_mailboxexists_test_mailbox(renv, mailbox, trace, &all_exist); if (ret <= 0) return ret; } if (ret < 0) { sieve_runtime_trace_error( renv, "invalid mailbox name item"); return SIEVE_EXEC_BIN_CORRUPT; } if (trace) { if (all_exist) { sieve_runtime_trace(renv, 0, "all mailboxes are available"); } else { sieve_runtime_trace(renv, 0, "some mailboxes are unavailable"); } } sieve_interpreter_set_test_result(renv->interp, all_exist); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/0000755000175100001700000000000015100335670024240 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/Makefile.am0000644000175100001700000000034615100335616026277 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_regex.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_regex_la_SOURCES = \ mcht-regex.c \ ext-regex-common.c \ ext-regex.c noinst_HEADERS = \ ext-regex-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/ext-regex-common.c0000644000175100001700000000077615100335616027614 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-match-types.h" #include "ext-regex-common.h" /* * Regex match type operand */ static const struct sieve_extension_objects ext_match_types = SIEVE_EXT_DEFINE_MATCH_TYPE(regex_match_type); const struct sieve_operand_def regex_match_type_operand = { .name = "regex match", .ext_def = ®ex_extension, .class = &sieve_match_type_operand_class, .interface = &ext_match_types }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/ext-regex-common.h0000644000175100001700000000046515100335616027614 0ustar00buildbotbuildbot00000000000000#ifndef EXT_REGEX_COMMON_H #define EXT_REGEX_COMMON_H /* * Extension */ extern const struct sieve_extension_def regex_extension; /* * Operand */ extern const struct sieve_operand_def regex_match_type_operand; /* * Match type */ extern const struct sieve_match_type_def regex_match_type; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/Makefile.in0000644000175100001700000005421315100335630026306 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/regex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_regex_la_LIBADD = am_libsieve_ext_regex_la_OBJECTS = mcht-regex.lo ext-regex-common.lo \ ext-regex.lo libsieve_ext_regex_la_OBJECTS = $(am_libsieve_ext_regex_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-regex-common.Plo \ ./$(DEPDIR)/ext-regex.Plo ./$(DEPDIR)/mcht-regex.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_regex_la_SOURCES) DIST_SOURCES = $(libsieve_ext_regex_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_regex.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_regex_la_SOURCES = \ mcht-regex.c \ ext-regex-common.c \ ext-regex.c noinst_HEADERS = \ ext-regex-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/regex/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/regex/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_regex.la: $(libsieve_ext_regex_la_OBJECTS) $(libsieve_ext_regex_la_DEPENDENCIES) $(EXTRA_libsieve_ext_regex_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_regex_la_OBJECTS) $(libsieve_ext_regex_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-regex-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-regex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-regex.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-regex-common.Plo -rm -f ./$(DEPDIR)/ext-regex.Plo -rm -f ./$(DEPDIR)/mcht-regex.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-regex-common.Plo -rm -f ./$(DEPDIR)/ext-regex.Plo -rm -f ./$(DEPDIR)/mcht-regex.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/mcht-regex.c0000644000175100001700000002170715100335616026456 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Match-type ':regex' */ #include "lib.h" #include "mempool.h" #include "buffer.h" #include "array.h" #include "str.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-ast.h" #include "sieve-stringlist.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-interpreter.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-match.h" #include "ext-regex-common.h" #include "dregex.h" #include #include /* * Configuration */ #define MCHT_REGEX_MAX_SUBSTITUTIONS SIEVE_MAX_MATCH_VALUES /* * Match type */ static bool mcht_regex_validate_context(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); static void mcht_regex_match_init(struct sieve_match_context *mctx); static int mcht_regex_match_keys(struct sieve_match_context *mctx, const char *val, size_t val_size, struct sieve_stringlist *key_list); static void mcht_regex_match_deinit(struct sieve_match_context *mctx); const struct sieve_match_type_def regex_match_type = { SIEVE_OBJECT("regex", ®ex_match_type_operand, 0), .validate_context = mcht_regex_validate_context, .match_init = mcht_regex_match_init, .match_keys = mcht_regex_match_keys, .match_deinit = mcht_regex_match_deinit, }; /* * Match type validation */ static int mcht_regex_validate_regexp(struct sieve_validator *valdtr, struct sieve_match_type_context *mtctx ATTR_UNUSED, struct sieve_ast_argument *key, int cflags) { int ret; const char *dregex_str = sieve_ast_argument_strc(key); const char *error; struct dregex_code *code = dregex_code_create(); ret = dregex_code_compile(code, dregex_str, cflags, &error); dregex_code_free(&code); if (ret != 0) { sieve_argument_validate_error( valdtr, key, "invalid regular expression '%s' for regex match: %s", str_sanitize(dregex_str, 128), error); return -1; } return 1; } struct _regex_key_context { struct sieve_validator *valdtr; struct sieve_match_type_context *mtctx; int cflags; }; static int mcht_regex_validate_key_argument(void *context, struct sieve_ast_argument *key) { struct _regex_key_context *keyctx = (struct _regex_key_context *)context; /* FIXME: We can currently only handle string literal argument, so variables are not allowed. */ if (sieve_argument_is_string_literal(key)) { return mcht_regex_validate_regexp(keyctx->valdtr, keyctx->mtctx, key, keyctx->cflags); } return 1; } static bool mcht_regex_validate_context(struct sieve_validator *valdtr, struct sieve_ast_argument *arg ATTR_UNUSED, struct sieve_match_type_context *mtctx, struct sieve_ast_argument *key_arg) { const struct sieve_comparator *cmp = mtctx->comparator; int cflags = DREGEX_NOSUB; struct _regex_key_context keyctx; struct sieve_ast_argument *kitem; if (cmp != NULL) { if (sieve_comparator_is(cmp, i_ascii_casemap_comparator)) cflags |= DREGEX_ICASE | DREGEX_ASCII_ONLY; else if (sieve_comparator_is(cmp, i_octet_comparator)) cflags |= DREGEX_ASCII_ONLY; else if (sieve_comparator_is(cmp, i_unicode_casemap_comparator)) cflags |= DREGEX_ICASE; else { sieve_argument_validate_error( valdtr, mtctx->argument, "regex match type only supports " "i;octet, i;ascii-casemap and i;unicode-casemap comparators"); return FALSE; } } /* Validate regular expression keys */ keyctx.valdtr = valdtr; keyctx.mtctx = mtctx; keyctx.cflags = cflags; kitem = key_arg; if (sieve_ast_stringlist_map(&kitem, &keyctx, mcht_regex_validate_key_argument) <= 0) return FALSE; return TRUE; } /* * Match type implementation */ struct mcht_regex_key { struct dregex_code *regexp; int status; }; struct mcht_regex_context { ARRAY(struct mcht_regex_key) reg_expressions; ARRAY_TYPE(const_string) pmatch; bool all_compiled:1; bool capture_groups; }; static void mcht_regex_match_init(struct sieve_match_context *mctx) { pool_t pool = mctx->pool; struct mcht_regex_context *ctx; /* Create context */ ctx = p_new(pool, struct mcht_regex_context, 1); /* Create storage for match values if match values are requested */ ctx->capture_groups = sieve_match_values_are_enabled(mctx->runenv); /* Assign context */ mctx->data = ctx; } static int mcht_regex_match_key(struct sieve_match_context *mctx, const char *val, struct dregex_code *code) { struct mcht_regex_context *ctx = (struct mcht_regex_context *)mctx->data; const char *error; int ret; ARRAY_TYPE(const_string) pmatch; if (ctx->capture_groups) t_array_init(&pmatch, 8); /* Execute regex */ if (!ctx->capture_groups) ret = dregex_code_match(code, val, &error); else ret = dregex_code_match_groups(code, val, &pmatch, &error); /* Handle match values if necessary */ if (ret > 0) { if (ctx->capture_groups && array_count(&pmatch) > 0) { struct sieve_match_values *mvalues; string_t *subst = t_str_new(32); const char *mvalue; /* Start new list of match values */ mvalues = sieve_match_values_start(mctx->runenv); i_assert(mvalues != NULL); array_foreach_elem(&pmatch, mvalue) { str_append(subst, mvalue); sieve_match_values_add(mvalues, subst); str_truncate(subst, 0); } /* Substitute the new match values */ sieve_match_values_commit(mctx->runenv, &mvalues); } return 1; } return 0; } static int mcht_regex_match_keys(struct sieve_match_context *mctx, const char *val, size_t val_size ATTR_UNUSED, struct sieve_stringlist *key_list) { const struct sieve_runtime_env *renv = mctx->runenv; bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); struct mcht_regex_context *ctx = (struct mcht_regex_context *)mctx->data; const struct sieve_comparator *cmp = mctx->comparator; int match; if (!ctx->all_compiled) { string_t *key_item = NULL; unsigned int i; int ret; /* Regular expressions still need to be compiled */ if (!array_is_created(&ctx->reg_expressions)) p_array_init(&ctx->reg_expressions, mctx->pool, 16); i = 0; match = 0; while (match == 0 && (ret = sieve_stringlist_next_item(key_list, &key_item)) > 0) { T_BEGIN { struct mcht_regex_key *rkey; if (i >= array_count(&ctx->reg_expressions)) { int cflags = 0; rkey = array_append_space(&ctx->reg_expressions); /* Configure case-sensitivity according to comparator */ if (sieve_comparator_is(cmp, i_octet_comparator)) cflags |= DREGEX_ASCII_ONLY; else if (sieve_comparator_is(cmp, i_ascii_casemap_comparator)) cflags |= (DREGEX_ICASE | DREGEX_ASCII_ONLY); else if (sieve_comparator_is(cmp, i_unicode_casemap_comparator)) cflags |= DREGEX_ICASE; else rkey->status = -1; /* Not supported */ if (rkey->status >= 0) { const char *dregex_str = str_c(key_item); const char *error; int rxret; /* Indicate whether match values need to be produced */ if (!ctx->capture_groups) cflags |= DREGEX_NOSUB; struct dregex_code *code = dregex_code_create(); /* Compile regular expression */ rxret = dregex_code_compile(code, dregex_str, cflags, &error); if (rxret != 0) { sieve_runtime_error(renv, NULL, "invalid regular expression '%s' for regex match: %s", str_sanitize(dregex_str, 128), error); rkey->status = -1; dregex_code_free(&code); } else { rkey->status = 1; rkey->regexp = code; } } } else { rkey = array_idx_modifiable(&ctx->reg_expressions, 1); } if (rkey->status > 0) { match = mcht_regex_match_key( mctx, val, rkey->regexp); if (trace) { sieve_runtime_trace(renv, 0, "with regex '%s' [id=%d] => %d", str_sanitize(str_c(key_item), 80), array_count(&ctx->reg_expressions)-1, match); } } } T_END; i++; } if (ret == 0) { ctx->all_compiled = TRUE; } else if (ret < 0) { mctx->exec_status = key_list->exec_status; match = -1; } } else { const struct mcht_regex_key *rkeys; unsigned int i, count; /* Regular expressions are compiled */ rkeys = array_get(&ctx->reg_expressions, &count); i = 0; match = 0; while (match == 0 && i < count) { if (rkeys[i].status > 0) { match = mcht_regex_match_key( mctx, val, rkeys[i].regexp); if (trace) { sieve_runtime_trace(renv, 0, "with compiled regex [id=%d] => %d", i, match); } } i++; } } return match; } void mcht_regex_match_deinit(struct sieve_match_context *mctx) { struct mcht_regex_context *ctx = (struct mcht_regex_context *)mctx->data; struct mcht_regex_key *rkeys; unsigned int count, i; /* Clean up compiled regular expressions */ if (array_is_created(&ctx->reg_expressions)) { rkeys = array_get_modifiable(&ctx->reg_expressions, &count); for (i = 0; i < count; i++) dregex_code_free(&rkeys[i].regexp); } } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/regex/ext-regex.c0000644000175100001700000000304615100335616026317 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension regex * --------------- * * Authors: Stephan Bosch * Specification: draft-murchison-sieve-regex-08 (not latest) * Implementation: full * Status: testing * */ /* FIXME: Regular expressions are compiled during compilation and * again during interpretation. This is suboptimal and should be * changed. This requires dumping the compiled regex to the binary. * Most likely, this will only be possible when we implement regular * expressions ourselves. */ /* NOTE: Extension does not support unicode equality operator `[=e=]` or * collation sequence `[.e.]` due to dovecot lib-regex limitations. */ #include "lib.h" #include "mempool.h" #include "buffer.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-regex-common.h" #include /* * Extension */ static bool ext_regex_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def regex_extension = { .name = "regex", .validator_load = ext_regex_validator_load, SIEVE_EXT_DEFINE_OPERAND(regex_match_type_operand) }; static bool ext_regex_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { sieve_match_type_register(valdtr, ext, ®ex_match_type); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/0000755000175100001700000000000015100335670025224 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/ext-editheader-limits.h0000644000175100001700000000026315100335616031571 0ustar00buildbotbuildbot00000000000000#ifndef EXT_EDITHEADER_LIMITS_H #define EXT_EDITHEADER_LIMITS_H #define EXT_EDITHEADER_MINIMUM_MAX_HEADER_SIZE 1024 #define EXT_EDITHEADER_DEFAULT_MAX_HEADER_SIZE 2048 #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/ext-editheader.c0000644000175100001700000000264415100335616030272 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension debug * --------------- * * Authors: Stephan Bosch * Specification: RFC 5293 * Implementation: full * Status: testing * */ #include "lib.h" #include "array.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-editheader-common.h" /* * Operations */ const struct sieve_operation_def *editheader_operations[] = { &addheader_operation, &deleteheader_operation, }; /* * Extension */ static bool ext_editheader_validator_load(const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def editheader_extension = { .name = "editheader", .load = ext_editheader_load, .unload = ext_editheader_unload, .validator_load = ext_editheader_validator_load, SIEVE_EXT_DEFINE_OPERATIONS(editheader_operations), }; static bool ext_editheader_validator_load(const struct sieve_extension *ext, struct sieve_validator *validator) { /* Register new commands */ sieve_validator_register_command(validator, ext, &addheader_command); sieve_validator_register_command(validator, ext, &deleteheader_command); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/Makefile.am0000644000175100001700000000064215100335616027262 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_editheader.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-addheader.c \ cmd-deleteheader.c libsieve_ext_editheader_la_SOURCES = \ $(commands) \ ext-editheader.c \ ext-editheader-settings.c \ ext-editheader-common.c noinst_HEADERS = \ ext-editheader-limits.h \ ext-editheader-settings.h \ ext-editheader-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/Makefile.in0000644000175100001700000005600115100335630027267 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/editheader ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_editheader_la_LIBADD = am__objects_1 = cmd-addheader.lo cmd-deleteheader.lo am_libsieve_ext_editheader_la_OBJECTS = $(am__objects_1) \ ext-editheader.lo ext-editheader-settings.lo \ ext-editheader-common.lo libsieve_ext_editheader_la_OBJECTS = \ $(am_libsieve_ext_editheader_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-addheader.Plo \ ./$(DEPDIR)/cmd-deleteheader.Plo \ ./$(DEPDIR)/ext-editheader-common.Plo \ ./$(DEPDIR)/ext-editheader-settings.Plo \ ./$(DEPDIR)/ext-editheader.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_editheader_la_SOURCES) DIST_SOURCES = $(libsieve_ext_editheader_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_editheader.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-addheader.c \ cmd-deleteheader.c libsieve_ext_editheader_la_SOURCES = \ $(commands) \ ext-editheader.c \ ext-editheader-settings.c \ ext-editheader-common.c noinst_HEADERS = \ ext-editheader-limits.h \ ext-editheader-settings.h \ ext-editheader-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/editheader/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/editheader/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_editheader.la: $(libsieve_ext_editheader_la_OBJECTS) $(libsieve_ext_editheader_la_DEPENDENCIES) $(EXTRA_libsieve_ext_editheader_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_editheader_la_OBJECTS) $(libsieve_ext_editheader_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-addheader.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-deleteheader.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-editheader-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-editheader-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-editheader.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-addheader.Plo -rm -f ./$(DEPDIR)/cmd-deleteheader.Plo -rm -f ./$(DEPDIR)/ext-editheader-common.Plo -rm -f ./$(DEPDIR)/ext-editheader-settings.Plo -rm -f ./$(DEPDIR)/ext-editheader.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-addheader.Plo -rm -f ./$(DEPDIR)/cmd-deleteheader.Plo -rm -f ./$(DEPDIR)/ext-editheader-common.Plo -rm -f ./$(DEPDIR)/ext-editheader-settings.Plo -rm -f ./$(DEPDIR)/ext-editheader.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/cmd-deleteheader.c0000644000175100001700000003442015100335616030547 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "mail-storage.h" #include "rfc2822.h" #include "edit-mail.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-editheader-common.h" /* * Deleteheader command * * Syntax: * deleteheader [":index" [":last"]] * [COMPARATOR] [MATCH-TYPE] * [] */ static bool cmd_deleteheader_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_deleteheader_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_deleteheader_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def deleteheader_command = { .identifier = "deleteheader", .type = SCT_COMMAND, .positional_args = -1, /* We check positional arguments ourselves */ .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_deleteheader_registered, .validate = cmd_deleteheader_validate, .generate = cmd_deleteheader_generate, }; /* * Deleteheader command tags */ /* Forward declarations */ static bool cmd_deleteheader_validate_index_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool cmd_deleteheader_validate_last_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def deleteheader_index_tag = { .identifier = "index", .validate = cmd_deleteheader_validate_index_tag, }; static const struct sieve_argument_def deleteheader_last_tag = { .identifier = "last", .validate = cmd_deleteheader_validate_last_tag, }; /* Codes for optional arguments */ enum cmd_deleteheader_optional { OPT_INDEX = SIEVE_MATCH_OPT_LAST, OPT_LAST, }; /* * Deleteheader operation */ static bool cmd_deleteheader_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_deleteheader_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def deleteheader_operation = { .mnemonic = "DELETEHEADER", .ext_def = &editheader_extension, .code = EXT_EDITHEADER_OPERATION_DELETEHEADER, .dump = cmd_deleteheader_operation_dump, .execute = cmd_deleteheader_operation_execute, }; /* * Command registration */ static bool cmd_deleteheader_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag(valdtr, cmd_reg, ext, &deleteheader_index_tag, OPT_INDEX); sieve_validator_register_tag(valdtr, cmd_reg, ext, &deleteheader_last_tag, OPT_LAST); return TRUE; } /* * Command validation context */ struct cmd_deleteheader_context_data { struct sieve_ast_argument *arg_index; struct sieve_ast_argument *arg_last; }; /* * Tag validation */ static struct cmd_deleteheader_context_data * cmd_deleteheader_get_context (struct sieve_command *cmd) { struct cmd_deleteheader_context_data *ctx_data = (struct cmd_deleteheader_context_data *)cmd->data; if (ctx_data != NULL) return ctx_data; ctx_data = p_new(sieve_command_pool(cmd), struct cmd_deleteheader_context_data, 1); cmd->data = ctx_data; return ctx_data; } static bool cmd_deleteheader_validate_index_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_deleteheader_context_data *ctx_data; sieve_number_t index; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :index number */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_NUMBER, FALSE)) return FALSE; index = sieve_ast_argument_number(*arg); if (index > INT_MAX) { sieve_argument_validate_warning( valdtr, *arg, "the :%s tag for the %s %s has a parameter value '%llu' " "exceeding the maximum (%d)", sieve_argument_identifier(tag), sieve_command_identifier(cmd), sieve_command_type_name(cmd), (unsigned long long)index, INT_MAX); return FALSE; } ctx_data = cmd_deleteheader_get_context(cmd); ctx_data->arg_index = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool cmd_deleteheader_validate_last_tag(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct cmd_deleteheader_context_data *ctx_data; ctx_data = cmd_deleteheader_get_context(cmd); ctx_data->arg_last = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Validation */ static bool cmd_deleteheader_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_deleteheader_context_data *ctx_data = (struct cmd_deleteheader_context_data *)cmd->data; struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); if (ctx_data != NULL) { if (ctx_data->arg_last != NULL && ctx_data->arg_index == NULL) { sieve_argument_validate_error( valdtr, ctx_data->arg_last, "the :last tag for the %s %s cannot be specified " "without the :index tag", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); } } /* Field name argument */ if (arg == NULL) { sieve_command_validate_error( valdtr, cmd, "the %s %s expects at least one positional argument, " "but none was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } if (!sieve_validate_positional_argument(valdtr, cmd, arg, "field name", 1, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; if (sieve_argument_is_string_literal(arg)) { string_t *fname = sieve_ast_argument_str(arg); if (!rfc2822_header_field_name_verify(str_c(fname), str_len(fname))) { sieve_argument_validate_error( valdtr, arg, "deleteheader command:" "specified field name '%s' is invalid", str_sanitize(str_c(fname), 80)); return FALSE; } if (!ext_editheader_header_allow_delete( cmd->ext, str_c(fname))) { sieve_argument_validate_warning( valdtr, arg, "deleteheader command: " "deleting specified header field '%s' is forbidden; " "modification will be denied", str_sanitize(str_c(fname), 80)); } } /* Value patterns argument */ arg = sieve_ast_argument_next(arg); if (arg == NULL) { /* There is none; let's not generate code for useless match arguments */ sieve_match_type_arguments_remove(valdtr, cmd); return TRUE; } if (!sieve_validate_positional_argument( valdtr, cmd, arg, "value patterns", 2, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; /* Validate the value patterns to a specified match type */ return sieve_match_type_validate(valdtr, cmd, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool cmd_deleteheader_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &deleteheader_operation); /* Generate arguments */ if (!sieve_generate_arguments(cgenv, cmd, NULL)) return FALSE; /* Emit a placeholder when the value-patterns argument is missing */ if (sieve_ast_argument_next(cmd->first_positional) == NULL) sieve_opr_omitted_emit(cgenv->sblock); return TRUE; } /* * Code dump */ static bool cmd_deleteheader_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "DELETEHEADER"); sieve_code_descend(denv); /* Optional operands */ for (;;) { int opt; opt = sieve_match_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_INDEX: if (!sieve_opr_number_dump(denv, address, "index")) return FALSE; break; case OPT_LAST: sieve_code_dumpf(denv, "last"); break; default: return FALSE; } }; if (!sieve_opr_string_dump(denv, address, "field name")) return FALSE; return sieve_opr_stringlist_dump_ex( denv, address, "value patterns", ""); } /* * Code execution */ static int cmd_deleteheader_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; int opt_code = 0; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); string_t *field_name; struct sieve_stringlist *vpattern_list = NULL; struct edit_mail *edmail; sieve_number_t index_offset = 0; bool index_last = FALSE; bool trace = FALSE; int ret; /* * Read operands */ for (;;) { int opt; opt = sieve_match_opr_optional_read(renv, address, &opt_code, &ret, &cmp, &mcht); if (opt < 0) return ret; if (opt == 0) break; switch (opt_code) { case OPT_INDEX: ret = sieve_opr_number_read(renv, address, "index", &index_offset); if (ret <= 0) return ret; if (index_offset > INT_MAX) { sieve_runtime_trace_error( renv, "index is > %d", INT_MAX); return SIEVE_EXEC_BIN_CORRUPT; } break; case OPT_LAST: index_last = TRUE; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } /* Read field-name */ ret = sieve_opr_string_read(renv, address, "field-name", &field_name); if (ret <= 0) return ret; /* Read value-patterns */ ret = sieve_opr_stringlist_read_ex(renv, address, "value-patterns", TRUE, &vpattern_list); if (ret <= 0) return ret; /* * Verify arguments */ if (!rfc2822_header_field_name_verify(str_c(field_name), str_len(field_name))) { sieve_runtime_error( renv, NULL, "deleteheader action: " "specified field name '%s' is invalid", str_sanitize(str_c(field_name), 80)); return SIEVE_EXEC_FAILURE; } if (!ext_editheader_header_allow_delete(this_ext, str_c(field_name))) { sieve_runtime_warning( renv, NULL, "deleteheader action: " "deleting specified header field '%s' is forbidden; " "modification denied", str_sanitize(str_c(field_name), 80)); return SIEVE_EXEC_OK; } /* * Execute command */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "deleteheader command"); /* Start editing the mail */ edmail = sieve_message_edit(renv->msgctx); trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS); /* Either do string matching or just kill all/indexed notify action(s) */ if (vpattern_list != NULL) { struct edit_mail_header_iter *edhiter; struct sieve_match_context *mctx; if (trace) { sieve_runtime_trace_descend(renv); if (index_offset != 0) { sieve_runtime_trace( renv, 0, "deleting matching occurrences of header '%s' at index %llu%s", str_c(field_name), (unsigned long long)index_offset, (index_last ? " from last": "")); } else { sieve_runtime_trace( renv, 0, "deleting matching occurrences of header '%s'", str_c(field_name)); } } /* Iterate through all headers and delete those that match */ ret = edit_mail_headers_iterate_init(edmail, str_c(field_name), index_last, &edhiter); if (ret > 0) { int mret = 0; sieve_number_t pos = 0; /* Initialize match */ mctx = sieve_match_begin(renv, &mcht, &cmp); /* Match */ for (;;) { pos++; /* Check index if any */ if (index_offset == 0 || pos == index_offset) { const char *value; int match; /* Match value against all value patterns */ edit_mail_headers_iterate_get(edhiter, &value); match = sieve_match_value( mctx, value, strlen(value), vpattern_list); if (match < 0) break; if (match > 0) { /* Remove it and iterate to next */ sieve_runtime_trace( renv, 0, "deleting header with value '%s'", value); if (!edit_mail_headers_iterate_remove(edhiter)) break; continue; } } if (!edit_mail_headers_iterate_next(edhiter)) break; } /* Finish match */ mret = sieve_match_end(&mctx, &ret); edit_mail_headers_iterate_deinit(&edhiter); if (mret < 0) return ret; } if (ret == 0) { sieve_runtime_trace(renv, 0, "header '%s' not found", str_c(field_name)); } else if (ret < 0) { sieve_runtime_warning( renv, NULL, "deleteheader action: " "failed to delete occurrences of header '%s' " "(this should not happen!)", str_c(field_name)); } } else { int index = (index_last ? -((int)index_offset) : ((int)index_offset)); if (trace) { sieve_runtime_trace_descend(renv); if (index_offset != 0) { sieve_runtime_trace( renv, 0, "deleting header '%s' at index %llu%s", str_c(field_name), (unsigned long long)index_offset, (index_last ? " from last": "")); } else { sieve_runtime_trace( renv, 0, "deleting header '%s'", str_c(field_name)); } } /* Delete all occurrences of header */ ret = edit_mail_header_delete(edmail, str_c(field_name), index); if (ret < 0) { sieve_runtime_warning( renv, NULL, "deleteheader action: " "failed to delete occurrences of header '%s' " "(this should not happen!)", str_c(field_name)); } else if (trace) { sieve_runtime_trace( renv, 0, "deleted %d occurrences of header '%s'", ret, str_c(field_name)); } } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/ext-editheader-settings.c0000644000175100001700000000636115100335616032130 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "rfc2822.h" #include "ext-editheader-limits.h" #include "ext-editheader-settings.h" static bool ext_editheader_header_settings_check(void *_set, pool_t pool, const char **error_r); static bool ext_editheader_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_editheader_header_"#name, name, \ struct ext_editheader_header_settings) static const struct setting_define ext_editheader_header_setting_defines[] = { DEF(STR, name), DEF(BOOL, forbid_add), DEF(BOOL, forbid_delete), SETTING_DEFINE_LIST_END, }; static const struct ext_editheader_header_settings ext_editheader_header_default_settings = { .name = "", .forbid_add = FALSE, .forbid_delete = FALSE, }; const struct setting_parser_info ext_editheader_header_setting_parser_info = { .name = "sieve_editheader_header", .defines = ext_editheader_header_setting_defines, .defaults = &ext_editheader_header_default_settings, .struct_size = sizeof(struct ext_editheader_header_settings), .check_func = ext_editheader_header_settings_check, .pool_offset1 = 1 + offsetof(struct ext_editheader_header_settings, pool), }; #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_editheader_"#name, name, \ struct ext_editheader_settings) static const struct setting_define ext_editheader_setting_defines[] = { DEF(SIZE, max_header_size), { .type = SET_FILTER_ARRAY, .key = "sieve_editheader_header", .filter_array_field_name = "sieve_editheader_header_name", .offset = offsetof(struct ext_editheader_settings, headers), }, SETTING_DEFINE_LIST_END, }; static const struct ext_editheader_settings ext_editheader_default_settings = { .max_header_size = EXT_EDITHEADER_DEFAULT_MAX_HEADER_SIZE, .headers = ARRAY_INIT, }; const struct setting_parser_info ext_editheader_setting_parser_info = { .name = "sieve_editheader", .defines = ext_editheader_setting_defines, .defaults = &ext_editheader_default_settings, .struct_size = sizeof(struct ext_editheader_settings), .check_func = ext_editheader_settings_check, .pool_offset1 = 1 + offsetof(struct ext_editheader_settings, pool), }; /* */ static bool ext_editheader_header_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct ext_editheader_header_settings *set = _set; if (!rfc2822_header_field_name_verify(set->name, strlen(set->name))) { *error_r = t_strdup_printf( "sieve_editheader_header_name: " "Invalid header field name '%s'", set->name); return FALSE; } return TRUE; } static bool ext_editheader_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct ext_editheader_settings *set = _set; if (set->max_header_size < EXT_EDITHEADER_MINIMUM_MAX_HEADER_SIZE) { *error_r = t_strdup_printf( "sieve_editheader_max_header_size: " "Value (=%"PRIuUOFF_T") is less than the minimum " "(=%"PRIuUOFF_T") ", set->max_header_size, (size_t)EXT_EDITHEADER_MINIMUM_MAX_HEADER_SIZE); return FALSE; } return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/cmd-addheader.c0000644000175100001700000001751615100335616030044 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "mail-storage.h" #include "rfc2822.h" #include "edit-mail.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-editheader-common.h" /* * Addheader command * * Syntax * "addheader" [":last"] */ static bool cmd_addheader_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_addheader_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool cmd_addheader_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def addheader_command = { .identifier = "addheader", .type = SCT_COMMAND, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_addheader_registered, .validate = cmd_addheader_validate, .generate = cmd_addheader_generate }; /* * Addheader command tags */ /* Argument objects */ static const struct sieve_argument_def addheader_last_tag = { .identifier = "last", }; /* Codes for optional arguments */ enum cmd_addheader_optional { OPT_END, OPT_LAST, }; /* * Addheader operation */ static bool cmd_addheader_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_addheader_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def addheader_operation = { .mnemonic = "ADDHEADER", .ext_def = &editheader_extension, .code = EXT_EDITHEADER_OPERATION_ADDHEADER, .dump = cmd_addheader_operation_dump, .execute = cmd_addheader_operation_execute, }; /* * Utility */ static bool _str_contains_nul(const string_t *str) { const unsigned char *p, *pend; p = str_data(str); pend = p + str_len(str); while (p < pend) { if (*p == '\0') return TRUE; p++; } return FALSE; } /* * Validation */ static bool cmd_addheader_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; /* Check field-name syntax */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "field-name", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; if (sieve_argument_is_string_literal(arg)) { string_t *fname = sieve_ast_argument_str(arg); if (!rfc2822_header_field_name_verify(str_c(fname), str_len(fname))) { sieve_argument_validate_error( valdtr, arg, "addheader command: " "specified field name '%s' is invalid", str_sanitize(str_c(fname), 80)); return FALSE; } if (!ext_editheader_header_allow_add(cmd->ext, str_c(fname))) { sieve_argument_validate_warning( valdtr, arg, "addheader command: " "adding specified header field '%s' is forbidden; " "modification will be denied", str_sanitize(str_c(fname), 80)); } } /* Check value syntax */ arg = sieve_ast_argument_next(arg); if (!sieve_validate_positional_argument(valdtr, cmd, arg, "value", 2, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; if (sieve_argument_is_string_literal(arg)) { string_t *fvalue = sieve_ast_argument_str(arg); if (_str_contains_nul(fvalue)) { sieve_argument_validate_error( valdtr, arg, "addheader command: specified value '%s' is invalid " "(contains NUL character)", str_sanitize(str_c(fvalue), 80)); return FALSE; } if (!rfc2822_header_field_body_verify(str_c( fvalue), str_len(fvalue), TRUE, TRUE)) { sieve_argument_validate_warning( valdtr, arg, "addheader command: specified value '%s' is invalid", str_sanitize(str_c(fvalue), 80)); } if (ext_editheader_header_too_large( cmd->ext, str_len(fvalue))) { sieve_argument_validate_error( valdtr, arg, "addheader command: " "specified header value '%s' is too large (%zu bytes)", str_sanitize(str_c(fvalue), 80), str_len(fvalue)); return SIEVE_EXEC_FAILURE; } } return TRUE; } /* * Command registration */ static bool cmd_addheader_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, &addheader_last_tag, OPT_LAST); return TRUE; } /* * Code generation */ static bool cmd_addheader_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &addheader_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_addheader_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "addheader"); sieve_code_descend(denv); /* Dump optional operands */ for (;;) { int opt; opt = sieve_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; if (opt_code == OPT_LAST) sieve_code_dumpf(denv, "last"); else return FALSE; } return (sieve_opr_string_dump(denv, address, "field-name") && sieve_opr_string_dump(denv, address, "value")); } /* * Interpretation */ static int cmd_addheader_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; string_t *field_name; string_t *value; struct edit_mail *edmail; bool last = FALSE; int opt_code = 0; int ret; /* * Read operands */ /* Optional operands */ for (;;) { int opt; opt = sieve_opr_optional_read(renv, address, &opt_code); if (opt < 0) return SIEVE_EXEC_BIN_CORRUPT; if (opt == 0) break; switch (opt_code) { case OPT_LAST: last = TRUE; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } /* Read message */ ret = sieve_opr_string_read(renv, address, "field-name", &field_name); if (ret <= 0) return ret; ret = sieve_opr_string_read(renv, address, "value", &value); if (ret <= 0) return ret; /* * Verify arguments */ if (!rfc2822_header_field_name_verify(str_c(field_name), str_len(field_name))) { sieve_runtime_error( renv, NULL, "addheader action: " "specified field name '%s' is invalid", str_sanitize(str_c(field_name), 80)); return SIEVE_EXEC_FAILURE; } if (!ext_editheader_header_allow_add(this_ext, str_c(field_name))) { sieve_runtime_warning( renv, NULL, "addheader action: " "adding specified header field '%s' is forbidden; " "modification denied", str_sanitize(str_c(field_name), 80)); return SIEVE_EXEC_OK; } if (_str_contains_nul(value)) { sieve_runtime_error( renv, NULL, "addheader action: " "specified value '%s' is invalid (contains NUL character)", str_sanitize(str_c(value), 80)); return SIEVE_EXEC_FAILURE; } if (ext_editheader_header_too_large(this_ext, str_len(value))) { sieve_runtime_error( renv, NULL, "addheader action: " "specified header value '%s' is too large (%zu bytes)", str_sanitize(str_c(value), 80), str_len(value)); return SIEVE_EXEC_FAILURE; } /* * Perform operation */ sieve_runtime_trace( renv, SIEVE_TRLVL_COMMANDS, "addheader \"%s: %s\"", str_sanitize(str_c(field_name), 80), str_sanitize(str_c(value), 80)); edmail = sieve_message_edit(renv->msgctx); edit_mail_header_add( edmail, rfc2822_header_field_name_sanitize(str_c(field_name)), str_c(value), last); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/ext-editheader-settings.h0000644000175100001700000000072115100335616032127 0ustar00buildbotbuildbot00000000000000#ifndef EXT_EDITHEADER_SETTINGS_H #define EXT_EDITHEADER_SETTINGS_H struct ext_editheader_header_settings { pool_t pool; const char *name; bool forbid_add; bool forbid_delete; }; struct ext_editheader_settings { pool_t pool; uoff_t max_header_size; ARRAY_TYPE(const_string) headers; }; extern const struct setting_parser_info ext_editheader_header_setting_parser_info; extern const struct setting_parser_info ext_editheader_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/ext-editheader-common.h0000644000175100001700000000201715100335616031557 0ustar00buildbotbuildbot00000000000000#ifndef EXT_EDITHEADER_COMMON_H #define EXT_EDITHEADER_COMMON_H /* * Commands */ extern const struct sieve_command_def addheader_command; extern const struct sieve_command_def deleteheader_command; /* * Operations */ enum ext_imap4flags_opcode { EXT_EDITHEADER_OPERATION_ADDHEADER, EXT_EDITHEADER_OPERATION_DELETEHEADER, }; extern const struct sieve_operation_def addheader_operation; extern const struct sieve_operation_def deleteheader_operation; /* * Extension */ extern const struct sieve_extension_def editheader_extension; int ext_editheader_load(const struct sieve_extension *ext, void **context_r); void ext_editheader_unload(const struct sieve_extension *ext); /* * Protected headers */ bool ext_editheader_header_allow_add(const struct sieve_extension *ext, const char *hname); bool ext_editheader_header_allow_delete(const struct sieve_extension *ext, const char *hname); /* * Limits */ bool ext_editheader_header_too_large(const struct sieve_extension *ext, size_t size); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/editheader/ext-editheader-common.c0000644000175100001700000001047215100335616031556 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mempool.h" #include "array.h" #include "settings.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "ext-editheader-limits.h" #include "ext-editheader-settings.h" #include "ext-editheader-common.h" /* * Extension configuration */ struct ext_editheader_header { const char *name; bool forbid_add:1; bool forbid_delete:1; }; struct ext_editheader_context { pool_t pool; const struct ext_editheader_settings *set; ARRAY(struct ext_editheader_header) headers; size_t max_header_size; }; static const struct ext_editheader_header * ext_editheader_header_find(struct ext_editheader_context *extctx, const char *hname) { const struct ext_editheader_header *header; if (extctx == NULL) return NULL; array_foreach(&extctx->headers, header) { if (strcasecmp(hname, header->name) == 0) return header; } return NULL; } static int ext_editheader_header_add(struct sieve_instance *svinst, struct ext_editheader_context *extctx, const char *hname) { struct ext_editheader_header *header; const struct ext_editheader_header_settings *set; const char *error; if (settings_get_filter(svinst->event, "sieve_editheader_header", hname, &ext_editheader_header_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } i_assert(ext_editheader_header_find(extctx, set->name) == NULL); header = array_append_space(&extctx->headers); header->name = p_strdup(extctx->pool, set->name); header->forbid_add = set->forbid_add; header->forbid_delete = set->forbid_delete; settings_free(set); return 0; } static int ext_editheader_config_headers(struct sieve_instance *svinst, struct ext_editheader_context *extctx) { const char *hname; if (!array_is_created(&extctx->set->headers)) return 0; array_foreach_elem(&extctx->set->headers, hname) { if (ext_editheader_header_add(svinst, extctx, hname) < 0) return -1; } return 0; } int ext_editheader_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct ext_editheader_settings *set; struct ext_editheader_context *extctx; const char *error; pool_t pool; if (settings_get(svinst->event, &ext_editheader_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } pool = pool_alloconly_create("editheader_config", 1024); extctx = p_new(pool, struct ext_editheader_context, 1); extctx->pool = pool; extctx->set = set; p_array_init(&extctx->headers, pool, 16); if (ext_editheader_config_headers(svinst, extctx) < 0) { settings_free(set); pool_unref(&pool); return -1; } *context_r = extctx; return 0; } void ext_editheader_unload(const struct sieve_extension *ext) { struct ext_editheader_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); pool_unref(&extctx->pool); } /* * Protected headers */ bool ext_editheader_header_allow_add(const struct sieve_extension *ext, const char *hname) { struct ext_editheader_context *extctx = ext->context; const struct ext_editheader_header *header; if (strcasecmp(hname, "subject") == 0) return TRUE; if (strcasecmp(hname, "x-sieve-redirected-from") == 0) return FALSE; header = ext_editheader_header_find(extctx, hname); if (header == NULL) return TRUE; return !header->forbid_add; } bool ext_editheader_header_allow_delete(const struct sieve_extension *ext, const char *hname) { struct ext_editheader_context *extctx = ext->context; const struct ext_editheader_header *header; if (strcasecmp(hname, "received") == 0 || strcasecmp(hname, "auto-submitted") == 0) return FALSE; if (strcasecmp(hname, "x-sieve-redirected-from") == 0) return FALSE; if (strcasecmp(hname, "subject") == 0) return TRUE; header = ext_editheader_header_find(extctx, hname); if (header == NULL) return TRUE; return !header->forbid_delete; } /* * Limits */ bool ext_editheader_header_too_large(const struct sieve_extension *ext, size_t size) { struct ext_editheader_context *extctx = ext->context; if (extctx == NULL) return size > EXT_EDITHEADER_DEFAULT_MAX_HEADER_SIZE; return (size > extctx->set->max_header_size); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/0000755000175100001700000000000015100335670025340 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/Makefile.am0000644000175100001700000000054115100335616027374 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_special_use.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tags = \ tag-specialuse.c tests = \ tst-specialuse-exists.c libsieve_ext_special_use_la_SOURCES = \ $(tags) \ $(tests) \ ext-special-use-common.c \ ext-special-use.c headers = \ ext-special-use-common.h noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/ext-special-use.c0000644000175100001700000000267515100335616030526 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2019 Pigeonhole authors, see the included COPYING file */ /* Extension special-use * --------------------- * * Authors: Stephan Bosch * Specification: RFC 8579 * Implementation: full * Status: testing * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "ext-special-use-common.h" /* * Extension */ static bool ext_special_use_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def special_use_extension = { .name = "special-use", .validator_load = ext_special_use_validator_load, SIEVE_EXT_DEFINE_OPERATION(specialuse_exists_operation), SIEVE_EXT_DEFINE_OPERAND(specialuse_operand) }; static bool ext_special_use_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register :specialuse tag with fileinto command and we don't care whether this command is registered or even whether it will be registered at all. The validator handles either situation gracefully. */ sieve_validator_register_external_tag( valdtr, "fileinto", ext, &specialuse_tag, SIEVE_OPT_SIDE_EFFECT); /* Register new test */ sieve_validator_register_command(valdtr, ext, &specialuse_exists_test); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/tst-specialuse-exists.c0000644000175100001700000003114415100335616031771 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2019 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-actions.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-special-use-common.h" /* * specialuse_exists command * * Syntax: * specialuse_exists [] * */ static bool tst_specialuse_exists_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_specialuse_exists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def specialuse_exists_test = { .identifier = "specialuse_exists", .type = SCT_TEST, .positional_args = -1, /* We check positional arguments ourselves */ .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_specialuse_exists_validate, .generate = tst_specialuse_exists_generate, }; /* * Mailboxexists operation */ static bool tst_specialuse_exists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_specialuse_exists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def specialuse_exists_operation = { .mnemonic = "SPECIALUSE_EXISTS", .ext_def = &special_use_extension, .dump = tst_specialuse_exists_operation_dump, .execute = tst_specialuse_exists_operation_execute, }; /* * Test validation */ struct _validate_context { struct sieve_validator *valdtr; struct sieve_command *tst; }; static int tst_specialuse_exists_flag_validate(void *context, struct sieve_ast_argument *arg) { struct _validate_context *valctx = (struct _validate_context *)context; if (sieve_argument_is_string_literal(arg)) { const char *flag = sieve_ast_argument_strc(arg); if (!ext_special_use_flag_valid(flag)) { sieve_argument_validate_error( valctx->valdtr, arg, "%s test: " "invalid special-use flag '%s' specified", sieve_command_identifier(valctx->tst), str_sanitize(flag, 64)); } } return 1; } static bool tst_specialuse_exists_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *arg2; struct sieve_ast_argument *aarg; struct _validate_context valctx; if (arg == NULL) { sieve_command_validate_error( valdtr, tst, "the %s %s expects at least one argument, " "but none was found", sieve_command_identifier(tst), sieve_command_type_name(tst)); return FALSE; } if (sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST) { sieve_argument_validate_error( valdtr, arg, "the %s %s expects either a string (mailbox) or " "a string-list (special-use flags) as first argument, " "but %s was found", sieve_command_identifier(tst), sieve_command_type_name(tst), sieve_ast_argument_name(arg)); return FALSE; } arg2 = sieve_ast_argument_next(arg); if (arg2 != NULL) { /* First, check syntax sanity */ if (sieve_ast_argument_type(arg) != SAAT_STRING) { sieve_argument_validate_error( valdtr, arg, "if a second argument is specified for the %s %s, " "the first must be a string (mailbox), " "but %s was found", sieve_command_identifier(tst), sieve_command_type_name(tst), sieve_ast_argument_name(arg)); return FALSE; } if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Check name validity when mailbox argument is not a variable */ if (sieve_argument_is_string_literal(arg)) { const char *mailbox = sieve_ast_argument_strc(arg); const char *error; if (!sieve_mailbox_check_name(mailbox, &error)) { sieve_argument_validate_warning( valdtr, arg, "%s test: " "invalid mailbox name '%s' specified: %s", sieve_command_identifier(tst), str_sanitize(mailbox, 256), error); } } if (sieve_ast_argument_type(arg2) != SAAT_STRING && sieve_ast_argument_type(arg2) != SAAT_STRING_LIST) { sieve_argument_validate_error( valdtr, arg2, "the %s %s expects a string list (special-use flags) as " "second argument when two arguments are specified, " "but %s was found", sieve_command_identifier(tst), sieve_command_type_name(tst), sieve_ast_argument_name(arg2)); return FALSE; } } else arg2 = arg; if (!sieve_validator_argument_activate(valdtr, tst, arg2, FALSE)) return FALSE; aarg = arg2; i_zero(&valctx); valctx.valdtr = valdtr; valctx.tst = tst; return (sieve_ast_stringlist_map( &aarg, &valctx, tst_specialuse_exists_flag_validate) >= 0); } /* * Test generation */ static bool tst_specialuse_exists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *arg2; sieve_operation_emit(cgenv->sblock, tst->ext, &specialuse_exists_operation); /* Generate arguments */ arg2 = sieve_ast_argument_next(arg); if (arg2 != NULL) { if (!sieve_generate_argument(cgenv, arg, tst)) return FALSE; } else { sieve_opr_omitted_emit(cgenv->sblock); arg2 = arg; } return sieve_generate_argument(cgenv, arg2, tst); } /* * Code dump */ static bool tst_specialuse_exists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct sieve_operand oprnd; sieve_code_dumpf(denv, "SPECIALUSE_EXISTS"); sieve_code_descend(denv); sieve_code_mark(denv); if (!sieve_operand_read(denv->sblock, address, NULL, &oprnd)) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } if (!sieve_operand_is_omitted(&oprnd)) { return (sieve_opr_string_dump_data(denv, &oprnd, address, "mailbox") && sieve_opr_stringlist_dump(denv, address, "special-use-flags")); } return sieve_opr_stringlist_dump(denv, address, "special-use-flags"); } /* * Code execution */ static int tst_specialuse_find_mailbox(const struct sieve_runtime_env *renv, const char *mailbox, struct mailbox **box_r) { const struct sieve_execute_env *eenv = renv->exec_env; struct mail_user *user = eenv->scriptenv->user; struct mailbox *box; bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); enum mail_error error_code; const char *error; *box_r = NULL; if (user == NULL) return 0; /* Open the box */ box = mailbox_alloc_for_user(user, mailbox, MAILBOX_FLAG_POST_SESSION); if (mailbox_open(box) < 0) { error = mailbox_get_last_internal_error(box, &error_code); if (trace) { sieve_runtime_trace( renv, 0, "mailbox '%s' cannot be opened: %s", str_sanitize(mailbox, 256), error); } mailbox_free(&box); if (error_code == MAIL_ERROR_TEMP) { sieve_runtime_error( renv, NULL, "specialuse_exists test: " "failed to open mailbox '%s': %s", str_sanitize(mailbox, 256), error); return -1; } return 0; } /* Also fail when it is readonly */ if (mailbox_is_readonly(box)) { if (trace) { sieve_runtime_trace( renv, 0, "mailbox '%s' is read-only", str_sanitize(mailbox, 256)); } mailbox_free(&box); return 0; } *box_r = box; return 1; } static int tst_specialuse_find_specialuse(const struct sieve_runtime_env *renv, const char *special_use) { const struct sieve_execute_env *eenv = renv->exec_env; struct mail_user *user = eenv->scriptenv->user; struct mailbox *box; bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); enum mail_error error_code; const char *error; if (user == NULL) return 0; /* Open the box */ box = mailbox_alloc_for_user(user, special_use, (MAILBOX_FLAG_POST_SESSION | MAILBOX_FLAG_SPECIAL_USE)); if (mailbox_open(box) < 0) { error = mailbox_get_last_internal_error(box, &error_code); if (trace) { sieve_runtime_trace( renv, 0, "mailbox with special-use flag '%s' " "cannot be opened: %s", str_sanitize(special_use, 64), error); } mailbox_free(&box); if (error_code == MAIL_ERROR_TEMP) { sieve_runtime_error( renv, NULL, "specialuse_exists test: " "failed to open mailbox with special-use flag'%s': %s", str_sanitize(special_use, 64), error); return -1; } return 0; } /* Also fail when it is readonly */ if (mailbox_is_readonly(box)) { if (trace) { sieve_runtime_trace( renv, 0, "mailbox with special-use flag '%s' is read-only", str_sanitize(special_use, 64)); } mailbox_free(&box); return 0; } mailbox_free(&box); return 1; } static int tst_specialuse_exists_check_flag(const struct sieve_runtime_env *renv, struct mailbox *box, const char *use_flag, bool trace, bool *all_exist_r) { int ret; if (!ext_special_use_flag_valid(use_flag)) { sieve_runtime_error( renv, NULL, "specialuse_exists test: " "invalid special-use flag '%s' specified", str_sanitize(use_flag, 64)); return SIEVE_EXEC_FAILURE; } if (box != NULL) { /* Mailbox has this SPECIAL-USE flag? */ if (!mailbox_has_special_use(box, use_flag)) { *all_exist_r = FALSE; return SIEVE_EXEC_OK; } } else { /* Is there mailbox with this SPECIAL-USE flag? */ ret = tst_specialuse_find_specialuse(renv, use_flag); if (ret < 0) return SIEVE_EXEC_TEMP_FAILURE; if (ret == 0) { *all_exist_r = FALSE; return SIEVE_EXEC_OK; } } if (trace) { sieve_runtime_trace( renv, 0, "special-use flag '%s' exists", str_sanitize(use_flag, 80)); } return SIEVE_EXEC_OK; } static int tst_specialuse_exists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_operand oprnd; struct sieve_stringlist *special_use_flags; string_t *mailbox, *special_use_flag; struct mailbox *box = NULL; const char *error; bool trace = FALSE, all_exist = TRUE; int ret; /* * Read operands */ /* Read bare operand (two types possible) */ ret = sieve_operand_runtime_read(renv, address, NULL, &oprnd); if (ret <= 0) return ret; /* Mailbox operand (optional) */ mailbox = NULL; if (!sieve_operand_is_omitted(&oprnd)) { /* Read the mailbox operand */ ret = sieve_opr_string_read_data(renv, &oprnd, address, "mailbox", &mailbox); if (ret <= 0) return ret; /* Read flag list */ ret = sieve_opr_stringlist_read(renv, address, "special-use-flags", &special_use_flags); if (ret <= 0) return ret; /* Flag-list operand */ } else { /* Read flag list */ ret = sieve_opr_stringlist_read(renv, address, "special-use-flags", &special_use_flags); if (ret <= 0) return ret; } /* * Perform operation */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS)) { sieve_runtime_trace(renv, 0, "specialuse_exists test"); sieve_runtime_trace_descend(renv); trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); } if (mailbox != NULL) { if (!sieve_mailbox_check_name(str_c(mailbox), &error)) { sieve_runtime_warning( renv, NULL, "specialuse_exists test: " "invalid mailbox name '%s' specified: %s", str_sanitize(str_c(mailbox), 256), error); sieve_interpreter_set_test_result(renv->interp, FALSE); return SIEVE_EXEC_OK; } if (tst_specialuse_find_mailbox(renv, str_c(mailbox), &box) < 0) return SIEVE_EXEC_TEMP_FAILURE; } if (box == NULL && mailbox != NULL) { sieve_runtime_trace( renv, 0, "mailbox '%s' is not accessible", str_sanitize(str_c(mailbox), 80)); sieve_interpreter_set_test_result(renv->interp, FALSE); return SIEVE_EXEC_OK; } if (mailbox != NULL) { sieve_runtime_trace( renv, 0, "mailbox '%s' is accessible", str_sanitize(str_c(mailbox), 80)); } ret = 0; special_use_flag = NULL; while (all_exist && (ret = sieve_stringlist_next_item( special_use_flags, &special_use_flag)) > 0) { const char *use_flag = str_c(special_use_flag); ret = tst_specialuse_exists_check_flag( renv, box, use_flag, trace, &all_exist); if (ret <= 0) { if (box != NULL) { /* Close mailbox */ mailbox_free(&box); } return ret; } } if (box != NULL) { /* Close mailbox */ mailbox_free(&box); } if (ret < 0) { sieve_runtime_trace_error( renv, "invalid special-use flag item"); return SIEVE_EXEC_BIN_CORRUPT; } if (trace) { if (all_exist) { sieve_runtime_trace( renv, 0, "all special-use flags are set"); } else { sieve_runtime_trace( renv, 0, "some special-use are not set"); } } sieve_interpreter_set_test_result(renv->interp, all_exist); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/Makefile.in0000644000175100001700000005537615100335630027421 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/special-use ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_special_use_la_LIBADD = am__objects_1 = tag-specialuse.lo am__objects_2 = tst-specialuse-exists.lo am_libsieve_ext_special_use_la_OBJECTS = $(am__objects_1) \ $(am__objects_2) ext-special-use-common.lo ext-special-use.lo libsieve_ext_special_use_la_OBJECTS = \ $(am_libsieve_ext_special_use_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-special-use-common.Plo \ ./$(DEPDIR)/ext-special-use.Plo ./$(DEPDIR)/tag-specialuse.Plo \ ./$(DEPDIR)/tst-specialuse-exists.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_special_use_la_SOURCES) DIST_SOURCES = $(libsieve_ext_special_use_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_special_use.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tags = \ tag-specialuse.c tests = \ tst-specialuse-exists.c libsieve_ext_special_use_la_SOURCES = \ $(tags) \ $(tests) \ ext-special-use-common.c \ ext-special-use.c headers = \ ext-special-use-common.h noinst_HEADERS = $(headers) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/special-use/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/special-use/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_special_use.la: $(libsieve_ext_special_use_la_OBJECTS) $(libsieve_ext_special_use_la_DEPENDENCIES) $(EXTRA_libsieve_ext_special_use_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_special_use_la_OBJECTS) $(libsieve_ext_special_use_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-special-use-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-special-use.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-specialuse.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-specialuse-exists.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-special-use-common.Plo -rm -f ./$(DEPDIR)/ext-special-use.Plo -rm -f ./$(DEPDIR)/tag-specialuse.Plo -rm -f ./$(DEPDIR)/tst-specialuse-exists.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-special-use-common.Plo -rm -f ./$(DEPDIR)/ext-special-use.Plo -rm -f ./$(DEPDIR)/tag-specialuse.Plo -rm -f ./$(DEPDIR)/tst-specialuse-exists.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/ext-special-use-common.c0000644000175100001700000000110615100335616032000 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2019 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "imap-arg.h" #include "ext-special-use-common.h" bool ext_special_use_flag_valid(const char *flag) { const char *p = flag; /* RFC 6154, Section 6: use-attr = "\All" / "\Archive" / "\Drafts" / "\Flagged" / "\Junk" / "\Sent" / "\Trash" / use-attr-ext use-attr-ext = "\" atom */ /* "\" */ if (*p != '\\') return FALSE; p++; /* atom */ for (; *p != '\0'; p++) { if (!IS_ATOM_CHAR(*p)) return FALSE; } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/ext-special-use-common.h0000644000175100001700000000117115100335616032007 0ustar00buildbotbuildbot00000000000000#ifndef EXT_SPECIAL_USE_COMMON_H #define EXT_SPECIAL_USE_COMMON_H #include "sieve-common.h" /* * Tagged arguments */ extern const struct sieve_argument_def specialuse_tag; /* * Commands */ extern const struct sieve_command_def specialuse_exists_test; /* * Operands */ extern const struct sieve_operand_def specialuse_operand; /* * Operations */ extern const struct sieve_operation_def specialuse_exists_operation; /* * Extension */ extern const struct sieve_extension_def special_use_extension; /* * Flag checking */ bool ext_special_use_flag_valid(const char *flag); #endif /* EXT_SPECIAL_USE_COMMON_H */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/special-use/tag-specialuse.c0000644000175100001700000002016215100335616030413 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2019 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-code.h" #include "sieve-actions.h" #include "sieve-result.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-special-use-common.h" /* * Flags tagged argument */ static bool tag_specialuse_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_specialuse_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); const struct sieve_argument_def specialuse_tag = { .identifier = "specialuse", .validate = tag_specialuse_validate, .generate = tag_specialuse_generate, }; /* * Side effect */ static bool seff_specialuse_dump_context(const struct sieve_side_effect *seffect, const struct sieve_dumptime_env *denv, sieve_size_t *address); static int seff_specialuse_read_context(const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **context); static int seff_specialuse_merge(const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_side_effect *old_seffect, const struct sieve_side_effect *new_seffect, void **old_context); static void seff_specialuse_print(const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int seff_specialuse_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context ATTR_UNUSED); const struct sieve_side_effect_def specialuse_side_effect = { SIEVE_OBJECT("specialuse", &specialuse_operand, 0), .precedence = 200, .to_action = &act_store, .dump_context = seff_specialuse_dump_context, .read_context = seff_specialuse_read_context, .merge = seff_specialuse_merge, .print = seff_specialuse_print, .pre_execute = seff_specialuse_pre_execute, }; /* * Operand */ static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(specialuse_side_effect); const struct sieve_operand_def specialuse_operand = { .name = "specialuse operand", .ext_def = &special_use_extension, .class = &sieve_side_effect_operand_class, .interface = &ext_side_effects, }; /* * Tag validation */ static bool tag_specialuse_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_argument_next(*arg); /* Check syntax: * :specialuse */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE)) return FALSE; if (sieve_argument_is_string_literal(*arg)) { const char *use_flag = sieve_ast_argument_strc(*arg); if (!ext_special_use_flag_valid(use_flag)) { sieve_argument_validate_error( valdtr, *arg, "specialuse tag: " "invalid special-use flag '%s' specified", str_sanitize(use_flag, 64)); return FALSE; } } tag->parameters = *arg; /* Detach parameter */ *arg = sieve_ast_arguments_detach(*arg,1); return TRUE; } /* * Code generation */ static bool tag_specialuse_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { struct sieve_ast_argument *param; if (sieve_ast_argument_type(arg) != SAAT_TAG) return FALSE; sieve_opr_side_effect_emit(cgenv->sblock, arg->argument->ext, &specialuse_side_effect); /* Explicit :specialuse tag */ param = arg->parameters; /* Call the generation function for the argument */ if (param->argument != NULL && param->argument->def != NULL && param->argument->def->generate != NULL && !param->argument->def->generate(cgenv, param, cmd)) return FALSE; return TRUE; } /* * Side effect implementation */ /* Context data */ struct seff_specialuse_context { const char *special_use_flag; }; /* Context coding */ static bool seff_specialuse_dump_context( const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { return sieve_opr_stringlist_dump(denv, address, "specialuse"); } static int seff_specialuse_read_context( const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { pool_t pool = sieve_result_pool(renv->result); struct seff_specialuse_context *ctx; string_t *special_use_flag; const char *use_flag; int ret; if ((ret = sieve_opr_string_read(renv, address, "specialuse", &special_use_flag)) <= 0) return ret; use_flag = str_c(special_use_flag); if (!ext_special_use_flag_valid(use_flag)) { sieve_runtime_error( renv, NULL, "specialuse tag: " "invalid special-use flag '%s' specified", str_sanitize(use_flag, 64)); return SIEVE_EXEC_FAILURE; } ctx = p_new(pool, struct seff_specialuse_context, 1); ctx->special_use_flag = p_strdup(pool, use_flag); *se_context = ctx; return SIEVE_EXEC_OK; } /* Result verification */ static int seff_specialuse_merge(const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, const struct sieve_side_effect *old_seffect ATTR_UNUSED, const struct sieve_side_effect *new_seffect, void **old_context) { if (new_seffect != NULL) *old_context = new_seffect->context; return 1; } /* Result printing */ static void seff_specialuse_print(const struct sieve_side_effect *seffect, const struct sieve_action *action ATTR_UNUSED, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { struct seff_specialuse_context *ctx = (struct seff_specialuse_context *)seffect->context; sieve_result_seffect_printf( rpenv, "use mailbox with special-use flag '%s' instead if accessible", ctx->special_use_flag); } /* Result execution */ static int seff_specialuse_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context ATTR_UNUSED) { struct seff_specialuse_context *ctx = (struct seff_specialuse_context *)seffect->context; const struct sieve_execute_env *eenv = aenv->exec_env; struct act_store_transaction *trans = (struct act_store_transaction *)tr_context; struct mailbox *box; if (trans->box == NULL || trans->disabled) return SIEVE_EXEC_OK; /* Check whether something already failed */ switch (trans->error_code) { case MAIL_ERROR_NONE: break; case MAIL_ERROR_TEMP: return SIEVE_EXEC_TEMP_FAILURE; default: return SIEVE_EXEC_FAILURE; } trans->error = NULL; trans->error_code = MAIL_ERROR_NONE; box = mailbox_alloc_for_user(eenv->scriptenv->user, ctx->special_use_flag, (MAILBOX_FLAG_POST_SESSION | MAILBOX_FLAG_SPECIAL_USE)); /* We still override the allocate default mailbox with ours below even when the default and special-use mailbox are identical. Choosing either one is (currently) equal and setting trans->mailbox_identifier for SPECIAL-USE needs to be done either way, so we use the same code path. */ /* Try to open the mailbox */ eenv->exec_status->last_storage = mailbox_get_storage(box); if (mailbox_open(box) == 0) { pool_t pool = sieve_result_pool(aenv->result); /* Success */ mailbox_free(&trans->box); trans->box = box; trans->mailbox_identifier = p_strdup_printf(pool, "[SPECIAL-USE %s]", ctx->special_use_flag); } else { /* Failure */ if (mailbox_get_last_mail_error(box) == MAIL_ERROR_NOTFOUND) { /* Not found; revert to default */ mailbox_free(&box); } else { /* Total failure */ mailbox_free(&trans->box); trans->box = box; sieve_act_store_get_storage_error(aenv, trans); return (trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/0000755000175100001700000000000015100335670025155 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c0000644000175100001700000000636015100335616030153 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension imap4flags * -------------------- * * Authors: Stephan Bosch * Specification: RFC 5232 * Implementation: full * Status: testing * */ #include "lib.h" #include "mempool.h" #include "str.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-imap4flags-common.h" /* * Operations */ const struct sieve_operation_def *imap4flags_operations[] = { &setflag_operation, &addflag_operation, &removeflag_operation, &hasflag_operation }; /* * Extension */ static int ext_imap4flags_load(const struct sieve_extension *ext, void **context_r); static void ext_imap4flags_unload(const struct sieve_extension *ext); static bool ext_imap4flags_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_imap4flags_interpreter_load (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_extension_def imap4flags_extension = { .name = "imap4flags", .version = 1, .load = ext_imap4flags_load, .unload = ext_imap4flags_unload, .validator_load = ext_imap4flags_validator_load, .interpreter_load = ext_imap4flags_interpreter_load, SIEVE_EXT_DEFINE_OPERATIONS(imap4flags_operations), SIEVE_EXT_DEFINE_OPERAND(flags_side_effect_operand) }; static int ext_imap4flags_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct sieve_extension *var_ext; struct ext_imap4flags_context *extctx; if (sieve_ext_variables_get_extension(svinst, &var_ext) < 0) return -1; extctx = i_new(struct ext_imap4flags_context, 1); extctx->var_ext = var_ext; *context_r = extctx; return 0; } static void ext_imap4flags_unload(const struct sieve_extension *ext) { struct ext_imap4flags_context *extctx = ext->context; i_free(extctx); } static bool ext_imap4flags_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register commands */ sieve_validator_register_command(valdtr, ext, &cmd_setflag); sieve_validator_register_command(valdtr, ext, &cmd_addflag); sieve_validator_register_command(valdtr, ext, &cmd_removeflag); sieve_validator_register_command(valdtr, ext, &tst_hasflag); /* Attach :flags tag to keep and fileinto commands */ ext_imap4flags_attach_flags_tag(valdtr, ext, "keep"); ext_imap4flags_attach_flags_tag(valdtr, ext, "fileinto"); /* Attach flags side-effect to keep and fileinto actions */ sieve_ext_imap4flags_register_side_effect(valdtr, ext, "keep"); sieve_ext_imap4flags_register_side_effect(valdtr, ext, "fileinto"); return TRUE; } void sieve_ext_imap4flags_interpreter_load (const struct sieve_extension *ext, const struct sieve_runtime_env *renv) { sieve_interpreter_extension_register (renv->interp, ext, &imap4flags_interpreter_extension, NULL); } static bool ext_imap4flags_interpreter_load (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_ext_imap4flags_interpreter_load(ext, renv); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h0000644000175100001700000000421415100335616031442 0ustar00buildbotbuildbot00000000000000#ifndef EXT_IMAP4FLAGS_COMMON_H #define EXT_IMAP4FLAGS_COMMON_H #include "lib.h" #include "sieve-common.h" #include "sieve-ext-variables.h" #include "sieve-ext-imap4flags.h" /* * Extension */ struct ext_imap4flags_context { const struct sieve_extension *var_ext; }; /* * Side effect */ extern const struct sieve_side_effect_def flags_side_effect; /* * Operands */ extern const struct sieve_operand_def flags_side_effect_operand; /* * Operations */ enum ext_imap4flags_opcode { EXT_IMAP4FLAGS_OPERATION_SETFLAG, EXT_IMAP4FLAGS_OPERATION_ADDFLAG, EXT_IMAP4FLAGS_OPERATION_REMOVEFLAG, EXT_IMAP4FLAGS_OPERATION_HASFLAG }; extern const struct sieve_operation_def setflag_operation; extern const struct sieve_operation_def addflag_operation; extern const struct sieve_operation_def removeflag_operation; extern const struct sieve_operation_def hasflag_operation; /* * Commands */ extern const struct sieve_command_def cmd_setflag; extern const struct sieve_command_def cmd_addflag; extern const struct sieve_command_def cmd_removeflag; extern const struct sieve_command_def tst_hasflag; /* * Common command functions */ bool ext_imap4flags_command_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); /* * Flags tagged argument */ void ext_imap4flags_attach_flags_tag(struct sieve_validator *valdtr, const struct sieve_extension *ext, const char *command); /* * Flag management */ struct ext_imap4flags_iter { string_t *flags_list; unsigned int offset; unsigned int last; }; void ext_imap4flags_iter_init(struct ext_imap4flags_iter *iter, string_t *flags_list); const char *ext_imap4flags_iter_get_flag(struct ext_imap4flags_iter *iter); /* Flag operations */ typedef int (*ext_imapflag_flag_operation_t)(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) ATTR_NULL(2); /* Flags access */ void ext_imap4flags_get_implicit_flags_init( struct ext_imap4flags_iter *iter, const struct sieve_extension *this_ext, struct sieve_result *result); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/Makefile.am0000644000175100001700000000102315100335616027205 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_imap4flags.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-flag.c tests = \ tst-hasflag.c tags = \ tag-flags.c libsieve_ext_imap4flags_la_SOURCES = \ ext-imap4flags-common.c \ $(commands) \ $(tests) \ $(tags) \ ext-imap4flags.c public_headers = \ sieve-ext-imap4flags.h headers = \ ext-imap4flags-common.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c0000644000175100001700000004461215100335616031443 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "mail-storage.h" #include "imap-arg.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-stringlist.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-imap4flags-common.h" /* * Tagged arguments */ extern const struct sieve_argument_def tag_flags; extern const struct sieve_argument_def tag_flags_implicit; /* * Common command functions */ bool ext_imap4flags_command_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { const struct sieve_extension *ext = cmd->ext; struct ext_imap4flags_context *extctx = ext->context; const struct sieve_extension *var_ext = extctx->var_ext; struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_ast_argument *arg2; /* Check arguments */ if (arg == NULL) { sieve_command_validate_error( valdtr, cmd, "the %s %s expects at least one argument, " "but none was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } if (sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST) { sieve_argument_validate_error( valdtr, arg, "the %s %s expects either a string (variable name) or " "a string-list (list of flags) as first argument, " "but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg)); return FALSE; } arg2 = sieve_ast_argument_next(arg); if (arg2 != NULL) { /* First, check syntax sanity */ if (sieve_ast_argument_type(arg) != SAAT_STRING) { if (sieve_command_is(cmd, tst_hasflag)) { if (sieve_ast_argument_type(arg) != SAAT_STRING_LIST) { sieve_argument_validate_error( valdtr, arg, "if a second argument is specified for the hasflag, " "the first must be a string-list (variable-list), " "but %s was found", sieve_ast_argument_name(arg)); return FALSE; } } else { sieve_argument_validate_error( valdtr, arg, "if a second argument is specified for the %s %s, " "the first must be a string (variable name), " "but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg)); return FALSE; } } /* Then, check whether the second argument is permitted */ if (var_ext == NULL || !sieve_ext_variables_is_active(var_ext, valdtr)) { sieve_argument_validate_error( valdtr,arg, "the %s %s only allows for the specification of a " "variable name when the variables extension is active", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } if (!sieve_variable_argument_activate( var_ext, var_ext, valdtr, cmd, arg, !sieve_command_is(cmd, tst_hasflag))) return FALSE; if (sieve_ast_argument_type(arg2) != SAAT_STRING && sieve_ast_argument_type(arg2) != SAAT_STRING_LIST) { sieve_argument_validate_error( valdtr, arg2, "the %s %s expects a string list (list of flags) as " "second argument when two arguments are specified, " "but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg2)); return FALSE; } } else arg2 = arg; if (!sieve_validator_argument_activate(valdtr, cmd, arg2, FALSE)) return FALSE; if (!sieve_command_is(cmd, tst_hasflag) && sieve_argument_is_string_literal(arg2)) { struct ext_imap4flags_iter fiter; const char *flag; /* Warn the user about validity of verifiable flags */ ext_imap4flags_iter_init(&fiter, sieve_ast_argument_str(arg)); while ((flag = ext_imap4flags_iter_get_flag(&fiter)) != NULL) { if (!sieve_ext_imap4flags_flag_is_valid(flag)) { sieve_argument_validate_warning( valdtr, arg, "IMAP flag '%s' specified for the %s command is invalid " "and will be ignored (only first invalid is reported)", str_sanitize(flag, 64), sieve_command_identifier(cmd)); break; } } } return TRUE; } /* * Flags tag registration */ void ext_imap4flags_attach_flags_tag(struct sieve_validator *valdtr, const struct sieve_extension *ext, const char *command) { /* Register :flags tag with the command and we don't care whether it is registered or even whether it will be registered at all. The validator handles either situation gracefully. */ /* Tag specified by user */ sieve_validator_register_external_tag(valdtr, command, ext, &tag_flags, SIEVE_OPT_SIDE_EFFECT); } void sieve_ext_imap4flags_register_side_effect( struct sieve_validator *valdtr, const struct sieve_extension *flg_ext, const char *command) { /* Implicit tag if none is specified */ sieve_validator_register_persistent_tag(valdtr, command, flg_ext, &tag_flags_implicit); } /* * Result context */ struct ext_imap4flags_result_context { string_t *internal_flags; }; static void _get_initial_flags(struct sieve_result *result, string_t *flags) { const struct sieve_message_data *msgdata = sieve_result_get_message_data(result); enum mail_flags mail_flags; const char *const *mail_keywords; mail_flags = mail_get_flags(msgdata->mail); mail_keywords = mail_get_keywords(msgdata->mail); if ((mail_flags & MAIL_FLAGGED) > 0) str_printfa(flags, " \\flagged"); if ((mail_flags & MAIL_ANSWERED) > 0) str_printfa(flags, " \\answered"); if ((mail_flags & MAIL_DELETED) > 0) str_printfa(flags, " \\deleted"); if ((mail_flags & MAIL_SEEN) > 0) str_printfa(flags, " \\seen"); if ((mail_flags & MAIL_DRAFT) > 0) str_printfa(flags, " \\draft"); while (*mail_keywords != NULL) { str_printfa(flags, " %s", *mail_keywords); mail_keywords++; } } static inline struct ext_imap4flags_result_context * _get_result_context(const struct sieve_extension *this_ext, struct sieve_result *result) { struct ext_imap4flags_result_context *rctx = (struct ext_imap4flags_result_context *) sieve_result_extension_get_context(result, this_ext); if (rctx == NULL) { pool_t pool = sieve_result_pool(result); rctx = p_new(pool, struct ext_imap4flags_result_context, 1); rctx->internal_flags = str_new(pool, 32); _get_initial_flags(result, rctx->internal_flags); sieve_result_extension_set_context(result, this_ext, rctx); } return rctx; } static string_t * _get_flags_string(const struct sieve_extension *this_ext, struct sieve_result *result) { struct ext_imap4flags_result_context *ctx = _get_result_context(this_ext, result); return ctx->internal_flags; } /* * Runtime initialization */ static int ext_imap4flags_runtime_init(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, void *context ATTR_UNUSED, bool deferred ATTR_UNUSED) { sieve_result_add_implicit_side_effect(renv->result, NULL, TRUE, ext, &flags_side_effect, NULL); return SIEVE_EXEC_OK; } const struct sieve_interpreter_extension imap4flags_interpreter_extension = { .ext_def = &imap4flags_extension, .run = ext_imap4flags_runtime_init, }; /* * Flag handling */ /* FIXME: This currently accepts a potentially unlimited number of flags, making the internal or variable flag list indefinitely long. */ bool sieve_ext_imap4flags_flag_is_valid(const char *flag) { if (*flag == '\0') return FALSE; if (*flag == '\\') { /* System flag */ const char *atom = t_str_ucase(flag); if (strcmp(atom, "\\ANSWERED") != 0 && strcmp(atom, "\\FLAGGED") != 0 && strcmp(atom, "\\DELETED") != 0 && strcmp(atom, "\\SEEN") != 0 && strcmp(atom, "\\DRAFT") != 0) { return FALSE; } } else { const char *p; /* Custom keyword: Syntax (IMAP4rev1, RFC 3501, Section 9. Formal Syntax) : flag-keyword = atom atom = 1*ATOM-CHAR */ p = flag; while (*p != '\0') { if (!IS_ATOM_CHAR(*p)) return FALSE; p++; } } return TRUE; } /* Flag iterator */ static void ext_imap4flags_iter_clear(struct ext_imap4flags_iter *iter) { i_zero(iter); } void ext_imap4flags_iter_init(struct ext_imap4flags_iter *iter, string_t *flags_list) { ext_imap4flags_iter_clear(iter); iter->flags_list = flags_list; } static string_t * ext_imap4flags_iter_get_flag_str(struct ext_imap4flags_iter *iter) { unsigned int len; const unsigned char *fp; const unsigned char *fbegin; const unsigned char *fstart; const unsigned char *fend; /* Return if not initialized */ if (iter->flags_list == NULL) return NULL; /* Return if no more flags are available */ len = str_len(iter->flags_list); if (iter->offset >= len) return NULL; /* Mark string boundries */ fbegin = str_data(iter->flags_list); fend = fbegin + len; /* Start of this flag */ fstart = fbegin + iter->offset; /* Scan for next flag */ fp = fstart; for (;;) { /* Have we reached the end or a flag boundary? */ if (fp >= fend || *fp == ' ') { /* Did we scan more than nothing ? */ if (fp > fstart) { /* Return flag */ string_t *flag = t_str_new(fp-fstart+1); str_append_data(flag, fstart, fp-fstart); iter->last = fstart - fbegin; iter->offset = fp - fbegin; return flag; } fstart = fp + 1; } if (fp >= fend) break; fp++; } iter->last = fstart - fbegin; iter->offset = fp - fbegin; return NULL; } const char *ext_imap4flags_iter_get_flag(struct ext_imap4flags_iter *iter) { string_t *flag = ext_imap4flags_iter_get_flag_str(iter); if (flag == NULL) return NULL; return str_c(flag); } static void ext_imap4flags_iter_delete_last(struct ext_imap4flags_iter *iter) { iter->offset++; if (iter->offset > str_len(iter->flags_list)) iter->offset = str_len(iter->flags_list); if (iter->offset == str_len(iter->flags_list) && iter->last > 0) iter->last--; str_delete(iter->flags_list, iter->last, iter->offset - iter->last); iter->offset = iter->last; } /* Flag operations */ static string_t * ext_imap4flags_get_flag_variable(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index) ATTR_NULL(2); static bool flags_list_flag_exists(string_t *flags_list, const char *flag) { const char *flg; struct ext_imap4flags_iter flit; ext_imap4flags_iter_init(&flit, flags_list); while ((flg = ext_imap4flags_iter_get_flag(&flit)) != NULL) { if (strcasecmp(flg, flag) == 0) return TRUE; } return FALSE; } static void flags_list_flag_delete(string_t *flags_list, const char *flag) { const char *flg; struct ext_imap4flags_iter flit; ext_imap4flags_iter_init(&flit, flags_list); while ((flg = ext_imap4flags_iter_get_flag(&flit)) != NULL) { if (strcasecmp(flg, flag) == 0) ext_imap4flags_iter_delete_last(&flit); } } static void flags_list_add_flags(string_t *flags_list, string_t *flags) { const char *flg; struct ext_imap4flags_iter flit; ext_imap4flags_iter_init(&flit, flags); while ((flg = ext_imap4flags_iter_get_flag(&flit)) != NULL) { if (sieve_ext_imap4flags_flag_is_valid(flg) && !flags_list_flag_exists(flags_list, flg)) { if (str_len(flags_list) != 0) str_append_c(flags_list, ' '); str_append(flags_list, flg); } } } static void flags_list_remove_flags(string_t *flags_list, string_t *flags) { const char *flg; struct ext_imap4flags_iter flit; ext_imap4flags_iter_init(&flit, flags); while ((flg = ext_imap4flags_iter_get_flag(&flit)) != NULL) flags_list_flag_delete(flags_list, flg); } static void flags_list_set_flags(string_t *flags_list, string_t *flags) { str_truncate(flags_list, 0); flags_list_add_flags(flags_list, flags); } static void flags_list_clear_flags(string_t *flags_list) { str_truncate(flags_list, 0); } static string_t * ext_imap4flags_get_flag_variable(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index) { string_t *flags; if (storage != NULL) { if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { const char *var_name, *var_id; (void)sieve_variable_get_identifier(storage, var_index, &var_name); var_id = sieve_variable_get_varid(storage, var_index); sieve_runtime_trace(renv, 0, "update variable '%s' [%s]", var_name, var_id); } if (!sieve_variable_get_modifiable(storage, var_index, &flags)) return NULL; } else { i_assert(sieve_extension_is(flg_ext, imap4flags_extension)); flags = _get_flags_string(flg_ext, renv->result); } return flags; } int sieve_ext_imap4flags_set_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) { string_t *cur_flags = ext_imap4flags_get_flag_variable( renv, flg_ext, storage, var_index); if (cur_flags != NULL) { string_t *flags_item; int ret; flags_list_clear_flags(cur_flags); while ((ret = sieve_stringlist_next_item( flags, &flags_item)) > 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "set flags '%s'", str_c(flags_item)); flags_list_add_flags(cur_flags, flags_item); } if (ret < 0) return SIEVE_EXEC_BIN_CORRUPT; return SIEVE_EXEC_OK; } return SIEVE_EXEC_BIN_CORRUPT; } int sieve_ext_imap4flags_add_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) { string_t *cur_flags = ext_imap4flags_get_flag_variable( renv, flg_ext, storage, var_index); if (cur_flags != NULL) { string_t *flags_item; int ret; while ((ret = sieve_stringlist_next_item( flags, &flags_item)) > 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "add flags '%s'", str_c(flags_item)); flags_list_add_flags(cur_flags, flags_item); } if (ret < 0) return SIEVE_EXEC_BIN_CORRUPT; return SIEVE_EXEC_OK; } return SIEVE_EXEC_BIN_CORRUPT; } int sieve_ext_imap4flags_remove_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) { string_t *cur_flags = ext_imap4flags_get_flag_variable( renv, flg_ext, storage, var_index); if (cur_flags != NULL) { string_t *flags_item; int ret; while ((ret = sieve_stringlist_next_item( flags, &flags_item)) > 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "remove flags '%s'", str_c(flags_item)); flags_list_remove_flags(cur_flags, flags_item); } if (ret < 0) return SIEVE_EXEC_BIN_CORRUPT; return SIEVE_EXEC_OK; } return SIEVE_EXEC_BIN_CORRUPT; } /* Flag stringlist */ static int ext_imap4flags_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void ext_imap4flags_stringlist_reset(struct sieve_stringlist *_strlist); struct ext_imap4flags_stringlist { struct sieve_stringlist strlist; struct sieve_stringlist *flags_list; string_t *flags_string; struct ext_imap4flags_iter flit; bool normalize:1; }; static struct sieve_stringlist * ext_imap4flags_stringlist_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *flags_list, bool normalize) { struct ext_imap4flags_stringlist *strlist; strlist = t_new(struct ext_imap4flags_stringlist, 1); strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.runenv = renv; strlist->strlist.next_item = ext_imap4flags_stringlist_next_item; strlist->strlist.reset = ext_imap4flags_stringlist_reset; strlist->normalize = normalize; strlist->flags_list = flags_list; return &strlist->strlist; } static struct sieve_stringlist * ext_imap4flags_stringlist_create_single(const struct sieve_runtime_env *renv, string_t *flags_string, bool normalize) { struct ext_imap4flags_stringlist *strlist; strlist = t_new(struct ext_imap4flags_stringlist, 1); strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.runenv = renv; strlist->strlist.next_item = ext_imap4flags_stringlist_next_item; strlist->strlist.reset = ext_imap4flags_stringlist_reset; strlist->normalize = normalize; if (normalize) { strlist->flags_string = t_str_new(256); flags_list_set_flags(strlist->flags_string, flags_string); } else { strlist->flags_string = flags_string; } ext_imap4flags_iter_init(&strlist->flit, strlist->flags_string); return &strlist->strlist; } static int ext_imap4flags_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct ext_imap4flags_stringlist *strlist = (struct ext_imap4flags_stringlist *)_strlist; while ((*str_r = ext_imap4flags_iter_get_flag_str( &strlist->flit)) == NULL) { int ret; if (strlist->flags_list == NULL) return 0; ret = sieve_stringlist_next_item(strlist->flags_list, &strlist->flags_string); if (ret <= 0) return ret; if (strlist->flags_string == NULL) return -1; if (strlist->normalize) { string_t *flags_string = t_str_new(256); flags_list_set_flags(flags_string, strlist->flags_string); strlist->flags_string = flags_string; } ext_imap4flags_iter_init(&strlist->flit, strlist->flags_string); } return 1; } static void ext_imap4flags_stringlist_reset(struct sieve_stringlist *_strlist) { struct ext_imap4flags_stringlist *strlist = (struct ext_imap4flags_stringlist *)_strlist; if (strlist->flags_list != NULL) { sieve_stringlist_reset(strlist->flags_list); ext_imap4flags_iter_clear(&strlist->flit); } else { ext_imap4flags_iter_init(&strlist->flit, strlist->flags_string); } } /* Flag access */ struct sieve_stringlist * sieve_ext_imap4flags_get_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_stringlist *flags_list) { if (flags_list == NULL) { i_assert(sieve_extension_is(flg_ext, imap4flags_extension)); return ext_imap4flags_stringlist_create_single( renv, _get_flags_string(flg_ext, renv->result), FALSE); } return ext_imap4flags_stringlist_create(renv, flags_list, TRUE); } void ext_imap4flags_get_implicit_flags_init( struct ext_imap4flags_iter *iter, const struct sieve_extension *this_ext, struct sieve_result *result) { string_t *cur_flags = _get_flags_string(this_ext, result); ext_imap4flags_iter_init(iter, cur_flags); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/Makefile.in0000644000175100001700000006253515100335630027231 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/imap4flags ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(pkginc_lib_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_imap4flags_la_LIBADD = am__objects_1 = cmd-flag.lo am__objects_2 = tst-hasflag.lo am__objects_3 = tag-flags.lo am_libsieve_ext_imap4flags_la_OBJECTS = ext-imap4flags-common.lo \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ ext-imap4flags.lo libsieve_ext_imap4flags_la_OBJECTS = \ $(am_libsieve_ext_imap4flags_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-flag.Plo \ ./$(DEPDIR)/ext-imap4flags-common.Plo \ ./$(DEPDIR)/ext-imap4flags.Plo ./$(DEPDIR)/tag-flags.Plo \ ./$(DEPDIR)/tst-hasflag.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_imap4flags_la_SOURCES) DIST_SOURCES = $(libsieve_ext_imap4flags_la_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(noinst_HEADERS) $(pkginc_lib_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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_imap4flags.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-flag.c tests = \ tst-hasflag.c tags = \ tag-flags.c libsieve_ext_imap4flags_la_SOURCES = \ ext-imap4flags-common.c \ $(commands) \ $(tests) \ $(tags) \ ext-imap4flags.c public_headers = \ sieve-ext-imap4flags.h headers = \ ext-imap4flags-common.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/imap4flags/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/imap4flags/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_imap4flags.la: $(libsieve_ext_imap4flags_la_OBJECTS) $(libsieve_ext_imap4flags_la_DEPENDENCIES) $(EXTRA_libsieve_ext_imap4flags_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_imap4flags_la_OBJECTS) $(libsieve_ext_imap4flags_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-flag.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-imap4flags-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-imap4flags.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-flags.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-hasflag.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-flag.Plo -rm -f ./$(DEPDIR)/ext-imap4flags-common.Plo -rm -f ./$(DEPDIR)/ext-imap4flags.Plo -rm -f ./$(DEPDIR)/tag-flags.Plo -rm -f ./$(DEPDIR)/tst-hasflag.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-flag.Plo -rm -f ./$(DEPDIR)/ext-imap4flags-common.Plo -rm -f ./$(DEPDIR)/ext-imap4flags.Plo -rm -f ./$(DEPDIR)/tag-flags.Plo -rm -f ./$(DEPDIR)/tst-hasflag.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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-pkginc_libHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/tag-flags.c0000644000175100001700000002451015100335616027170 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "array.h" #include "mail-storage.h" #include "sieve-code.h" #include "sieve-stringlist.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-result.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-actions.h" #include "sieve-dump.h" #include "ext-imap4flags-common.h" #include /* * Flags tagged argument */ static bool tag_flags_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_flags_validate_persistent(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext); static bool tag_flags_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); const struct sieve_argument_def tag_flags = { .identifier = "flags", .validate = tag_flags_validate, .generate = tag_flags_generate, }; const struct sieve_argument_def tag_flags_implicit = { .identifier = "flags-implicit", .validate_persistent = tag_flags_validate_persistent, .generate = tag_flags_generate, }; /* * Side effect */ static bool seff_flags_dump_context(const struct sieve_side_effect *seffect, const struct sieve_dumptime_env *denv, sieve_size_t *address); static int seff_flags_read_context(const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **context); static int seff_flags_merge(const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_side_effect *old_seffect, const struct sieve_side_effect *new_seffect, void **old_context); static void seff_flags_print(const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int seff_flags_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context); const struct sieve_side_effect_def flags_side_effect = { SIEVE_OBJECT("flags", &flags_side_effect_operand, 0), .to_action = &act_store, .dump_context = seff_flags_dump_context, .read_context = seff_flags_read_context, .merge = seff_flags_merge, .print = seff_flags_print, .pre_execute = seff_flags_pre_execute, }; /* * Operand */ static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(flags_side_effect); const struct sieve_operand_def flags_side_effect_operand = { .name = "flags operand", .ext_def = &imap4flags_extension, .class = &sieve_side_effect_operand_class, .interface = &ext_side_effects, }; /* * Tag validation */ static bool tag_flags_validate_persistent(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd, const struct sieve_extension *ext) { if (sieve_command_find_argument(cmd, &tag_flags) == NULL) sieve_command_add_dynamic_tag(cmd, ext, &tag_flags_implicit, -1); return TRUE; } static bool tag_flags_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_argument_next(*arg); /* Check syntax: * :flags */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING_LIST, FALSE)) return FALSE; tag->parameters = *arg; /* Detach parameter */ *arg = sieve_ast_arguments_detach(*arg,1); return TRUE; } /* * Code generation */ static bool tag_flags_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { struct sieve_ast_argument *param; if (sieve_ast_argument_type(arg) != SAAT_TAG) return FALSE; sieve_opr_side_effect_emit(cgenv->sblock, arg->argument->ext, &flags_side_effect); if (sieve_argument_is(arg, tag_flags)) { /* Explicit :flags tag */ param = arg->parameters; /* Call the generation function for the argument */ if (param->argument != NULL && param->argument->def != NULL && param->argument->def->generate != NULL && !param->argument->def->generate(cgenv, param, cmd)) return FALSE; } else if (sieve_argument_is(arg, tag_flags_implicit)) { /* Implicit flags */ sieve_opr_omitted_emit(cgenv->sblock); } else { /* Something else?! */ i_unreached(); } return TRUE; } /* * Side effect implementation */ /* Context data */ struct seff_flags_context { ARRAY(const char *) keywords; enum mail_flags flags; }; /* Context coding */ static bool seff_flags_dump_context(const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { return sieve_opr_stringlist_dump_ex(denv, address, "flags", "INTERNAL"); } static struct seff_flags_context * seff_flags_get_implicit_context(const struct sieve_extension *this_ext, struct sieve_result *result) { pool_t pool = sieve_result_pool(result); struct seff_flags_context *ctx; const char *flag; struct ext_imap4flags_iter flit; ctx = p_new(pool, struct seff_flags_context, 1); p_array_init(&ctx->keywords, pool, 2); T_BEGIN { /* Unpack */ ext_imap4flags_get_implicit_flags_init(&flit, this_ext, result); while ((flag = ext_imap4flags_iter_get_flag(&flit)) != NULL) { if (flag != NULL && *flag != '\\') { /* keyword */ const char *keyword = p_strdup(pool, flag); array_append(&ctx->keywords, &keyword, 1); } else { /* system flag */ if (flag == NULL || strcasecmp(flag, "\\flagged") == 0) ctx->flags |= MAIL_FLAGGED; else if (strcasecmp(flag, "\\answered") == 0) ctx->flags |= MAIL_ANSWERED; else if (strcasecmp(flag, "\\deleted") == 0) ctx->flags |= MAIL_DELETED; else if (strcasecmp(flag, "\\seen") == 0) ctx->flags |= MAIL_SEEN; else if (strcasecmp(flag, "\\draft") == 0) ctx->flags |= MAIL_DRAFT; } } } T_END; return ctx; } static int seff_flags_do_read_context(const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { pool_t pool = sieve_result_pool(renv->result); struct seff_flags_context *ctx; string_t *flags_item; struct sieve_stringlist *flag_list = NULL; int ret; ret = sieve_opr_stringlist_read_ex(renv, address, "flags", TRUE, &flag_list); if (ret <= 0) return ret; if (flag_list == NULL) { /* Flag list is omitted, use current value of internal * variable to construct side effect context. */ *se_context = seff_flags_get_implicit_context( SIEVE_OBJECT_EXTENSION(seffect), renv->result); return SIEVE_EXEC_OK; } ctx = p_new(pool, struct seff_flags_context, 1); p_array_init(&ctx->keywords, pool, 2); /* Unpack */ flags_item = NULL; while ((ret = sieve_stringlist_next_item(flag_list, &flags_item)) > 0) { const char *flag; struct ext_imap4flags_iter flit; ext_imap4flags_iter_init(&flit, flags_item); while ((flag = ext_imap4flags_iter_get_flag(&flit)) != NULL) { if (flag != NULL && *flag != '\\') { /* keyword */ const char *keyword = p_strdup(pool, flag); /* FIXME: should check for duplicates (cannot trust variables) */ array_append(&ctx->keywords, &keyword, 1); } else { /* system flag */ if (flag == NULL || strcasecmp(flag, "\\flagged") == 0) ctx->flags |= MAIL_FLAGGED; else if (strcasecmp(flag, "\\answered") == 0) ctx->flags |= MAIL_ANSWERED; else if (strcasecmp(flag, "\\deleted") == 0) ctx->flags |= MAIL_DELETED; else if (strcasecmp(flag, "\\seen") == 0) ctx->flags |= MAIL_SEEN; else if (strcasecmp(flag, "\\draft") == 0) ctx->flags |= MAIL_DRAFT; } } } if (ret < 0) return flag_list->exec_status; *se_context = ctx; return SIEVE_EXEC_OK; } static int seff_flags_read_context(const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { int ret; T_BEGIN { ret = seff_flags_do_read_context(seffect, renv, address, se_context); } T_END; return ret; } /* Result verification */ static int seff_flags_merge(const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, const struct sieve_side_effect *old_seffect ATTR_UNUSED, const struct sieve_side_effect *new_seffect, void **old_context) { if (new_seffect != NULL) *old_context = new_seffect->context; return 1; } /* Result printing */ static void seff_flags_print(const struct sieve_side_effect *seffect, const struct sieve_action *action ATTR_UNUSED, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { struct sieve_result *result = rpenv->result; struct seff_flags_context *ctx = (struct seff_flags_context *)seffect->context; unsigned int i; if (ctx == NULL) { ctx = seff_flags_get_implicit_context( SIEVE_OBJECT_EXTENSION(seffect), result); } if (ctx->flags != 0 || array_count(&ctx->keywords) > 0) { T_BEGIN { string_t *flags = t_str_new(128); if ((ctx->flags & MAIL_FLAGGED) > 0) str_printfa(flags, " \\flagged"); if ((ctx->flags & MAIL_ANSWERED) > 0) str_printfa(flags, " \\answered"); if ((ctx->flags & MAIL_DELETED) > 0) str_printfa(flags, " \\deleted"); if ((ctx->flags & MAIL_SEEN) > 0) str_printfa(flags, " \\seen"); if ((ctx->flags & MAIL_DRAFT) > 0) str_printfa(flags, " \\draft"); for (i = 0; i < array_count(&ctx->keywords); i++) { const char *const *keyword = array_idx(&ctx->keywords, i); str_printfa(flags, " %s", str_sanitize(*keyword, 64)); } sieve_result_seffect_printf(rpenv, "add IMAP flags:%s", str_c(flags)); } T_END; } } /* Result execution */ static int seff_flags_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_action_exec_env *aenv, void *tr_context, void **se_tr_context ATTR_UNUSED) { struct seff_flags_context *ctx = seffect->context; const char *const *keywords; if (ctx == NULL) { ctx = seff_flags_get_implicit_context( SIEVE_OBJECT_EXTENSION(seffect), aenv->result); } (void)array_append_space(&ctx->keywords); keywords = array_idx(&ctx->keywords, 0); sieve_act_store_add_flags(aenv, tr_context, keywords, ctx->flags); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/cmd-flag.c0000644000175100001700000001416315100335616027000 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-code.h" #include "sieve-stringlist.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-imap4flags-common.h" /* * Commands */ /* Forward declarations */ static bool cmd_flag_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); /* Setflag command * * Syntax: * setflag [] */ const struct sieve_command_def cmd_setflag = { .identifier = "setflag", .type = SCT_COMMAND, .positional_args = -1, /* We check positional arguments ourselves */ .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = ext_imap4flags_command_validate, .generate = cmd_flag_generate }; /* Addflag command * * Syntax: * addflag [] */ const struct sieve_command_def cmd_addflag = { .identifier = "addflag", .type = SCT_COMMAND, .positional_args = -1, /* We check positional arguments ourselves */ .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = ext_imap4flags_command_validate, .generate = cmd_flag_generate }; /* Removeflag command * * Syntax: * removeflag [] */ const struct sieve_command_def cmd_removeflag = { .identifier = "removeflag", .type = SCT_COMMAND, .positional_args = -1, /* We check positional arguments ourselves */ .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = ext_imap4flags_command_validate, .generate = cmd_flag_generate }; /* * Operations */ /* Forward declarations */ bool cmd_flag_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_flag_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); /* Setflag operation */ const struct sieve_operation_def setflag_operation = { .mnemonic = "SETFLAG", .ext_def = &imap4flags_extension, .code = EXT_IMAP4FLAGS_OPERATION_SETFLAG, .dump = cmd_flag_operation_dump, .execute = cmd_flag_operation_execute }; /* Addflag operation */ const struct sieve_operation_def addflag_operation = { .mnemonic = "ADDFLAG", .ext_def = &imap4flags_extension, .code = EXT_IMAP4FLAGS_OPERATION_ADDFLAG, .dump = cmd_flag_operation_dump, .execute = cmd_flag_operation_execute }; /* Removeflag operation */ const struct sieve_operation_def removeflag_operation = { .mnemonic = "REMOVEFLAG", .ext_def = &imap4flags_extension, .code = EXT_IMAP4FLAGS_OPERATION_REMOVEFLAG, .dump = cmd_flag_operation_dump, .execute = cmd_flag_operation_execute }; /* * Code generation */ static bool cmd_flag_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct sieve_ast_argument *arg1, *arg2; /* Emit operation */ if ( sieve_command_is(cmd, cmd_setflag) ) sieve_operation_emit(cgenv->sblock, cmd->ext, &setflag_operation); else if ( sieve_command_is(cmd, cmd_addflag) ) sieve_operation_emit(cgenv->sblock, cmd->ext, &addflag_operation); else if ( sieve_command_is(cmd, cmd_removeflag) ) sieve_operation_emit(cgenv->sblock, cmd->ext, &removeflag_operation); arg1 = cmd->first_positional; arg2 = sieve_ast_argument_next(arg1); if ( arg2 == NULL ) { /* No variable */ sieve_opr_omitted_emit(cgenv->sblock); if ( !sieve_generate_argument(cgenv, arg1, cmd) ) return FALSE; } else { /* Full command */ if ( !sieve_generate_argument(cgenv, arg1, cmd) ) return FALSE; if ( !sieve_generate_argument(cgenv, arg2, cmd) ) return FALSE; } return TRUE; } /* * Code dump */ bool cmd_flag_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct sieve_operand oprnd; sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(denv->oprtn)); sieve_code_descend(denv); sieve_code_mark(denv); if ( !sieve_operand_read(denv->sblock, address, NULL, &oprnd) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } if ( !sieve_operand_is_omitted(&oprnd) ) { return sieve_opr_string_dump_data(denv, &oprnd, address, "variable name") && sieve_opr_stringlist_dump(denv, address, "list of flags"); } return sieve_opr_stringlist_dump(denv, address, "list of flags"); } /* * Code execution */ static int cmd_flag_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *op = renv->oprtn; struct sieve_operand oprnd; struct sieve_stringlist *flag_list; struct sieve_variable_storage *storage; unsigned int var_index; ext_imapflag_flag_operation_t flag_op; int ret; /* * Read operands */ /* Read bare operand (two types possible) */ if ( (ret=sieve_operand_runtime_read (renv, address, NULL, &oprnd)) <= 0 ) return ret; /* Variable operand (optional) */ if ( !sieve_operand_is_omitted(&oprnd) ) { /* Read the variable operand */ if ( (ret=sieve_variable_operand_read_data (renv, &oprnd, address, "variable", &storage, &var_index)) <= 0 ) return ret; /* Read flag list */ if ( (ret=sieve_opr_stringlist_read(renv, address, "flag-list", &flag_list)) <= 0 ) return ret; /* Flag-list operand */ } else { storage = NULL; var_index = 0; /* Read flag list */ if ( (ret=sieve_opr_stringlist_read(renv, address, "flag-list", &flag_list)) <= 0 ) return ret; } /* * Perform operation */ /* Determine what to do */ if ( sieve_operation_is(op, setflag_operation) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "setflag command"); flag_op = sieve_ext_imap4flags_set_flags; } else if ( sieve_operation_is(op, addflag_operation) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "addflag command"); flag_op = sieve_ext_imap4flags_add_flags; } else if ( sieve_operation_is(op, removeflag_operation) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "removeflag command"); flag_op = sieve_ext_imap4flags_remove_flags; } else { i_unreached(); } sieve_runtime_trace_descend(renv); /* Perform requested operation */ return flag_op(renv, op->ext, storage, var_index, flag_list); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/sieve-ext-imap4flags.h0000644000175100001700000000367415100335616031276 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXT_IMAP4FLAGS_H #define SIEVE_EXT_IMAP4FLAGS_H struct sieve_variable_storage; /* * Imap4flags extension */ /* FIXME: this is not suitable for future plugin support */ extern const struct sieve_extension_def imap4flags_extension; extern const struct sieve_interpreter_extension imap4flags_interpreter_extension; static inline int sieve_ext_imap4flags_require_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_require(svinst, &imap4flags_extension, TRUE, ext_r); } void sieve_ext_imap4flags_interpreter_load( const struct sieve_extension *ext, const struct sieve_runtime_env *renv); /* * Action side-effect */ void sieve_ext_imap4flags_register_side_effect( struct sieve_validator *valdtr, const struct sieve_extension *flg_ext, const char *command); /* * Flag syntax */ bool sieve_ext_imap4flags_flag_is_valid(const char *flag); /* * Flag manipulation */ int sieve_ext_imap4flags_set_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) ATTR_NULL(3); int sieve_ext_imap4flags_add_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) ATTR_NULL(3); int sieve_ext_imap4flags_remove_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) ATTR_NULL(3); /* * Flag retrieval */ struct sieve_stringlist * sieve_ext_imap4flags_get_flags(const struct sieve_runtime_env *renv, const struct sieve_extension *flg_ext, struct sieve_stringlist *flags_list); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/imap4flags/tst-hasflag.c0000644000175100001700000001331415100335616027540 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-imap4flags-common.h" /* * Hasflag test * * Syntax: * hasflag [MATCH-TYPE] [COMPARATOR] [] * */ static bool tst_hasflag_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_hasflag_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_hasflag_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def tst_hasflag = { .identifier = "hasflag", .type = SCT_TEST, .positional_args = -1, /* We check positional arguments ourselves */ .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_hasflag_registered, .validate = tst_hasflag_validate, .generate = tst_hasflag_generate, }; /* * Hasflag operation */ static bool tst_hasflag_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_hasflag_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def hasflag_operation = { .mnemonic = "HASFLAG", .ext_def = &imap4flags_extension, .code = EXT_IMAP4FLAGS_OPERATION_HASFLAG, .dump = tst_hasflag_operation_dump, .execute = tst_hasflag_operation_execute, }; /* * Optional arguments */ enum tst_hasflag_optional { OPT_VARIABLES = SIEVE_MATCH_OPT_LAST, }; /* * Tag registration */ static bool tst_hasflag_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); return TRUE; } /* * Validation */ static bool tst_hasflag_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if (!ext_imap4flags_command_validate(valdtr, tst)) return FALSE; struct sieve_ast_argument *vars = tst->first_positional; struct sieve_ast_argument *keys = sieve_ast_argument_next(vars); if (keys == NULL) { keys = vars; vars = NULL; } else { vars->argument->id_code = OPT_VARIABLES; } /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, keys, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_hasflag_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &hasflag_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool tst_hasflag_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "HASFLAG"); sieve_code_descend(denv); /* Optional operands */ for (;;) { bool opok = TRUE; int opt; opt = sieve_match_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_VARIABLES: opok = sieve_opr_stringlist_dump(denv, address, "variables"); break; default: return FALSE; } if (!opok) return FALSE; } return sieve_opr_stringlist_dump(denv, address, "list of flags"); } /* * Interpretation */ static int tst_hasflag_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *op = renv->oprtn; int opt_code = 0; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_stringlist *flag_list, *variables_list, *value_list, *key_list; int match, ret; /* * Read operands */ /* Optional operands */ variables_list = NULL; for (;;) { int opt; opt = sieve_match_opr_optional_read(renv, address, &opt_code, &ret, &cmp, &mcht); if (opt < 0) return ret; if (opt == 0) break; switch (opt_code) { case OPT_VARIABLES: ret = sieve_opr_stringlist_read( renv, address, "variables-list", &variables_list); break; default: sieve_runtime_trace_error( renv, "invalid optional operand"); ret = SIEVE_EXEC_BIN_CORRUPT; } if (ret <= 0) return ret; } /* Fixed operands */ ret = sieve_opr_stringlist_read(renv, address, "flag-list", &flag_list); if (ret <= 0) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "hasflag test"); value_list = sieve_ext_imap4flags_get_flags(renv, op->ext, variables_list); if (sieve_match_type_is(&mcht, is_match_type) || sieve_match_type_is(&mcht, contains_match_type)) { key_list = sieve_ext_imap4flags_get_flags( renv, op->ext, flag_list); } else { key_list = flag_list; } /* Perform match */ match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret); if (match < 0) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/comparator-i-ascii-numeric/0000755000175100001700000000000015100335670030251 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.am0000644000175100001700000000032015100335616032300 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_comparator-i-ascii-numeric.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_comparator_i_ascii_numeric_la_SOURCES = \ ext-cmp-i-ascii-numeric.c dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.in0000644000175100001700000005377715100335630032335 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/comparator-i-ascii-numeric ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_comparator_i_ascii_numeric_la_LIBADD = am_libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS = \ ext-cmp-i-ascii-numeric.lo libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS = \ $(am_libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-cmp-i-ascii-numeric.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_comparator_i_ascii_numeric_la_SOURCES) DIST_SOURCES = $(libsieve_ext_comparator_i_ascii_numeric_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_comparator-i-ascii-numeric.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_comparator_i_ascii_numeric_la_SOURCES = \ ext-cmp-i-ascii-numeric.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/comparator-i-ascii-numeric/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_comparator-i-ascii-numeric.la: $(libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS) $(libsieve_ext_comparator_i_ascii_numeric_la_DEPENDENCIES) $(EXTRA_libsieve_ext_comparator_i_ascii_numeric_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS) $(libsieve_ext_comparator_i_ascii_numeric_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-cmp-i-ascii-numeric.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-cmp-i-ascii-numeric.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-cmp-i-ascii-numeric.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c0000644000175100001700000000647415100335616034761 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension comparator-i;ascii-numeric * ------------------------------------ * * Author: Stephan Bosch * Specification: RFC 2244 * Implementation: full * Status: testing * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-comparators.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include /* * Forward declarations */ static const struct sieve_operand_def my_comparator_operand; const struct sieve_comparator_def i_ascii_numeric_comparator; /* * Extension */ static bool ext_cmp_i_ascii_numeric_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def comparator_i_ascii_numeric_extension = { .name = "comparator-i;ascii-numeric", .validator_load = ext_cmp_i_ascii_numeric_validator_load, SIEVE_EXT_DEFINE_OPERAND(my_comparator_operand) }; static bool ext_cmp_i_ascii_numeric_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator) { sieve_comparator_register(validator, ext, &i_ascii_numeric_comparator); return TRUE; } /* * Operand */ static const struct sieve_extension_objects ext_comparators = SIEVE_EXT_DEFINE_COMPARATOR(i_ascii_numeric_comparator); static const struct sieve_operand_def my_comparator_operand = { .name = "comparator-i;ascii-numeric", .ext_def = &comparator_i_ascii_numeric_extension, .class = &sieve_comparator_operand_class, .interface = &ext_comparators }; /* * Comparator */ /* Forward declarations */ static int cmp_i_ascii_numeric_compare (const struct sieve_comparator *cmp, const char *val1, size_t val1_size, const char *val2, size_t val2_size); /* Comparator object */ const struct sieve_comparator_def i_ascii_numeric_comparator = { SIEVE_OBJECT("i;ascii-numeric", &my_comparator_operand, 0), .flags = SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY, .compare = cmp_i_ascii_numeric_compare }; /* Comparator implementation */ static int cmp_i_ascii_numeric_compare (const struct sieve_comparator *cmp ATTR_UNUSED, const char *val, size_t val_size, const char *key, size_t key_size) { const char *vend = val + val_size; const char *kend = key + key_size; const char *vp = val; const char *kp = key; int digits, i; /* RFC 4790: All input is valid; strings that do not start with a digit * represent positive infinity. */ if ( !i_isdigit(*vp) ) { if ( i_isdigit(*kp) ) { /* Value is greater */ return 1; } } else { if ( !i_isdigit(*kp) ) { /* Value is less */ return -1; } } /* Ignore leading zeros */ while ( *vp == '0' && vp < vend ) vp++; while ( *kp == '0' && kp < kend ) kp++; /* Check whether both numbers are equally long in terms of digits */ digits = 0; while ( vp < vend && kp < kend && i_isdigit(*vp) && i_isdigit(*kp) ) { vp++; kp++; digits++; } if ( vp == vend || !i_isdigit(*vp) ) { if ( kp != kend && i_isdigit(*kp) ) { /* Value is less */ return -1; } } else { /* Value is greater */ return 1; } /* Equally long: compare digits */ vp -= digits; kp -= digits; i = 0; while ( i < digits ) { if ( *vp > *kp ) return 1; else if ( *vp < *kp ) return -1; kp++; vp++; i++; } return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/Makefile.am0000644000175100001700000000056415100335616025167 0ustar00buildbotbuildbot00000000000000if BUILD_UNFINISHED UNFINISHED = endif SUBDIRS = \ vacation \ subaddress \ comparator-i-ascii-numeric \ relational \ regex \ imap4flags \ copy \ include \ body \ variables \ enotify \ environment \ mailbox \ date \ spamvirustest \ ihave \ editheader \ duplicate \ index \ metadata \ mime \ special-use \ extlists \ vnd.dovecot \ $(UNFINISHED) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/0000755000175100001700000000000015100335670024055 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/cmd-break.c0000644000175100001700000001431315100335616026050 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-binary.h" #include "sieve-dump.h" #include "ext-mime-common.h" #include /* break * * Syntax: * break [":name" ] * */ static bool cmd_break_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_break_pre_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_break_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_break_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def cmd_break = { .identifier = "break", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_break_registered, .pre_validate = cmd_break_pre_validate, .validate = cmd_break_validate, .generate = cmd_break_generate, }; /* * Tagged arguments */ /* Forward declarations */ static bool cmd_break_validate_name_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def break_name_tag = { .identifier = "name", .validate = cmd_break_validate_name_tag, }; /* * Break operation */ static bool cmd_break_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_break_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def break_operation = { .mnemonic = "BREAK", .ext_def = &foreverypart_extension, .code = EXT_FOREVERYPART_OPERATION_BREAK, .dump = cmd_break_operation_dump, .execute = cmd_break_operation_execute, }; /* * Validation data */ struct cmd_break_data { struct sieve_ast_argument *name; struct sieve_command *loop_cmd; }; /* * Tag validation */ static bool cmd_break_validate_name_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct cmd_break_data *data = (struct cmd_break_data *)cmd->data; struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg, 1); /* Check syntax: * :name */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, TRUE)) return FALSE; data->name = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Command registration */ static bool cmd_break_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, &break_name_tag, 0); return TRUE; } /* * Command validation */ static bool cmd_break_pre_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct cmd_break_data *data; pool_t pool = sieve_command_pool(cmd); data = p_new(pool, struct cmd_break_data, 1); cmd->data = data; return TRUE; } static bool cmd_break_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct cmd_break_data *data = (struct cmd_break_data *)cmd->data; struct sieve_ast_node *node = cmd->ast_node; const char *name = (data->name == NULL ? NULL : sieve_ast_argument_strc(data->name)); i_assert(node != NULL); while (node != NULL && node->command != NULL) { if (sieve_command_is(node->command, cmd_foreverypart)) { struct ext_foreverypart_loop *loop = (struct ext_foreverypart_loop *) node->command->data; if (name == NULL || (name != NULL && loop->name != NULL && strcmp(name, loop->name) == 0)) { data->loop_cmd = node->command; break; } } node = sieve_ast_node_parent(node); } if (data->loop_cmd == NULL) { if (name == NULL) { sieve_command_validate_error( valdtr, cmd, "the break command is not placed inside " "a foreverypart loop"); } else { sieve_command_validate_error( valdtr, cmd, "the break command is not placed inside " "a foreverypart loop named '%s'", name); } return FALSE; } sieve_command_exit_block_unconditionally(cmd); return TRUE; } /* * Code generation */ static bool cmd_break_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_break_data *data = (struct cmd_break_data *)cmd->data; struct ext_foreverypart_loop *loop; i_assert(data->loop_cmd != NULL); loop = (struct ext_foreverypart_loop *)data->loop_cmd->data; sieve_operation_emit(cgenv->sblock, cmd->ext, &break_operation); sieve_jumplist_add(loop->exit_jumps, sieve_binary_emit_offset(cgenv->sblock, 0)); return TRUE; } /* * Code dump */ static bool cmd_break_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int pc = *address; sieve_offset_t offset; sieve_code_dumpf(denv, "BREAK"); sieve_code_descend(denv); if (!sieve_binary_read_offset(denv->sblock, address, &offset)) return FALSE; sieve_code_dumpf(denv, "END: %d [%08x]", offset, pc + offset); return TRUE; } /* * Code execution */ static int cmd_break_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_interpreter_loop *loop; unsigned int pc = *address; sieve_offset_t offset; sieve_size_t loop_end; /* * Read operands */ if (!sieve_binary_read_offset(renv->sblock, address, &offset)) { sieve_runtime_trace_error(renv, "invalid loop end offset"); return SIEVE_EXEC_BIN_CORRUPT; } loop_end = pc + offset; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "break command"); sieve_runtime_trace_descend(renv); loop = sieve_interpreter_loop_get(renv->interp, loop_end, &foreverypart_extension); if (loop == NULL) { sieve_runtime_trace_error(renv, "no matching loop found"); return SIEVE_EXEC_BIN_CORRUPT; } sieve_interpreter_loop_break(renv->interp, loop); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/cmd-foreverypart.c0000644000175100001700000002323415100335616027516 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-binary.h" #include "sieve-dump.h" #include "sieve-message.h" #include "ext-mime-common.h" #include /* Foreverypart * * Syntax: * foreverypart [":name" ] * */ static bool cmd_foreverypart_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_foreverypart_pre_validate (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_foreverypart_validate (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_foreverypart_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def cmd_foreverypart = { .identifier = "foreverypart", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = TRUE, .block_required = TRUE, .registered = cmd_foreverypart_registered, .pre_validate = cmd_foreverypart_pre_validate, .validate = cmd_foreverypart_validate, .generate = cmd_foreverypart_generate }; /* * Tagged arguments */ /* Forward declarations */ static bool cmd_foreverypart_validate_name_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def foreverypart_name_tag = { .identifier = "name", .validate = cmd_foreverypart_validate_name_tag, }; /* * foreverypart operation */ static bool cmd_foreverypart_begin_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_foreverypart_begin_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def foreverypart_begin_operation = { .mnemonic = "FOREVERYPART_BEGIN", .ext_def = &foreverypart_extension, .code = EXT_FOREVERYPART_OPERATION_FOREVERYPART_BEGIN, .dump = cmd_foreverypart_begin_operation_dump, .execute = cmd_foreverypart_begin_operation_execute }; static bool cmd_foreverypart_end_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_foreverypart_end_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def foreverypart_end_operation = { .mnemonic = "FOREVERYPART_END", .ext_def = &foreverypart_extension, .code = EXT_FOREVERYPART_OPERATION_FOREVERYPART_END, .dump = cmd_foreverypart_end_operation_dump, .execute = cmd_foreverypart_end_operation_execute }; /* * Tag validation */ static bool cmd_foreverypart_validate_name_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct ext_foreverypart_loop *loop = (struct ext_foreverypart_loop *)cmd->data; struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg, 1); /* Check syntax: * :name */ if ( !sieve_validate_tag_parameter (valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, TRUE) ) return FALSE; loop->name = sieve_ast_argument_strc(*arg); /* Detach parameter */ *arg = sieve_ast_arguments_detach(*arg, 1); return TRUE; } /* * Command registration */ static bool cmd_foreverypart_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag (valdtr, cmd_reg, ext, &foreverypart_name_tag, 0); return TRUE; } /* * Command validation */ static bool cmd_foreverypart_pre_validate (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct ext_foreverypart_loop *loop; pool_t pool = sieve_command_pool(cmd); loop = p_new(pool, struct ext_foreverypart_loop, 1); cmd->data = loop; return TRUE; } static bool cmd_foreverypart_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_node *node = cmd->ast_node; unsigned int nesting = 0; /* Determine nesting depth of foreverypart commands at this point. */ i_assert(node != NULL); node = sieve_ast_node_parent(node); while ( node != NULL && node->command != NULL ) { if ( sieve_command_is(node->command, cmd_foreverypart) ) nesting++; node = sieve_ast_node_parent(node); } /* Enforce nesting limit NOTE: this only recognizes the foreverypart command as a loop; if new loop commands are introduced in the future, these must be recognized somehow. */ if ( nesting + 1 > SIEVE_MAX_LOOP_DEPTH ) { sieve_command_validate_error(valdtr, cmd, "the nested foreverypart loop exceeds " "the nesting limit (<= %u levels)", SIEVE_MAX_LOOP_DEPTH); return FALSE; } return TRUE; } /* * Code generation */ static bool cmd_foreverypart_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct ext_foreverypart_loop *loop = (struct ext_foreverypart_loop *)cmd->data; sieve_size_t block_begin, loop_jump; /* Emit FOREVERYPART_BEGIN operation */ sieve_operation_emit(cgenv->sblock, cmd->ext, &foreverypart_begin_operation); /* Emit exit address */ loop->exit_jumps = sieve_jumplist_create (sieve_command_pool(cmd), cgenv->sblock); sieve_jumplist_add(loop->exit_jumps, sieve_binary_emit_offset(cgenv->sblock, 0)); block_begin = sieve_binary_block_get_size(cgenv->sblock); /* Generate loop block */ if ( !sieve_generate_block(cgenv, cmd->ast_node) ) return FALSE; /* Emit FOREVERYPART_END operation */ sieve_operation_emit(cgenv->sblock, cmd->ext, &foreverypart_end_operation); loop_jump = sieve_binary_block_get_size(cgenv->sblock); i_assert(loop_jump > block_begin); (void)sieve_binary_emit_offset (cgenv->sblock, (loop_jump - block_begin)); /* Resolve exit address */ sieve_jumplist_resolve(loop->exit_jumps); return TRUE; } /* * Code dump */ static bool cmd_foreverypart_begin_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int pc = *address; sieve_offset_t offset; sieve_code_dumpf(denv, "FOREVERYPART_BEGIN"); sieve_code_descend(denv); if ( !sieve_binary_read_offset(denv->sblock, address, &offset) ) return FALSE; sieve_code_dumpf(denv, "END: %d [%08x]", offset, pc + offset); return TRUE; } static bool cmd_foreverypart_end_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED) { unsigned int pc = *address; sieve_offset_t offset; sieve_code_dumpf(denv, "FOREVERYPART_END"); sieve_code_descend(denv); if ( !sieve_binary_read_offset(denv->sblock, address, &offset) ) return FALSE; sieve_code_dumpf(denv, "BEGIN: -%d [%08x]", offset, pc - offset); return TRUE; } /* * Code execution */ static int cmd_foreverypart_begin_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_interpreter_loop *loop; struct ext_foreverypart_runtime_loop *fploop, *sfploop; unsigned int pc = *address; sieve_offset_t offset; sieve_size_t loop_end; pool_t pool; int ret; /* * Read operands */ if ( !sieve_binary_read_offset(renv->sblock, address, &offset) ) { sieve_runtime_trace_error(renv, "invalid loop end offset"); return SIEVE_EXEC_BIN_CORRUPT; } loop_end = pc + offset; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "foreverypart loop begin"); sieve_runtime_trace_descend(renv); sfploop = ext_foreverypart_runtime_loop_get_current(renv); if ( (ret=sieve_interpreter_loop_start(renv->interp, loop_end, &foreverypart_extension, &loop)) <= 0 ) return ret; pool = sieve_interpreter_loop_get_pool(loop); fploop = p_new(pool, struct ext_foreverypart_runtime_loop, 1); if ( sfploop == NULL ) { if ( (ret=sieve_message_part_iter_init (&fploop->part_iter, renv)) <= 0 ) return ret; } else { sieve_message_part_iter_children(&sfploop->part_iter, &fploop->part_iter); } fploop->part = sieve_message_part_iter_current(&fploop->part_iter); if (fploop->part != NULL) { sieve_interpreter_loop_set_context(loop, fploop); } else { /* No children parts to iterate */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "no children at this level"); sieve_interpreter_loop_break(renv->interp, loop); } return SIEVE_EXEC_OK; } static int cmd_foreverypart_end_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_interpreter_loop *loop; struct ext_foreverypart_runtime_loop *fploop; unsigned int pc = *address; sieve_offset_t offset; sieve_size_t loop_begin; /* * Read operands */ if ( !sieve_binary_read_offset(renv->sblock, address, &offset) ) { sieve_runtime_trace_error(renv, "invalid loop begin offset"); return SIEVE_EXEC_BIN_CORRUPT; } loop_begin = pc - offset; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "foreverypart loop end"); sieve_runtime_trace_descend(renv); loop = sieve_interpreter_loop_get (renv->interp, *address, &foreverypart_extension); if ( loop == NULL ) { sieve_runtime_trace_error(renv, "no matching loop found"); return SIEVE_EXEC_BIN_CORRUPT; } fploop = (struct ext_foreverypart_runtime_loop *) sieve_interpreter_loop_get_context(loop); i_assert(fploop->part != NULL); fploop->part = sieve_message_part_iter_next(&fploop->part_iter); if ( fploop->part == NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "no more message parts"); return sieve_interpreter_loop_break(renv->interp, loop); } sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "switched to next message part"); return sieve_interpreter_loop_next(renv->interp, loop, loop_begin); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/ext-extracttext.c0000644000175100001700000000662015100335616027402 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension extracttext * --------------------- * * Authors: Stephan Bosch * Specification: RFC 5703, Section 7 * Implementation: full * Status: experimental * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "sieve-ext-variables.h" #include "ext-mime-common.h" /* * Extension */ static int ext_extracttext_load(const struct sieve_extension *ext, void **context_r); static void ext_extracttext_unload(const struct sieve_extension *ext); static bool ext_extracttext_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def extracttext_extension = { .name = "extracttext", .load = ext_extracttext_load, .unload = ext_extracttext_unload, .validator_load = ext_extracttext_validator_load, SIEVE_EXT_DEFINE_OPERATION(extracttext_operation), }; static int ext_extracttext_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct sieve_extension *var_ext; const struct sieve_extension *fep_ext; struct ext_extracttext_context *extctx; if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0) return -1; if (sieve_extension_register(svinst, &foreverypart_extension, FALSE, &fep_ext) < 0) return -1; extctx = i_new(struct ext_extracttext_context, 1); extctx->var_ext = var_ext; extctx->fep_ext = fep_ext; *context_r = extctx; return 0; } static void ext_extracttext_unload(const struct sieve_extension *ext) { struct ext_extracttext_context *extctx = ext->context; i_free(extctx); } /* * Extension validation */ static bool ext_extracttext_validator_validate( const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, bool required); const struct sieve_validator_extension extracttext_validator_extension = { .ext = &extracttext_extension, .validate = ext_extracttext_validator_validate, }; static bool ext_extracttext_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register validator extension to check for conflict with eextracttext. */ sieve_validator_extension_register( valdtr, ext, &extracttext_validator_extension, NULL); /* Register new commands */ sieve_validator_register_command(valdtr, ext, &cmd_extracttext); return TRUE; } static bool ext_extracttext_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg, bool required ATTR_UNUSED) { struct ext_extracttext_context *extctx = ext->context; if (extctx->var_ext == NULL || !sieve_ext_variables_is_active(extctx->var_ext, valdtr) ) { sieve_argument_validate_error( valdtr, require_arg, "extracttext extension cannot be used " "without variables extension"); return FALSE; } if (extctx->fep_ext == NULL || !sieve_validator_extension_loaded(valdtr, extctx->fep_ext) ) { sieve_argument_validate_error( valdtr, require_arg, "extracttext extension cannot be used " "without foreverypart extension"); return FALSE; } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/Makefile.am0000644000175100001700000000071115100335616026110 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_mime.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-foreverypart.c \ cmd-break.c \ cmd-extracttext.c tags = \ tag-mime.c extensions = \ ext-mime.c \ ext-foreverypart.c \ ext-extracttext.c libsieve_ext_mime_la_SOURCES = \ ext-mime-common.c \ $(commands) \ $(tags) \ $(extensions) noinst_HEADERS = \ ext-mime-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/ext-foreverypart.c0000644000175100001700000000252715100335616027555 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension foreverypart * ---------------------- * * Authors: Stephan Bosch * Specification: RFC 5703, Section 3 * Implementation: full * Status: experimental * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "ext-mime-common.h" /* * Operations */ const struct sieve_operation_def *ext_foreverypart_operations[] = { &foreverypart_begin_operation, &foreverypart_end_operation, &break_operation }; /* * Extension */ static bool ext_foreverypart_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def foreverypart_extension = { .name = "foreverypart", .validator_load = ext_foreverypart_validator_load, SIEVE_EXT_DEFINE_OPERATIONS(ext_foreverypart_operations) }; /* * Extension validation */ static bool ext_foreverypart_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new commands */ sieve_validator_register_command(valdtr, ext, &cmd_foreverypart); sieve_validator_register_command(valdtr, ext, &cmd_break); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/Makefile.in0000644000175100001700000005706015100335630026126 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/mime ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_mime_la_LIBADD = am__objects_1 = cmd-foreverypart.lo cmd-break.lo cmd-extracttext.lo am__objects_2 = tag-mime.lo am__objects_3 = ext-mime.lo ext-foreverypart.lo ext-extracttext.lo am_libsieve_ext_mime_la_OBJECTS = ext-mime-common.lo $(am__objects_1) \ $(am__objects_2) $(am__objects_3) libsieve_ext_mime_la_OBJECTS = $(am_libsieve_ext_mime_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-break.Plo \ ./$(DEPDIR)/cmd-extracttext.Plo \ ./$(DEPDIR)/cmd-foreverypart.Plo \ ./$(DEPDIR)/ext-extracttext.Plo \ ./$(DEPDIR)/ext-foreverypart.Plo \ ./$(DEPDIR)/ext-mime-common.Plo ./$(DEPDIR)/ext-mime.Plo \ ./$(DEPDIR)/tag-mime.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_mime_la_SOURCES) DIST_SOURCES = $(libsieve_ext_mime_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_mime.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-foreverypart.c \ cmd-break.c \ cmd-extracttext.c tags = \ tag-mime.c extensions = \ ext-mime.c \ ext-foreverypart.c \ ext-extracttext.c libsieve_ext_mime_la_SOURCES = \ ext-mime-common.c \ $(commands) \ $(tags) \ $(extensions) noinst_HEADERS = \ ext-mime-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/mime/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/mime/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_mime.la: $(libsieve_ext_mime_la_OBJECTS) $(libsieve_ext_mime_la_DEPENDENCIES) $(EXTRA_libsieve_ext_mime_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_mime_la_OBJECTS) $(libsieve_ext_mime_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-break.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-extracttext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-foreverypart.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-extracttext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-foreverypart.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-mime-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-mime.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-mime.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-break.Plo -rm -f ./$(DEPDIR)/cmd-extracttext.Plo -rm -f ./$(DEPDIR)/cmd-foreverypart.Plo -rm -f ./$(DEPDIR)/ext-extracttext.Plo -rm -f ./$(DEPDIR)/ext-foreverypart.Plo -rm -f ./$(DEPDIR)/ext-mime-common.Plo -rm -f ./$(DEPDIR)/ext-mime.Plo -rm -f ./$(DEPDIR)/tag-mime.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-break.Plo -rm -f ./$(DEPDIR)/cmd-extracttext.Plo -rm -f ./$(DEPDIR)/cmd-foreverypart.Plo -rm -f ./$(DEPDIR)/ext-extracttext.Plo -rm -f ./$(DEPDIR)/ext-foreverypart.Plo -rm -f ./$(DEPDIR)/ext-mime-common.Plo -rm -f ./$(DEPDIR)/ext-mime.Plo -rm -f ./$(DEPDIR)/tag-mime.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/ext-mime-common.h0000644000175100001700000000372515100335616027250 0ustar00buildbotbuildbot00000000000000#ifndef EXT_FOREVERYPART_COMMON_H #define EXT_FOREVERYPART_COMMON_H #include "sieve-message.h" /* * Extension */ struct ext_extracttext_context { const struct sieve_extension *var_ext; const struct sieve_extension *fep_ext; }; extern const struct sieve_extension_def foreverypart_extension; extern const struct sieve_extension_def mime_extension; extern const struct sieve_extension_def extracttext_extension; /* * Tagged arguments */ extern const struct sieve_argument_def mime_tag; extern const struct sieve_argument_def mime_anychild_tag; extern const struct sieve_argument_def mime_type_tag; extern const struct sieve_argument_def mime_subtype_tag; extern const struct sieve_argument_def mime_contenttype_tag; extern const struct sieve_argument_def mime_param_tag; /* * Commands */ struct ext_foreverypart_loop { const char *name; struct sieve_jumplist *exit_jumps; }; extern const struct sieve_command_def cmd_foreverypart; extern const struct sieve_command_def cmd_break; extern const struct sieve_command_def cmd_extracttext; /* * Operations */ extern const struct sieve_operation_def foreverypart_begin_operation; extern const struct sieve_operation_def foreverypart_end_operation; extern const struct sieve_operation_def break_operation; extern const struct sieve_operation_def extracttext_operation; enum ext_foreverypart_opcode { EXT_FOREVERYPART_OPERATION_FOREVERYPART_BEGIN, EXT_FOREVERYPART_OPERATION_FOREVERYPART_END, EXT_FOREVERYPART_OPERATION_BREAK, }; /* * Operands */ enum ext_mime_option { EXT_MIME_OPTION_NONE = 0, EXT_MIME_OPTION_TYPE, EXT_MIME_OPTION_SUBTYPE, EXT_MIME_OPTION_CONTENTTYPE, EXT_MIME_OPTION_PARAM }; extern const struct sieve_operand_def mime_operand; /* * Foreverypart loop */ struct ext_foreverypart_runtime_loop { struct sieve_message_part_iter part_iter; struct sieve_message_part *part; }; struct ext_foreverypart_runtime_loop * ext_foreverypart_runtime_loop_get_current (const struct sieve_runtime_env *renv); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/ext-mime.c0000644000175100001700000000420415100335616025746 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension mime * -------------- * * Authors: Stephan Bosch * Specification: RFC 5703, Section 4 * Implementation: full * Status: experimental * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-message.h" #include "sieve-result.h" #include "ext-mime-common.h" /* * Extension */ static bool ext_mime_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def mime_extension = { .name = "mime", .validator_load = ext_mime_validator_load, SIEVE_EXT_DEFINE_OPERAND(mime_operand) }; /* * Extension validation */ static bool ext_mime_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register :mime tag and friends with header, address and exists test * commands and we don't care whether these command are registered or * even whether these will be registered at all. The validator handles * either situation gracefully. */ sieve_validator_register_external_tag (valdtr, "header", ext, &mime_tag, SIEVE_OPT_MESSAGE_OVERRIDE); sieve_validator_register_external_tag (valdtr, "header", ext, &mime_anychild_tag, 0); sieve_validator_register_external_tag (valdtr, "header", ext, &mime_type_tag, 0); sieve_validator_register_external_tag (valdtr, "header", ext, &mime_subtype_tag, 0); sieve_validator_register_external_tag (valdtr, "header", ext, &mime_contenttype_tag, 0); sieve_validator_register_external_tag (valdtr, "header", ext, &mime_param_tag, 0); sieve_validator_register_external_tag (valdtr, "address", ext, &mime_tag, SIEVE_OPT_MESSAGE_OVERRIDE); sieve_validator_register_external_tag (valdtr, "address", ext, &mime_anychild_tag, 0); sieve_validator_register_external_tag (valdtr, "exists", ext, &mime_tag, SIEVE_OPT_MESSAGE_OVERRIDE); sieve_validator_register_external_tag (valdtr, "exists", ext, &mime_anychild_tag, 0); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/tag-mime.c0000644000175100001700000004325115100335616025726 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "rfc822-parser.h" #include "rfc2231-parser.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-result.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "ext-mime-common.h" /* * Tagged argument */ static bool tag_mime_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_mime_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); const struct sieve_argument_def mime_tag = { .identifier = "mime", .validate = tag_mime_validate, .generate = tag_mime_generate, }; static bool tag_mime_option_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); const struct sieve_argument_def mime_anychild_tag = { .identifier = "anychild", .validate = tag_mime_option_validate, }; const struct sieve_argument_def mime_type_tag = { .identifier = "type", .validate = tag_mime_option_validate, }; const struct sieve_argument_def mime_subtype_tag = { .identifier = "subtype", .validate = tag_mime_option_validate, }; const struct sieve_argument_def mime_contenttype_tag = { .identifier = "contenttype", .validate = tag_mime_option_validate, }; const struct sieve_argument_def mime_param_tag = { .identifier = "param", .validate = tag_mime_option_validate, }; /* * Header override */ static bool svmo_mime_dump_context(const struct sieve_message_override *svmo, const struct sieve_dumptime_env *denv, sieve_size_t *address); static int svmo_mime_read_context(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, sieve_size_t *address, void **ho_context); static int svmo_mime_header_override(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, bool mime_decode, struct sieve_stringlist **headers); const struct sieve_message_override_def mime_header_override = { SIEVE_OBJECT("mime", &mime_operand, 0), .sequence = 0, /* Completely replace header source */ .dump_context = svmo_mime_dump_context, .read_context = svmo_mime_read_context, .header_override = svmo_mime_header_override, }; /* * Operand */ static const struct sieve_extension_objects ext_header_overrides = SIEVE_EXT_DEFINE_MESSAGE_OVERRIDE(mime_header_override); const struct sieve_operand_def mime_operand = { .name = "mime operand", .ext_def = &mime_extension, .class = &sieve_message_override_operand_class, .interface = &ext_header_overrides, }; /* * Tag data */ struct tag_mime_data { enum ext_mime_option mimeopt; struct sieve_ast_argument *param_arg; bool anychild:1; }; /* * Tag validation */ static struct tag_mime_data * tag_mime_get_data(struct sieve_command *cmd, struct sieve_ast_argument *tag) { struct tag_mime_data *data; if (tag->argument->data == NULL) { data = p_new(sieve_command_pool(cmd), struct tag_mime_data, 1); tag->argument->data = data; } else { data = (struct tag_mime_data *)tag->argument->data; } return data; } static bool tag_mime_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; /* Skip the tag itself */ *arg = sieve_ast_argument_next(*arg); (void)tag_mime_get_data(cmd, tag); return TRUE; } static bool tag_mime_option_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct sieve_ast_argument *mime_arg; struct tag_mime_data *data; i_assert(tag != NULL); /* Detach tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Find required ":mime" tag */ mime_arg = sieve_command_find_argument(cmd, &mime_tag); if (mime_arg == NULL) { sieve_argument_validate_error( valdtr, tag, "the :%s tag for the %s %s cannot be specified " "without the :mime tag", sieve_ast_argument_tag(tag), sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* Annotate ":mime" tag with the data provided by this option tag */ data = tag_mime_get_data(cmd, mime_arg); if (sieve_argument_is(tag, mime_anychild_tag)) data->anychild = TRUE; else { if (data->mimeopt != EXT_MIME_OPTION_NONE) { sieve_argument_validate_error( valdtr, *arg, "the :type, :subtype, :contenttype, and :param " "arguments for the %s test are mutually exclusive, " "but more than one was specified", sieve_command_identifier(cmd)); return FALSE; } if (sieve_argument_is(tag, mime_type_tag)) data->mimeopt = EXT_MIME_OPTION_TYPE; else if (sieve_argument_is(tag, mime_subtype_tag)) data->mimeopt = EXT_MIME_OPTION_SUBTYPE; else if (sieve_argument_is(tag, mime_contenttype_tag)) data->mimeopt = EXT_MIME_OPTION_CONTENTTYPE; else if (sieve_argument_is(tag, mime_param_tag)) { /* Check syntax: ":param" */ if (!sieve_validate_tag_parameter( valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING_LIST, FALSE)) return FALSE; data->mimeopt = EXT_MIME_OPTION_PARAM; data->param_arg = *arg; /* Detach parameter */ *arg = sieve_ast_arguments_detach(*arg,1); } else { i_unreached(); } } return TRUE; } /* * Code generation */ static bool tag_mime_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { struct tag_mime_data *data = (struct tag_mime_data *)arg->argument->data; if (sieve_ast_argument_type(arg) != SAAT_TAG) return FALSE; sieve_opr_message_override_emit(cgenv->sblock, arg->argument->ext, &mime_header_override); (void)sieve_binary_emit_byte(cgenv->sblock, (data->anychild ? 1 : 0)); (void)sieve_binary_emit_byte(cgenv->sblock, data->mimeopt); if (data->mimeopt == EXT_MIME_OPTION_PARAM && !sieve_generate_argument(cgenv, data->param_arg, cmd)) return FALSE; return TRUE; } /* * Content-type stringlist */ enum content_type_part { CONTENT_TYPE_PART_NONE = 0, CONTENT_TYPE_PART_TYPE, CONTENT_TYPE_PART_SUBTYPE, CONTENT_TYPE_PART_CONTENTTYPE, }; /* Object */ static int content_header_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void content_header_stringlist_reset(struct sieve_stringlist *_strlist); static int content_header_stringlist_get_length(struct sieve_stringlist *_strlist); static void content_header_stringlist_set_trace(struct sieve_stringlist *strlist, bool trace); struct content_header_stringlist { struct sieve_stringlist strlist; struct sieve_header_list *source; enum ext_mime_option option; const char *const *params; const char *const *param_values; }; static struct sieve_stringlist * content_header_stringlist_create(const struct sieve_runtime_env *renv, struct sieve_header_list *source, enum ext_mime_option option, const char *const *params) { struct content_header_stringlist *strlist; strlist = t_new(struct content_header_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = content_header_stringlist_next_item; strlist->strlist.reset = content_header_stringlist_reset; strlist->strlist.set_trace = content_header_stringlist_set_trace; strlist->source = source; strlist->option = option; strlist->params = params; if (option != EXT_MIME_OPTION_PARAM) { /* One header can have multiple parameters, so we cannot rely on the source length for the :param option. */ strlist->strlist.get_length = content_header_stringlist_get_length; } return &strlist->strlist; } /* Implementation */ static string_t * content_type_param_next(struct content_header_stringlist *strlist) { const struct sieve_runtime_env *renv = strlist->strlist.runenv; const char *const *values = strlist->param_values; bool trace = strlist->strlist.trace; i_assert(strlist->params != NULL); /* Iterate over all parsed parameter values */ for (; *values != NULL; values += 2) { const char *const *params = strlist->params; const char *name = values[0], *value = values[1]; size_t nlen = strlen(name); /* Iterate over all interesting parameter names */ for (; *params != NULL; params++) { const size_t plen = strlen(*params); if (plen != nlen && (nlen != plen + 1 || name[nlen-1] != '*')) continue; if (plen == nlen) { if (strcasecmp(name, *params) == 0) { /* Return raw value */ if (trace) { sieve_runtime_trace(renv, 0, "found mime parameter '%s' in mime header", *params); } strlist->param_values = values + 2; return t_str_new_const(value, strlen(value)); } } } } strlist->param_values = NULL; return NULL; } // FIXME: not too happy with the use of string_t like this. // Sieve should have a special runtime string type (TODO) static string_t * content_header_parse(struct content_header_stringlist *strlist, const char *hdr_name, string_t *str) { const struct sieve_runtime_env *renv = strlist->strlist.runenv; bool trace = strlist->strlist.trace; struct rfc822_parser_context parser; const char *type, *p; bool is_ctype = FALSE; string_t *content; if (strlist->option == EXT_MIME_OPTION_NONE) return str; if (strcasecmp(hdr_name, "content-type") == 0) is_ctype = TRUE; else if (strcasecmp(hdr_name, "content-disposition") != 0) { if (trace) { sieve_runtime_trace( renv, 0, "non-mime header yields empty string"); } return t_str_new(0); } /* Initialize parsing */ rfc822_parser_init(&parser, str_data(str), str_len(str), NULL); (void)rfc822_skip_lwsp(&parser); /* Parse content type/disposition */ content = t_str_new(64); if (is_ctype) { if (rfc822_parse_content_type(&parser, content) < 0) { str_truncate(content, 0); return content; } } else { if (rfc822_parse_mime_token(&parser, content) < 0) { str_truncate(content, 0); return content; } } /* Content-type value must end here, otherwise it is invalid after all */ (void)rfc822_skip_lwsp(&parser); if (parser.data != parser.end && *parser.data != ';') { str_truncate(content, 0); return content; } if (strlist->option == EXT_MIME_OPTION_PARAM) { string_t *param_val; /* MIME parameter */ i_assert(strlist->params != NULL); // FIXME: not very nice when multiple parameters in the same header // are queried in successive tests. str_truncate(content, 0); rfc2231_parse(&parser, &strlist->param_values); param_val = content_type_param_next(strlist); if (param_val != NULL) content = param_val; } else { /* Get :type/:subtype:/:contenttype value */ type = str_c(content); p = strchr(type, '/'); switch (strlist->option) { case EXT_MIME_OPTION_TYPE: if (trace) { sieve_runtime_trace( renv, 0, "extracted MIME type"); } if (p != NULL) { i_assert(is_ctype); str_truncate(content, (p - type)); } break; case EXT_MIME_OPTION_SUBTYPE: if (p == NULL) { i_assert(!is_ctype); if (trace) { sieve_runtime_trace( renv, 0, "no MIME sub-type for content-disposition"); } str_truncate(content, 0); break; } i_assert(is_ctype); if (trace) { sieve_runtime_trace( renv, 0, "extracted MIME sub-type"); } str_delete(content, 0, (p - type) + 1); break; case EXT_MIME_OPTION_CONTENTTYPE: sieve_runtime_trace( renv, 0, "extracted full MIME contenttype"); break; default: break; } } /* Success */ return content; } static int content_header_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct content_header_stringlist *strlist = (struct content_header_stringlist *)_strlist; const char *hdr_name; int ret; if (strlist->param_values != NULL) { string_t *param_val; i_assert(strlist->option == EXT_MIME_OPTION_PARAM); param_val = content_type_param_next(strlist); if (param_val != NULL) { *str_r = param_val; return 1; } } ret = sieve_header_list_next_item(strlist->source, &hdr_name, str_r); if (ret <= 0) { if (ret < 0) { _strlist->exec_status = strlist->source->strlist.exec_status; } return ret; } *str_r = content_header_parse(strlist, hdr_name, *str_r); return 1; } static void content_header_stringlist_reset(struct sieve_stringlist *_strlist) { struct content_header_stringlist *strlist = (struct content_header_stringlist *)_strlist; sieve_header_list_reset(strlist->source); } static int content_header_stringlist_get_length(struct sieve_stringlist *_strlist) { struct content_header_stringlist *strlist = (struct content_header_stringlist *)_strlist; return sieve_header_list_get_length(strlist->source); } static void content_header_stringlist_set_trace(struct sieve_stringlist *_strlist, bool trace) { struct content_header_stringlist *strlist = (struct content_header_stringlist *)_strlist; sieve_header_list_set_trace(strlist->source, trace); } /* * Header override implementation */ /* Context data */ struct svmo_mime_context { enum ext_mime_option mimeopt; const char *const *params; bool anychild:1; }; /* Context coding */ static bool svmo_mime_dump_context(const struct sieve_message_override *svmo ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int anychild, mimeopt; if (!sieve_binary_read_byte(denv->sblock, address, &anychild)) return FALSE; if (anychild > 0) sieve_code_dumpf(denv, "anychild"); if (!sieve_binary_read_byte(denv->sblock, address, &mimeopt)) return FALSE; switch (mimeopt) { case EXT_MIME_OPTION_NONE: break; case EXT_MIME_OPTION_TYPE: sieve_code_dumpf(denv, "option: type"); break; case EXT_MIME_OPTION_SUBTYPE: sieve_code_dumpf(denv, "option: subtype"); break; case EXT_MIME_OPTION_CONTENTTYPE: sieve_code_dumpf(denv, "option: contenttype"); break; case EXT_MIME_OPTION_PARAM: sieve_code_dumpf(denv, "option: param"); sieve_code_descend(denv); if (!sieve_opr_stringlist_dump(denv, address, "param-list")) return FALSE; sieve_code_ascend(denv); break; default: return FALSE; } return TRUE; } static int svmo_mime_read_context(const struct sieve_message_override *svmo ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address, void **ho_context) { pool_t pool = sieve_result_pool(renv->result); // FIXME: investigate struct svmo_mime_context *ctx; unsigned int anychild = 0, mimeopt = EXT_MIME_OPTION_NONE; struct sieve_stringlist *param_list = NULL; int ret; if (!sieve_binary_read_byte(renv->sblock, address, &anychild)) { sieve_runtime_trace_error(renv, "anychild: invalid byte"); return SIEVE_EXEC_BIN_CORRUPT; } if (!sieve_binary_read_byte(renv->sblock, address, &mimeopt) || mimeopt > EXT_MIME_OPTION_PARAM) { sieve_runtime_trace_error( renv, "option: invalid mime option code"); return SIEVE_EXEC_BIN_CORRUPT; } if (mimeopt == EXT_MIME_OPTION_PARAM && (ret = sieve_opr_stringlist_read(renv, address, "param-list", ¶m_list)) <= 0) return ret; ctx = p_new(pool, struct svmo_mime_context, 1); ctx->anychild = (anychild == 0 ? FALSE : TRUE); ctx->mimeopt = (enum ext_mime_option)mimeopt; if (param_list != NULL && sieve_stringlist_read_all(param_list, pool, &ctx->params) < 0) { sieve_runtime_trace_error( renv, "failed to read param-list operand"); return param_list->exec_status; } *ho_context = ctx; return SIEVE_EXEC_OK; } /* Override */ static int svmo_mime_header_override(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, bool mime_decode, struct sieve_stringlist **headers_r) { struct svmo_mime_context *ctx = (struct svmo_mime_context *)svmo->context; struct ext_foreverypart_runtime_loop *sfploop; struct sieve_header_list *headers; struct sieve_stringlist *values; int ret; sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "header mime override:"); sieve_runtime_trace_descend(renv); if (ctx->anychild) { sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "headers from current mime part and children"); } else { sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "headers from current mime part"); } sfploop = ext_foreverypart_runtime_loop_get_current(renv); if (sfploop != NULL) { headers = sieve_mime_header_list_create( renv, *headers_r, &sfploop->part_iter, mime_decode, ctx->anychild); } else if (ctx->anychild) { struct sieve_message_part_iter part_iter; ret = sieve_message_part_iter_init(&part_iter, renv); if (ret <= 0) return ret; headers = sieve_mime_header_list_create( renv, *headers_r, &part_iter, mime_decode, TRUE); } else { headers = sieve_message_header_list_create( renv, *headers_r, mime_decode); } values = &headers->strlist; switch (ctx->mimeopt) { case EXT_MIME_OPTION_NONE: break; case EXT_MIME_OPTION_TYPE: sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "extract mime type from header value"); break; case EXT_MIME_OPTION_SUBTYPE: sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "extract mime subtype from header value"); break; case EXT_MIME_OPTION_CONTENTTYPE: sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "extract mime contenttype from header value"); break; case EXT_MIME_OPTION_PARAM: sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "extract mime parameters from header value"); break; default: i_unreached(); } if (ctx->mimeopt != EXT_MIME_OPTION_NONE) { values = content_header_stringlist_create( renv, headers, ctx->mimeopt, ctx->params); } *headers_r = values; sieve_runtime_trace_ascend(renv); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/cmd-extracttext.c0000644000175100001700000002151615100335616027346 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "array.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-ast.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-message.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-mime-common.h" /* * Extracttext command * * Syntax: * extracttext [MODIFIER] [":first" number] */ static bool cmd_extracttext_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_extracttext_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_extracttext_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def cmd_extracttext = { .identifier = "extracttext", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_extracttext_registered, .validate = cmd_extracttext_validate, .generate = cmd_extracttext_generate, }; /* * Extracttext command tags */ enum cmd_extracttext_optional { CMD_EXTRACTTEXT_OPT_END, CMD_EXTRACTTEXT_OPT_FIRST }; static bool cmd_extracttext_validate_first_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static const struct sieve_argument_def extracttext_from_tag = { .identifier = "first", .validate = cmd_extracttext_validate_first_tag, }; /* * Extracttext operation */ static bool cmd_extracttext_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_extracttext_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def extracttext_operation = { .mnemonic = "EXTRACTTEXT", .ext_def = &extracttext_extension, .dump = cmd_extracttext_operation_dump, .execute = cmd_extracttext_operation_execute, }; /* * Compiler context */ struct cmd_extracttext_context { ARRAY_TYPE(sieve_variables_modifier) modifiers; }; /* * Tag validation */ static bool cmd_extracttext_validate_first_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :first */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_NUMBER, FALSE) ) return FALSE; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } /* Command registration */ static bool cmd_extracttext_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { struct ext_extracttext_context *extctx = ext->context; sieve_validator_register_tag(valdtr, cmd_reg, ext, &extracttext_from_tag, CMD_EXTRACTTEXT_OPT_FIRST); sieve_variables_modifiers_link_tag(valdtr, extctx->var_ext, cmd_reg); return TRUE; } /* * Command validation */ static bool cmd_extracttext_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct ext_extracttext_context *extctx = this_ext->context; struct sieve_ast_node *node = cmd->ast_node; struct sieve_ast_argument *arg = cmd->first_positional; pool_t pool = sieve_command_pool(cmd); struct cmd_extracttext_context *sctx; /* Create command context */ sctx = p_new(pool, struct cmd_extracttext_context, 1); p_array_init(&sctx->modifiers, pool, 4); cmd->data = sctx; /* Validate modifiers */ if (!sieve_variables_modifiers_validate(valdtr, cmd, &sctx->modifiers)) return FALSE; /* Validate varname argument */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "varname", 1, SAAT_STRING)) return FALSE; if (!sieve_variable_argument_activate(extctx->var_ext, extctx->var_ext, valdtr, cmd, arg, TRUE)) return FALSE; /* Check foreverypart context */ i_assert(node != NULL); while (node != NULL) { if (node->command != NULL && sieve_command_is(node->command, cmd_foreverypart)) break; node = sieve_ast_node_parent(node); } if (node == NULL) { sieve_command_validate_error( valdtr, cmd, "the extracttext command is not placed inside " "a foreverypart loop"); return FALSE; } return TRUE; } /* * Code generation */ static bool cmd_extracttext_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_binary_block *sblock = cgenv->sblock; struct cmd_extracttext_context *sctx = (struct cmd_extracttext_context *) cmd->data; sieve_operation_emit(sblock, this_ext, &extracttext_operation); /* Generate arguments */ if (!sieve_generate_arguments(cgenv, cmd, NULL)) return FALSE; /* Generate modifiers */ if (!sieve_variables_modifiers_generate(cgenv, &sctx->modifiers)) return FALSE; return TRUE; } /* * Code dump */ static bool cmd_extracttext_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "EXTRACTTEXT"); sieve_code_descend(denv); /* Dump optional operands */ for (;;) { int opt; bool opok = TRUE; opt = sieve_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case CMD_EXTRACTTEXT_OPT_FIRST: opok = sieve_opr_number_dump(denv, address, "first"); break; default: return FALSE; } if (!opok) return FALSE; } /* Print both variable name and string value */ if (!sieve_opr_string_dump(denv, address, "varname")) return FALSE; return sieve_variables_modifiers_code_dump(denv, address); } /* * Code execution */ static int cmd_extracttext_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_extracttext_context *extctx = this_ext->context; struct sieve_variable_storage *storage; ARRAY_TYPE(sieve_variables_modifier) modifiers; struct ext_foreverypart_runtime_loop *sfploop; struct sieve_message_part *mpart; struct sieve_message_part_data mpart_data; int opt_code = 0; sieve_number_t first = 0; string_t *value; unsigned int var_index; bool have_first = FALSE; int ret = SIEVE_EXEC_OK; /* * Read the normal operands */ /* Optional operands */ for (;;) { int opt; opt = sieve_opr_optional_read(renv, address, &opt_code); if (opt < 0) return SIEVE_EXEC_BIN_CORRUPT; if (opt == 0) break; switch (opt_code) { case CMD_EXTRACTTEXT_OPT_FIRST: ret = sieve_opr_number_read(renv, address, "first", &first); have_first = TRUE; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } if (ret <= 0) return ret; } /* Varname operand */ ret = sieve_variable_operand_read(renv, address, "varname", &storage, &var_index); if (ret <= 0) return ret; /* Modifiers */ ret = sieve_variables_modifiers_code_read(renv, extctx->var_ext, address, &modifiers); if (ret <= 0) return ret; /* * Determine and assign the value */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "extracttext command"); sieve_runtime_trace_descend(renv); sfploop = ext_foreverypart_runtime_loop_get_current(renv); if (sfploop == NULL) { sieve_runtime_trace_error(renv, "outside foreverypart context"); return SIEVE_EXEC_BIN_CORRUPT; } /* Get current message part */ mpart = sieve_message_part_iter_current(&sfploop->part_iter); i_assert(mpart != NULL); /* Get message part content */ sieve_message_part_get_data(mpart, &mpart_data, TRUE); /* Apply ":first" limit, if any */ if (!have_first || (size_t)first > mpart_data.size) { value = t_str_new_const(mpart_data.content, mpart_data.size); } else { value = t_str_new((size_t)first); str_append_data(value, mpart_data.content, (size_t)first); } /* Apply modifiers */ ret = sieve_variables_modifiers_apply(renv, extctx->var_ext, &modifiers, &value); if (ret <= 0) return ret; /* Actually assign the value if all is well */ i_assert (value != NULL); if (!sieve_variable_assign(storage, var_index, value)) return SIEVE_EXEC_BIN_CORRUPT; /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { const char *var_name, *var_id; (void)sieve_variable_get_identifier(storage, var_index, &var_name); var_id = sieve_variable_get_varid(storage, var_index); sieve_runtime_trace_here(renv, 0, "assign '%s' [%s] = \"%s\"", var_name, var_id, str_c(value)); } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/mime/ext-mime-common.c0000644000175100001700000000124015100335616027231 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-interpreter.h" #include "ext-mime-common.h" struct ext_foreverypart_runtime_loop * ext_foreverypart_runtime_loop_get_current (const struct sieve_runtime_env *renv) { struct sieve_interpreter_loop *loop; struct ext_foreverypart_runtime_loop *fploop; loop = sieve_interpreter_loop_get_global (renv->interp, NULL, &foreverypart_extension); if ( loop == NULL ) { fploop = NULL; } else { fploop = (struct ext_foreverypart_runtime_loop *) sieve_interpreter_loop_get_context(loop); i_assert(fploop->part != NULL); } return fploop; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/copy/0000755000175100001700000000000015100335670024100 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/copy/Makefile.am0000644000175100001700000000047015100335616026135 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_copy.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_copy_la_SOURCES = \ ext-copy.c public_headers = \ sieve-ext-copy.h headers = pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/copy/Makefile.in0000644000175100001700000006005215100335630026144 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/copy ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(pkginc_lib_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_copy_la_LIBADD = am_libsieve_ext_copy_la_OBJECTS = ext-copy.lo libsieve_ext_copy_la_OBJECTS = $(am_libsieve_ext_copy_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-copy.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_copy_la_SOURCES) DIST_SOURCES = $(libsieve_ext_copy_la_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(noinst_HEADERS) $(pkginc_lib_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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_copy.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_copy_la_SOURCES = \ ext-copy.c public_headers = \ sieve-ext-copy.h headers = pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/copy/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/copy/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_copy.la: $(libsieve_ext_copy_la_OBJECTS) $(libsieve_ext_copy_la_DEPENDENCIES) $(EXTRA_libsieve_ext_copy_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_copy_la_OBJECTS) $(libsieve_ext_copy_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-copy.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-copy.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-copy.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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-pkginc_libHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/copy/ext-copy.c0000644000175100001700000001056515100335616026023 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension copy * -------------- * * Authors: Stephan Bosch * Specification: RFC 3894 * Implementation: full * Status: testing * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "sieve-ext-copy.h" /* * Forward declarations */ static const struct sieve_argument_def copy_tag; static const struct sieve_operand_def copy_side_effect_operand; /* * Extension */ static bool ext_copy_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def copy_extension = { .name = "copy", .validator_load = ext_copy_validator_load, SIEVE_EXT_DEFINE_OPERAND(copy_side_effect_operand), }; static bool ext_copy_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register copy tag with redirect and fileinto commands and we don't care whether these commands are registered or even whether they will be registered at all. The validator handles either situation gracefully. */ sieve_validator_register_external_tag(valdtr, "redirect", ext, ©_tag, SIEVE_OPT_SIDE_EFFECT); sieve_validator_register_external_tag(valdtr, "fileinto", ext, ©_tag, SIEVE_OPT_SIDE_EFFECT); return TRUE; } /* * Side effect */ static void seff_copy_print(const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int seff_copy_post_execute(const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action_exec_env *aenv ATTR_UNUSED, void *tr_context ATTR_UNUSED, void *se_tr_context ATTR_UNUSED, bool *keep); const struct sieve_side_effect_def copy_side_effect = { SIEVE_OBJECT("copy", ©_side_effect_operand, 0), .to_action = &act_store, .print = seff_copy_print, .post_execute = seff_copy_post_execute, }; /* * Tagged argument */ static bool tag_copy_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_copy_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); static const struct sieve_argument_def copy_tag = { .identifier = "copy", .validate = tag_copy_validate, .generate = tag_copy_generate, }; /* * Operand */ static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(copy_side_effect); static const struct sieve_operand_def copy_side_effect_operand = { .name = "copy operand", .ext_def = ©_extension, .class = &sieve_side_effect_operand_class, .interface = &ext_side_effects, }; /* * Tag registration */ void sieve_ext_copy_register_tag(struct sieve_validator *valdtr, const struct sieve_extension *copy_ext, const char *command) { if (sieve_validator_extension_loaded(valdtr, copy_ext)) { sieve_validator_register_external_tag( valdtr, command, copy_ext, ©_tag, SIEVE_OPT_SIDE_EFFECT); } } /* * Tag validation */ static bool tag_copy_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg ATTR_UNUSED, struct sieve_command *cmd ATTR_UNUSED) { *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Code generation */ static bool tag_copy_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { if (sieve_ast_argument_type(arg) != SAAT_TAG) return FALSE; sieve_opr_side_effect_emit(cgenv->sblock, sieve_argument_ext(arg), ©_side_effect); return TRUE; } /* * Side effect implementation */ static void seff_copy_print(const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, const struct sieve_result_print_env *rpenv, bool *keep) { sieve_result_seffect_printf(rpenv, "preserve implicit keep"); *keep = TRUE; } static int seff_copy_post_execute(const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action_exec_env *aenv ATTR_UNUSED, void *tr_context ATTR_UNUSED, void *se_tr_context ATTR_UNUSED, bool *keep) { *keep = TRUE; return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/copy/sieve-ext-copy.h0000644000175100001700000000124115100335616027130 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXT_COPY_H #define SIEVE_EXT_COPY_H extern const struct sieve_extension_def copy_extension; /* sieve_ext_copy_get_extension(): * Get the extension struct for the copy extension. */ static inline int sieve_ext_copy_get_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_register(svinst, ©_extension, FALSE, ext_r); } /* sieve_ext_copy_register_tag(): * Register the :copy tagged argument for a command other than fileinto and * redirect. */ void sieve_ext_copy_register_tag (struct sieve_validator *valdtr, const struct sieve_extension *copy_ext, const char *command); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/0000755000175100001700000000000015100335670024222 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/ext-ihave-common.h0000644000175100001700000000161115100335616027552 0ustar00buildbotbuildbot00000000000000#ifndef EXT_IHAVE_COMMON_H #define EXT_IHAVE_COMMON_H #include "sieve-common.h" /* * Extensions */ extern const struct sieve_extension_def ihave_extension; /* * Tests */ extern const struct sieve_command_def ihave_test; /* * Commands */ extern const struct sieve_command_def error_command; /* * Operations */ enum ext_ihave_opcode { EXT_IHAVE_OPERATION_IHAVE, EXT_IHAVE_OPERATION_ERROR }; extern const struct sieve_operation_def tst_ihave_operation; extern const struct sieve_operation_def cmd_error_operation; /* * AST context */ struct ext_ihave_ast_context { ARRAY(const char *) missing_extensions; }; struct ext_ihave_ast_context * ext_ihave_get_ast_context(const struct sieve_extension *this_ext, struct sieve_ast *ast); void ext_ihave_ast_add_missing_extension(const struct sieve_extension *this_ext, struct sieve_ast *ast, const char *ext_name); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/Makefile.am0000644000175100001700000000052015100335616026253 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_ihave.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-ihave.c commands = \ cmd-error.c libsieve_ext_ihave_la_SOURCES = \ $(tests) \ $(commands) \ ext-ihave-binary.c \ ext-ihave-common.c \ ext-ihave.c noinst_HEADERS = \ ext-ihave-binary.h \ ext-ihave-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/ext-ihave-binary.c0000644000175100001700000001443015100335616027544 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-error.h" #include "sieve-script.h" #include "sieve-binary.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-ihave-common.h" #include "ext-ihave-binary.h" /* * Forward declarations */ static bool ext_ihave_binary_pre_save(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_error *error_code_r); static bool ext_ihave_binary_open(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); static bool ext_ihave_binary_up_to_date(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_compile_flags cpflags); /* * Binary include extension */ const struct sieve_binary_extension ihave_binary_ext = { .extension = &ihave_extension, .binary_pre_save = ext_ihave_binary_pre_save, .binary_open = ext_ihave_binary_open, .binary_up_to_date = ext_ihave_binary_up_to_date, }; /* * Binary context management */ struct ext_ihave_binary_context { struct sieve_binary *binary; struct sieve_binary_block *block; ARRAY(const char *) missing_extensions; }; static struct ext_ihave_binary_context * ext_ihave_binary_create_context(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { pool_t pool = sieve_binary_pool(sbin); struct ext_ihave_binary_context *ctx = p_new(pool, struct ext_ihave_binary_context, 1); ctx->binary = sbin; p_array_init(&ctx->missing_extensions, pool, 64); sieve_binary_extension_set(sbin, this_ext, &ihave_binary_ext, ctx); return ctx; } struct ext_ihave_binary_context * ext_ihave_binary_get_context(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { struct ext_ihave_binary_context *ctx = (struct ext_ihave_binary_context *) sieve_binary_extension_get_context(sbin, this_ext); if (ctx == NULL) ctx = ext_ihave_binary_create_context(this_ext, sbin); return ctx; } struct ext_ihave_binary_context * ext_ihave_binary_init(const struct sieve_extension *this_ext, struct sieve_binary *sbin, struct sieve_ast *ast) { struct ext_ihave_ast_context *ast_ctx = ext_ihave_get_ast_context(this_ext, ast); struct ext_ihave_binary_context *binctx; const char *const *exts; unsigned int i, count; binctx = ext_ihave_binary_get_context(this_ext, sbin); exts = array_get(&ast_ctx->missing_extensions, &count); if (count > 0) { pool_t pool = sieve_binary_pool(sbin); if (binctx->block == NULL) { binctx->block = sieve_binary_extension_create_block( sbin, this_ext); } for (i = 0; i < count; i++) { const char *ext_name = p_strdup(pool, exts[i]); array_append(&binctx->missing_extensions, &ext_name, 1); } } return binctx; } /* * Binary extension */ static bool ext_ihave_binary_pre_save(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_error *error_code_r ATTR_UNUSED) { struct ext_ihave_binary_context *binctx = (struct ext_ihave_binary_context *)context; const char *const *exts; unsigned int count, i; exts = array_get(&binctx->missing_extensions, &count); if (binctx->block != NULL) sieve_binary_block_clear(binctx->block); if (count > 0) { if (binctx->block == NULL) { binctx->block = sieve_binary_extension_create_block(sbin, ext); } sieve_binary_emit_unsigned(binctx->block, count); for (i = 0; i < count; i++) sieve_binary_emit_cstring(binctx->block, exts[i]); } return TRUE; } static bool ext_ihave_binary_open(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context) { struct sieve_instance *svinst = ext->svinst; struct ext_ihave_binary_context *binctx = (struct ext_ihave_binary_context *)context; struct sieve_binary_block *sblock; unsigned int i, count, block_id; sieve_size_t offset; sblock = sieve_binary_extension_get_block(sbin, ext); if (sblock != NULL) { binctx->block = sblock; block_id = sieve_binary_block_get_id(sblock); offset = 0; /* Read number of missing extensions to read subsequently */ if (!sieve_binary_read_unsigned(sblock, &offset, &count)) { e_error(svinst->event, "ihave: " "failed to read missing extension count " "from block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } /* Read dependencies */ for (i = 0; i < count; i++) { string_t *ext_name; const char *name; if (!sieve_binary_read_string(sblock, &offset, &ext_name)) { /* Binary is corrupt, recompile */ e_error(svinst->event, "ihave: " "failed to read missing extension name " "from block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } name = str_c(ext_name); array_append(&binctx->missing_extensions, &name, 1); } } return TRUE; } static bool ext_ihave_binary_up_to_date(const struct sieve_extension *ext, struct sieve_binary *sbin ATTR_UNUSED, void *context, enum sieve_compile_flags cpflags) { struct ext_ihave_binary_context *binctx = (struct ext_ihave_binary_context *)context; const struct sieve_extension *mext; const char *const *mexts; unsigned int count, i; mexts = array_get(&binctx->missing_extensions, &count); for (i = 0; i < count; i++) { mext = sieve_extension_get_by_name(ext->svinst, mexts[i]); if (mext != NULL && ((cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) == 0 || !mext->global)) return FALSE; } return TRUE; } /* * Main extension interface */ bool ext_ihave_binary_load(const struct sieve_extension *ext, struct sieve_binary *sbin) { (void)ext_ihave_binary_get_context(ext, sbin); return TRUE; } bool ext_ihave_binary_dump(const struct sieve_extension *ext, struct sieve_dumptime_env *denv) { struct sieve_binary *sbin = denv->sbin; struct ext_ihave_binary_context *binctx = ext_ihave_binary_get_context(ext, sbin); const char *const *exts; unsigned int count, i; exts = array_get(&binctx->missing_extensions, &count); if (count > 0) { sieve_binary_dump_sectionf( denv, "Extensions missing at compile (block: %d)", sieve_binary_block_get_id(binctx->block)); for (i = 0; i < count; i++) sieve_binary_dumpf(denv, " - %s\n", exts[i]); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/cmd-error.c0000644000175100001700000000531215100335616026261 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-ihave-common.h" /* * Error command * * Syntax * error */ static bool cmd_error_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool cmd_error_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def error_command = { .identifier = "error", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_error_validate, .generate = cmd_error_generate }; /* * Body operation */ static bool cmd_error_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_error_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def cmd_error_operation = { .mnemonic = "ERROR", .ext_def = &ihave_extension, .code = EXT_IHAVE_OPERATION_ERROR, .dump = cmd_error_operation_dump, .execute = cmd_error_operation_execute }; /* * Validation */ static bool cmd_error_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if ( !sieve_validate_positional_argument (valdtr, tst, arg, "message", 1, SAAT_STRING) ) { return FALSE; } return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* * Code generation */ static bool cmd_error_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &cmd_error_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_error_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "ERROR"); sieve_code_descend(denv); return sieve_opr_string_dump(denv, address, "message"); } /* * Interpretation */ static int cmd_error_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *message; int ret; /* * Read operands */ /* Read message */ if ( (ret=sieve_opr_string_read(renv, address, "message", &message)) <= 0 ) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "error \"%s\"", str_sanitize(str_c(message), 80)); sieve_runtime_error(renv, NULL, "%s", str_c(message)); return SIEVE_EXEC_FAILURE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/ext-ihave.c0000644000175100001700000000310115100335616026253 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension ihave * --------------- * * Authors: Stephan Bosch * Specification: RFC 5463 * Implementation: full * Status: testing * */ #include "lib.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "ext-ihave-common.h" #include "ext-ihave-binary.h" /* * Operations */ const struct sieve_operation_def *ext_ihave_operations[] = { &tst_ihave_operation, &cmd_error_operation }; /* * Extension */ static bool ext_ihave_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); static bool ext_ihave_generator_load (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); const struct sieve_extension_def ihave_extension = { "ihave", .version = 1, .validator_load = ext_ihave_validator_load, .generator_load = ext_ihave_generator_load, .binary_load = ext_ihave_binary_load, .binary_dump = ext_ihave_binary_dump, SIEVE_EXT_DEFINE_OPERATIONS(ext_ihave_operations) }; static bool ext_ihave_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator) { sieve_validator_register_command(validator, ext, &ihave_test); sieve_validator_register_command(validator, ext, &error_command); return TRUE; } static bool ext_ihave_generator_load (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv) { (void)ext_ihave_binary_init(ext, cgenv->sbin, cgenv->ast); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/Makefile.in0000644000175100001700000005535715100335630026302 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/ihave ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_ihave_la_LIBADD = am__objects_1 = tst-ihave.lo am__objects_2 = cmd-error.lo am_libsieve_ext_ihave_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ ext-ihave-binary.lo ext-ihave-common.lo ext-ihave.lo libsieve_ext_ihave_la_OBJECTS = $(am_libsieve_ext_ihave_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-error.Plo \ ./$(DEPDIR)/ext-ihave-binary.Plo \ ./$(DEPDIR)/ext-ihave-common.Plo ./$(DEPDIR)/ext-ihave.Plo \ ./$(DEPDIR)/tst-ihave.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_ihave_la_SOURCES) DIST_SOURCES = $(libsieve_ext_ihave_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_ihave.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-ihave.c commands = \ cmd-error.c libsieve_ext_ihave_la_SOURCES = \ $(tests) \ $(commands) \ ext-ihave-binary.c \ ext-ihave-common.c \ ext-ihave.c noinst_HEADERS = \ ext-ihave-binary.h \ ext-ihave-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/ihave/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/ihave/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_ihave.la: $(libsieve_ext_ihave_la_OBJECTS) $(libsieve_ext_ihave_la_DEPENDENCIES) $(EXTRA_libsieve_ext_ihave_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_ihave_la_OBJECTS) $(libsieve_ext_ihave_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-ihave-binary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-ihave-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-ihave.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-ihave.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-error.Plo -rm -f ./$(DEPDIR)/ext-ihave-binary.Plo -rm -f ./$(DEPDIR)/ext-ihave-common.Plo -rm -f ./$(DEPDIR)/ext-ihave.Plo -rm -f ./$(DEPDIR)/tst-ihave.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-error.Plo -rm -f ./$(DEPDIR)/ext-ihave-binary.Plo -rm -f ./$(DEPDIR)/ext-ihave-common.Plo -rm -f ./$(DEPDIR)/ext-ihave.Plo -rm -f ./$(DEPDIR)/tst-ihave.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/ext-ihave-common.c0000644000175100001700000000227415100335616027553 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "sieve-common.h" #include "sieve-ast.h" #include "ext-ihave-common.h" /* * AST context management */ struct ext_ihave_ast_context * ext_ihave_get_ast_context(const struct sieve_extension *this_ext, struct sieve_ast *ast) { struct ext_ihave_ast_context *actx = (struct ext_ihave_ast_context *) sieve_ast_extension_get_context(ast, this_ext); pool_t pool; if (actx != NULL) return actx; pool = sieve_ast_pool(ast); actx = p_new(pool, struct ext_ihave_ast_context, 1); p_array_init(&actx->missing_extensions, pool, 64); sieve_ast_extension_set_context(ast, this_ext, actx); return actx; } void ext_ihave_ast_add_missing_extension(const struct sieve_extension *this_ext, struct sieve_ast *ast, const char *ext_name) { struct ext_ihave_ast_context *actx = ext_ihave_get_ast_context(this_ext, ast); const char *const *exts; unsigned int i, count; exts = array_get(&actx->missing_extensions, &count); for (i = 0; i < count; i++) { if (strcmp(exts[i], ext_name) == 0) return; } array_append(&actx->missing_extensions, &ext_name, 1); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/ext-ihave-binary.h0000644000175100001700000000146015100335616027550 0ustar00buildbotbuildbot00000000000000#ifndef EXT_IHAVE_BINARY_H #define EXT_IHAVE_BINARY_H /* * Binary context management */ struct ext_ihave_binary_context; struct ext_ihave_binary_context * ext_ihave_binary_get_context(const struct sieve_extension *this_ext, struct sieve_binary *sbin); struct ext_ihave_binary_context * ext_ihave_binary_init(const struct sieve_extension *this_ext, struct sieve_binary *sbin, struct sieve_ast *ast); /* * Registering missing extension */ void ext_ihave_binary_add_missing_extension( struct ext_ihave_binary_context *binctx, const char *ext_name); /* * Main extension interface */ bool ext_ihave_binary_load(const struct sieve_extension *ext, struct sieve_binary *sbin); bool ext_ihave_binary_dump(const struct sieve_extension *ext, struct sieve_dumptime_env *denv); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/ihave/tst-ihave.c0000644000175100001700000001610115100335616026271 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-ihave-common.h" /* * Ihave test * * Syntax: * ihave */ static bool tst_ihave_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_ihave_validate_const(struct sieve_validator *valdtr, struct sieve_command *tst, int *const_current, int const_next); static bool tst_ihave_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst); const struct sieve_command_def ihave_test = { .identifier = "ihave", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_ihave_validate, .validate_const = tst_ihave_validate_const, .generate = tst_ihave_generate, }; /* * Ihave operation */ static bool tst_ihave_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_ihave_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_ihave_operation = { .mnemonic = "IHAVE", .ext_def = &ihave_extension, .code = EXT_IHAVE_OPERATION_IHAVE, .dump = tst_ihave_operation_dump, .execute = tst_ihave_operation_execute, }; /* * Code validation */ static bool tst_ihave_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct _capability { const struct sieve_extension *ext; struct sieve_ast_argument *arg; }; struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *stritem; enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr); bool no_global = ((cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0); ARRAY(struct _capability) capabilities; struct _capability capability; const struct _capability *caps; unsigned int i, count; bool all_known = TRUE; t_array_init(&capabilities, 64); tst->data = (void *)FALSE; /* Check stringlist argument */ if (!sieve_validate_positional_argument(valdtr, tst, arg, "capabilities", 1, SAAT_STRING_LIST)) return FALSE; switch (sieve_ast_argument_type(arg)) { case SAAT_STRING: /* Single string */ capability.arg = arg; capability.ext = sieve_extension_get_by_name( tst->ext->svinst, sieve_ast_argument_strc(arg)); if (capability.ext == NULL || (no_global && capability.ext->global)) { all_known = FALSE; ext_ihave_ast_add_missing_extension( tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg)); } else { array_append(&capabilities, &capability, 1); } break; case SAAT_STRING_LIST: /* String list */ stritem = sieve_ast_strlist_first(arg); while (stritem != NULL) { capability.arg = stritem; capability.ext = sieve_extension_get_by_name( tst->ext->svinst, sieve_ast_argument_strc(stritem)); if (capability.ext == NULL || (no_global && capability.ext->global)) { all_known = FALSE; ext_ihave_ast_add_missing_extension( tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem)); } else { array_append(&capabilities, &capability, 1); } stritem = sieve_ast_strlist_next(stritem); } break; default: i_unreached(); } if (!all_known) return TRUE; /* RFC 5463, Section 4, page 4: The "ihave" extension is designed to be used with other extensions that add tests, actions, comparators, or arguments. Implementations MUST NOT allow it to be used with extensions that change the underlying Sieve grammar, or extensions like encoded-character [RFC5228], or variables [RFC5229] that change how the content of Sieve scripts are interpreted. The test MUST fail and the extension MUST NOT be enabled if such usage is attempted. FIXME: current implementation of this restriction is hardcoded and therefore highly inflexible */ caps = array_get(&capabilities, &count); for (i = 0; i < count; i++) { if (sieve_extension_name_is(caps[i].ext, "variables") || sieve_extension_name_is(caps[i].ext, "encoded-character")) return TRUE; } /* Load all extensions */ caps = array_get(&capabilities, &count); for (i = 0; i < count; i++) { if (!sieve_validator_extension_load(valdtr, tst, caps[i].arg, caps[i].ext, FALSE)) return FALSE; } if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; tst->data = (void *)TRUE; return TRUE; } static bool tst_ihave_validate_const(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst, int *const_current, int const_next ATTR_UNUSED) { if ((bool)tst->data == TRUE) *const_current = -1; else *const_current = 0; return TRUE; } /* * Code generation */ bool tst_ihave_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { /* Emit opcode */ sieve_operation_emit(cgenv->sblock, tst->ext, &tst_ihave_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_ihave_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "IHAVE"); sieve_code_descend(denv); return sieve_opr_stringlist_dump(denv, address, "capabilities"); } /* * Code execution */ static int tst_ihave_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_execute_env *eenv = renv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct sieve_stringlist *capabilities; string_t *cap_item; bool matched; int ret; /* * Read operands */ /* Read capabilities */ if ((ret = sieve_opr_stringlist_read(renv, address, "capabilities", &capabilities)) <= 0) return ret; /* * Perform test */ /* Perform the test */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "ihave test"); sieve_runtime_trace_descend(renv); cap_item = NULL; matched = TRUE; while (matched && (ret = sieve_stringlist_next_item(capabilities, &cap_item)) > 0) { const struct sieve_extension *ext; int sret; ext = sieve_extension_get_by_name(svinst, str_c(cap_item)); if (ext == NULL) { sieve_runtime_trace_error( renv, "ihave: invalid extension name"); return SIEVE_EXEC_BIN_CORRUPT; } sret = sieve_interpreter_extension_start(renv->interp, ext); if (sret == SIEVE_EXEC_FAILURE) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "extension '%s' not available", sieve_extension_name(ext)); matched = FALSE; } else if (sret == SIEVE_EXEC_OK) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "extension '%s' available", sieve_extension_name(ext)); } else { return sret; } } if (ret < 0) { sieve_runtime_trace_error(renv, "invalid capabilities item"); return SIEVE_EXEC_BIN_CORRUPT; } /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, matched); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/0000755000175100001700000000000015100335670024235 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/ext-index-common.h0000644000175100001700000000067015100335616027604 0ustar00buildbotbuildbot00000000000000#ifndef EXT_INDEX_COMMON_H #define EXT_INDEX_COMMON_H #include "sieve-common.h" #include #define SIEVE_EXT_INDEX_HDR_OVERRIDE_SEQUENCE 100 /* * Tagged arguments */ extern const struct sieve_argument_def index_tag; extern const struct sieve_argument_def last_tag; /* * Operands */ extern const struct sieve_operand_def index_operand; /* * Extension */ extern const struct sieve_extension_def index_extension; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/Makefile.am0000644000175100001700000000034515100335616026273 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_index.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_index_la_SOURCES = \ ext-index-common.c \ ext-index.c \ tag-index.c noinst_HEADERS = \ ext-index-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/tag-index.c0000644000175100001700000001555115100335616026270 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-result.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "ext-index-common.h" /* * Tagged argument */ static bool tag_index_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_index_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); const struct sieve_argument_def index_tag = { .identifier = "index", .validate = tag_index_validate, .generate = tag_index_generate }; static bool tag_last_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); const struct sieve_argument_def last_tag = { .identifier = "last", .validate = tag_last_validate, }; /* * Header override */ static bool svmo_index_dump_context(const struct sieve_message_override *svmo, const struct sieve_dumptime_env *denv, sieve_size_t *address); static int svmo_index_read_context(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, sieve_size_t *address, void **ho_context); static int svmo_index_header_override(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, bool mime_decode, struct sieve_stringlist **headers); const struct sieve_message_override_def index_header_override = { SIEVE_OBJECT("index", &index_operand, 0), .sequence = SIEVE_EXT_INDEX_HDR_OVERRIDE_SEQUENCE, .dump_context = svmo_index_dump_context, .read_context = svmo_index_read_context, .header_override = svmo_index_header_override }; /* * Operand */ static const struct sieve_extension_objects ext_header_overrides = SIEVE_EXT_DEFINE_MESSAGE_OVERRIDE(index_header_override); const struct sieve_operand_def index_operand = { .name = "index operand", .ext_def = &index_extension, .class = &sieve_message_override_operand_class, .interface = &ext_header_overrides }; /* * Tag data */ struct tag_index_data { sieve_number_t fieldno; bool last:1; }; /* * Tag validation */ static bool tag_index_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct tag_index_data *data; /* Skip the tag itself */ *arg = sieve_ast_argument_next(*arg); /* Check syntax: * ":index" */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_NUMBER, FALSE)) return FALSE; if (tag->argument->data == NULL) { data = p_new(sieve_command_pool(cmd), struct tag_index_data, 1); tag->argument->data = data; } else { data = (struct tag_index_data *)tag->argument->data; } data->fieldno = sieve_ast_argument_number(*arg); if (data->fieldno == 0) { sieve_argument_validate_error(valdtr, *arg, "the :index tag for the %s %s cannot be zero", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* Detach parameter */ *arg = sieve_ast_arguments_detach(*arg,1); return TRUE; } static bool tag_last_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *index_arg; struct tag_index_data *data; index_arg = sieve_command_find_argument(cmd, &index_tag); if (index_arg == NULL) { sieve_argument_validate_error( valdtr, *arg, "the :last tag for the %s %s cannot be specified " "without the :index tag", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* Set :last flag */ if (index_arg->argument->data == NULL) { data = p_new(sieve_command_pool(cmd), struct tag_index_data, 1); index_arg->argument->data = data; } else { data = (struct tag_index_data *)index_arg->argument->data; } data->last = TRUE; /* Detach */ *arg = sieve_ast_arguments_detach(*arg, 1); return TRUE; } /* * Code generation */ static bool tag_index_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { struct tag_index_data *data = (struct tag_index_data *)arg->argument->data; if (sieve_ast_argument_type(arg) != SAAT_TAG) return FALSE; sieve_opr_message_override_emit(cgenv->sblock, arg->argument->ext, &index_header_override); (void)sieve_binary_emit_integer (cgenv->sblock, data->fieldno); (void)sieve_binary_emit_byte(cgenv->sblock, (data->last ? 1 : 0)); return TRUE; } /* * Header override implementation */ /* Context data */ struct svmo_index_context { unsigned int fieldno; bool last:1; }; /* Context coding */ static bool svmo_index_dump_context(const struct sieve_message_override *svmo ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_number_t fieldno = 0; unsigned int last; if (!sieve_binary_read_integer(denv->sblock, address, &fieldno) || fieldno == 0) return FALSE; sieve_code_dumpf(denv, "fieldno: %llu", (unsigned long long) fieldno); if (!sieve_binary_read_byte(denv->sblock, address, &last)) return FALSE; if (last > 0) sieve_code_dumpf(denv, "last"); return TRUE; } static int svmo_index_read_context(const struct sieve_message_override *svmo ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address, void **ho_context) { pool_t pool = sieve_result_pool(renv->result); struct svmo_index_context *ctx; sieve_number_t fieldno; unsigned int last = 0; if (!sieve_binary_read_integer(renv->sblock, address, &fieldno)) { sieve_runtime_trace_error(renv, "fieldno: invalid number"); return SIEVE_EXEC_BIN_CORRUPT; } if (fieldno == 0) { sieve_runtime_trace_error(renv, "fieldno: index is zero"); return SIEVE_EXEC_BIN_CORRUPT; } if (!sieve_binary_read_byte(renv->sblock, address, &last)) { sieve_runtime_trace_error(renv, "last: invalid byte"); return SIEVE_EXEC_BIN_CORRUPT; } ctx = p_new(pool, struct svmo_index_context, 1); ctx->fieldno = fieldno; ctx->last = (last == 0 ? FALSE : TRUE); *ho_context = ctx; return SIEVE_EXEC_OK; } /* Override */ static int svmo_index_header_override(const struct sieve_message_override *svmo, const struct sieve_runtime_env *renv, bool mime_decode ATTR_UNUSED, struct sieve_stringlist **headers) { struct svmo_index_context *ctx = (struct svmo_index_context *)svmo->context; sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "header index override: only returning index %d%s", ctx->fieldno, (ctx->last ? " (from last)" : "")); *headers = sieve_index_stringlist_create( renv, *headers, (int)ctx->fieldno * (ctx->last ? -1 : 1)); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/Makefile.in0000644000175100001700000005420515100335630026304 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/index ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_index_la_LIBADD = am_libsieve_ext_index_la_OBJECTS = ext-index-common.lo ext-index.lo \ tag-index.lo libsieve_ext_index_la_OBJECTS = $(am_libsieve_ext_index_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-index-common.Plo \ ./$(DEPDIR)/ext-index.Plo ./$(DEPDIR)/tag-index.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_index_la_SOURCES) DIST_SOURCES = $(libsieve_ext_index_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_index.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_index_la_SOURCES = \ ext-index-common.c \ ext-index.c \ tag-index.c noinst_HEADERS = \ ext-index-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/index/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/index/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_index.la: $(libsieve_ext_index_la_OBJECTS) $(libsieve_ext_index_la_DEPENDENCIES) $(EXTRA_libsieve_ext_index_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_index_la_OBJECTS) $(libsieve_ext_index_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-index-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-index.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-index.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-index-common.Plo -rm -f ./$(DEPDIR)/ext-index.Plo -rm -f ./$(DEPDIR)/tag-index.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-index-common.Plo -rm -f ./$(DEPDIR)/ext-index.Plo -rm -f ./$(DEPDIR)/tag-index.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/ext-index-common.c0000644000175100001700000000046715100335616027603 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "utc-offset.h" #include "str.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-interpreter.h" #include "sieve-message.h" #include "ext-index-common.h" dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/index/ext-index.c0000644000175100001700000000336115100335616026311 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension index * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5260 * Implementation: full * Status: testing * */ #include "lib.h" #include "array.h" #include "sieve-common.h" #include "sieve-message.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-index-common.h" /* * Extension */ static bool ext_index_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def index_extension = { .name = "index", .validator_load = ext_index_validator_load, SIEVE_EXT_DEFINE_OPERAND(index_operand) }; static bool ext_index_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register :index and :last tags with header, address and date test commands * and we don't care whether these command are registered or even whether * these will be registered at all. The validator handles either situation * gracefully. */ sieve_validator_register_external_tag (valdtr, "header", ext, &index_tag, SIEVE_OPT_MESSAGE_OVERRIDE); sieve_validator_register_external_tag (valdtr, "header", ext, &last_tag, 0); sieve_validator_register_external_tag (valdtr, "address", ext, &index_tag, SIEVE_OPT_MESSAGE_OVERRIDE); sieve_validator_register_external_tag (valdtr, "address", ext, &last_tag, 0); sieve_validator_register_external_tag (valdtr, "date", ext, &index_tag, SIEVE_OPT_MESSAGE_OVERRIDE); sieve_validator_register_external_tag (valdtr, "date", ext, &last_tag, 0); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/0000755000175100001700000000000015100335670025005 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/tag-redirect-list.c0000644000175100001700000000177015100335616030501 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-code.h" #include "sieve-actions.h" #include "sieve-result.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "ext-extlists-common.h" /* * Tagged argument */ static bool tag_redirect_list_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); const struct sieve_argument_def redirect_list_tag = { .identifier = "list", .validate = tag_redirect_list_validate, }; /* * Tag validation */ static bool tag_redirect_list_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd ATTR_UNUSED) { sieve_argument_validate_error( valdtr, *arg, "list tag: " "using :list with redirect is not supported"); return FALSE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/ext-extlists-settings.h0000644000175100001700000000147415100335616031477 0ustar00buildbotbuildbot00000000000000#ifndef EXT_EXTLISTS_SETTINGS_H #define EXT_EXTLISTS_SETTINGS_H /* */ #define SIEVE_URN_PREFIX "urn:ietf:params:sieve" #define SIEVE_URN_ADDRBOOK SIEVE_URN_PREFIX":addrbook" #define SIEVE_URN_ADDRBOOK_DEFAULT SIEVE_URN_ADDRBOOK":default" /* */ struct ext_extlists_list_settings { pool_t pool; const char *name; /* Maximum size of lookup value */ size_t max_lookup_size; struct { const char *name; } parsed; }; struct ext_extlists_settings { pool_t pool; ARRAY_TYPE(const_string) lists; }; extern const struct setting_parser_info ext_extlists_list_setting_parser_info; extern const struct setting_parser_info ext_extlists_setting_parser_info; /* */ int ext_extlists_name_normalize(const char **name, const char **error_r); /* */ #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/Makefile.am0000644000175100001700000000067515100335616027051 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_extlists.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ $(LIBDOVECOT_INCLUDE) tags = \ tag-redirect-list.c match_types = \ mcht-list.c tests = \ tst-valid-ext-list.c libsieve_ext_extlists_la_SOURCES = \ $(tags) \ $(match_types) \ $(tests) \ ext-extlists-settings.c \ ext-extlists-common.c \ ext-extlists.c noinst_HEADERS = \ ext-extlists-settings.h \ ext-extlists-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/tst-valid-ext-list.c0000644000175100001700000000717315100335616030637 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-extlists-common.h" /* Valid_ext_list test Syntax: valid_ext_list */ static bool tst_vextlist_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_vextlist_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def valid_ext_list_test = { .identifier = "valid_ext_list", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_vextlist_validate, .generate = tst_vextlist_generate }; /* * Valid_ext_list operation */ static bool tst_vextlist_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_vextlist_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def valid_ext_list_operation = { .mnemonic = "VALID_EXT_LIST", .ext_def = &extlists_extension, .dump = tst_vextlist_operation_dump, .execute = tst_vextlist_operation_execute }; /* * Test validation */ static bool tst_vextlist_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if (!sieve_validate_positional_argument(valdtr, tst, arg, "ext-list-names", 1, SAAT_STRING_LIST)) return FALSE; return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* * Test generation */ static bool tst_vextlist_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &valid_ext_list_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool tst_vextlist_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "VALID_EXT_LIST"); sieve_code_descend(denv); return sieve_opr_stringlist_dump(denv, address, "ext-list-names"); } /* * Code execution */ static int tst_vextlist_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_stringlist *ext_list_names; string_t *list_name_item; bool all_valid = TRUE, warned = FALSE; int ret; /* * Read operands */ /* Read list names */ ret = sieve_opr_stringlist_read(renv, address, "ext-list-names", &ext_list_names); if (ret <= 0) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "valid_ext_list_test"); list_name_item = NULL; while ((ret = sieve_stringlist_next_item(ext_list_names, &list_name_item)) > 0) { int vret; vret = ext_extlists_runtime_ext_list_validate( renv, list_name_item); if (vret < 0) { all_valid = FALSE; if (warned) continue; warned = TRUE; sieve_runtime_warning( renv, NULL, ":list tag: " "invalid external list name: %s", str_sanitize_utf8(str_c(list_name_item), 1024)); } if (vret == 0) { all_valid = FALSE; break; } } if (ret < 0) { sieve_runtime_trace_error(renv, "corrupt external list name item"); return SIEVE_EXEC_BIN_CORRUPT; } sieve_interpreter_set_test_result(renv->interp, all_valid); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/ext-extlists-common.c0000644000175100001700000004412315100335616031120 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "array.h" #include "bsearch-insert-pos.h" #include "ioloop.h" #include "dict.h" #include "settings.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-settings.h" #include "sieve-stringlist.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-extlists-settings.h" #include "ext-extlists-common.h" /* * List match type operand */ static const struct sieve_extension_objects ext_match_types = SIEVE_EXT_DEFINE_MATCH_TYPE(list_match_type); const struct sieve_operand_def list_match_type_operand = { .name = "list match", .ext_def = &extlists_extension, .class = &sieve_match_type_operand_class, .interface = &ext_match_types }; /* * Configuration */ static int ext_extlists_list_find(struct ext_extlists_context *extctx, const char *name, struct ext_extlists_list **list_r) { int ret; const char *error; if (extctx == NULL) return 0; ret = ext_extlists_name_normalize(&name, &error); if (ret < 0) return -1; struct ext_extlists_list *list; array_foreach_modifiable(&extctx->lists, list) { if (strcasecmp(name, list->set->parsed.name) == 0) { *list_r = list; return 1; } } return 0; } static int ext_extlists_list_add(struct sieve_instance *svinst, struct ext_extlists_context *extctx, const char *name) { struct ext_extlists_list *list; const struct ext_extlists_list_settings *set; const char *error; int ret; ret = ext_extlists_list_find(extctx, name, &list); i_assert(ret >= 0); if (ret > 0) { e_error(svinst->event, "extlists: Duplicate list definition with name '%s'", name); return -1; } if (settings_get_filter(svinst->event, "sieve_extlists_list", name, &ext_extlists_list_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } list = array_append_space(&extctx->lists); list->set = set; return 0; } static void ext_extlists_list_add_default(struct ext_extlists_context *extctx) { struct ext_extlists_list *list; int ret; ret = ext_extlists_list_find(extctx, SIEVE_URN_ADDRBOOK_DEFAULT, &list); i_assert(ret >= 0); if (ret > 0) return; struct ext_extlists_list_settings *set; pool_t pool; pool = pool_alloconly_create("sieve extlists default list", 256); set = settings_defaults_dup( pool, &ext_extlists_list_setting_parser_info); set->name = SIEVE_URN_ADDRBOOK_DEFAULT; set->parsed.name = SIEVE_URN_ADDRBOOK_DEFAULT; list = array_append_space(&extctx->lists); list->set = set; } static int ext_extlists_config_lists(struct sieve_instance *svinst, struct ext_extlists_context *extctx) { const char *name; if (!array_is_created(&extctx->set->lists)) return 0; array_foreach_elem(&extctx->set->lists, name) { if (ext_extlists_list_add(svinst, extctx, name) < 0) return -1; } return 0; } int ext_extlists_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct ext_extlists_settings *set; const char *error; if (settings_get(svinst->event, &ext_extlists_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } struct ext_extlists_context *extctx; unsigned int lists_count = (!array_is_created(&set->lists) ? 0 : array_count(&set->lists)); extctx = i_new(struct ext_extlists_context, 1); extctx->set = set; i_array_init(&extctx->lists, lists_count); *context_r = extctx; if (ext_extlists_config_lists(svinst, extctx) < 0) { ext_extlists_unload(ext); return -1; } ext_extlists_list_add_default(extctx); sieve_extension_capabilities_register(ext, &extlists_capabilities); return 0; } void ext_extlists_unload(const struct sieve_extension *ext) { struct ext_extlists_context *extctx = ext->context; struct ext_extlists_list *list; if (extctx == NULL) return; array_foreach_modifiable(&extctx->lists, list) { dict_deinit(&list->dict); settings_free(list->set); pool_unref(&list->cache_pool); } settings_free(extctx->set); array_free(&extctx->lists); i_free(extctx); } static const char * ext_extlists_get_lists_string(const struct sieve_extension *ext) { struct ext_extlists_context *extctx = ext->context; if (extctx == NULL || array_count(&extctx->lists) == 0) return NULL; struct ext_extlists_list *list; string_t *result = t_str_new(128); array_foreach_modifiable(&extctx->lists, list) { if (str_len(result) > 0) str_append_c(result, ' '); str_append(result, list->set->parsed.name); } return str_c(result); } static int ext_extlists_list_init(struct ext_extlists_list *list, struct event *event_parent, const char **error_r) { int ret; if (list->dict != NULL) return 1; struct event *event = event_create(event_parent); event_add_str(event, "sieve_extlists_list", list->set->name); settings_event_add_list_filter_name(event, "sieve_extlists_list", list->set->name); ret = dict_init_auto(event, &list->dict, error_r); event_unref(&event); return ret; } static int ext_extlists_list_cache_cmp(const struct ext_extlists_cache_entry *entry1, const struct ext_extlists_cache_entry *entry2) { return strcmp(entry1->value, entry2->value); } static void ext_extlists_list_cache_add(struct ext_extlists_list *list, const char *value, bool matched) { struct ext_extlists_cache_entry entry; unsigned int insert_idx; bool found; if (list->cache_pool == NULL) { list->cache_pool = pool_alloconly_create( "sieve extlists list cache", 4096); p_array_init(&list->cache, list->cache_pool, 64); } i_zero(&entry); entry.value = value; entry.matched = matched; found = array_bsearch_insert_pos(&list->cache, &entry, ext_extlists_list_cache_cmp, &insert_idx); i_assert(!found); entry.value = p_strdup(list->cache_pool, value); array_insert(&list->cache, insert_idx, &entry, 1); } static bool ext_extlists_list_cache_lookup(struct ext_extlists_list *list, const char *value, bool *matched_r) { *matched_r = FALSE; if (list->cache_pool == NULL) return FALSE; struct ext_extlists_cache_entry entry; unsigned int idx; i_zero(&entry); entry.value = value; if (!array_bsearch_insert_pos(&list->cache, &entry, ext_extlists_list_cache_cmp, &idx)) return FALSE; const struct ext_extlists_cache_entry *found_entry; found_entry = array_idx(&list->cache, idx); *matched_r = found_entry->matched; return TRUE; } /* * Extlists capability */ const struct sieve_extension_capabilities extlists_capabilities = { "extlists", ext_extlists_get_lists_string, }; /* * Runtime operand checking */ int ext_extlists_runtime_ext_list_validate(const struct sieve_runtime_env *renv, string_t *ext_list_name) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_extlists_context *extctx = this_ext->context; const char *list_name = str_c(ext_list_name); struct ext_extlists_list *list; return ext_extlists_list_find(extctx, list_name, &list); } /* * Lookup */ #define DICT_LOOKUP_BATCH_MAX 100 #define DICT_LOOKUP_BATCH_MIN 100 #define DICT_SIEVE_PATH DICT_PATH_PRIVATE"sieve/" #define DICT_EXTLISTS_PATH DICT_SIEVE_PATH"extlists/" struct _dict_lookup; struct _dict_lookup_value; struct _dict_lookup_list; struct _dict_lookup_context; struct _dict_lookup { struct _dict_lookup_value *value; struct ext_extlists_list *list; }; struct _dict_lookup_value { struct _dict_lookup_context *context; unsigned int id; char *value; unsigned int lookups_pending; }; struct _dict_lookup_list { struct _dict_lookup_context *context; struct ext_extlists_list *list; }; struct _dict_lookup_context { pool_t pool; const struct sieve_runtime_env *renv; struct ext_extlists_context *extctx; ARRAY(struct _dict_lookup_list) lists; struct ioloop *ioloop; struct sieve_stringlist *values; unsigned int lookup_id_counter; unsigned int batch_max, lookups_max; ARRAY(struct _dict_lookup) lookups; ARRAY(struct _dict_lookup_value) lookup_values; unsigned int lookups_pending; char *match; int status; bool warned:1; bool return_match:1; bool found:1; bool lookup_continuing:1; bool lookup_finished:1; }; static void _dict_lookup_continue(struct _dict_lookup_context *dlctx); static int _dict_lookup_list_init(struct _dict_lookup_context *dlctx, string_t *key_item) { const struct sieve_runtime_env *renv = dlctx->renv; const struct sieve_execute_env *eenv = renv->exec_env; struct ext_extlists_context *extctx = dlctx->extctx; const char *key = str_c(key_item); struct ext_extlists_list *list; struct _dict_lookup_list *dllst; const char *error; int ret; if (strlen(key) != str_len(key_item)) { if (dlctx->warned) return SIEVE_EXEC_OK; dlctx->warned = TRUE; sieve_runtime_error( renv, NULL, "Key item for \":list\" match contains NUL byte"); return SIEVE_EXEC_OK; } ret = ext_extlists_list_find(extctx, key, &list); if (ret < 0) { if (dlctx->warned) return SIEVE_EXEC_OK; dlctx->warned = TRUE; sieve_runtime_warning( renv, NULL, "Key item '%s' for \":list\" match is not a valid list name", str_sanitize_utf8(key, 1024)); return SIEVE_EXEC_OK; } if (ret == 0) { if (dlctx->warned) return SIEVE_EXEC_OK; dlctx->warned = TRUE; sieve_runtime_warning( renv, NULL, "Key item '%s' for \":list\" match is not a known list name", str_sanitize_utf8(key, 1024)); return SIEVE_EXEC_OK; } ret = ext_extlists_list_init(list, eenv->event, &error); if (ret < 0) { sieve_runtime_critical( renv, NULL, "\":list\" match", "\":list\" match: Failed to initialize dict: %s", error); return SIEVE_EXEC_FAILURE; } if (ret == 0) { sieve_runtime_debug( renv, NULL, "Key item '%s' for \":list\" match yields empty list", str_sanitize_utf8(key, 1024)); return SIEVE_EXEC_OK; } dllst = array_append_space(&dlctx->lists); dllst->list = list; if (list->dict != NULL) dict_switch_ioloop(list->dict); return SIEVE_EXEC_OK; } static void _dict_lookup_callback(const struct dict_lookup_result *result, struct _dict_lookup *dl) { struct _dict_lookup_value *dlval = dl->value; struct _dict_lookup_context *dlctx = dlval->context; const struct sieve_runtime_env *renv = dlctx->renv; i_assert(dlctx->lookups_pending > 0); dlval->lookups_pending--; dlctx->lookups_pending--; if (result->ret < 0) { if (dlctx->lookup_finished) return; sieve_runtime_critical( renv, NULL, "\":list\" match", "\":list\" match: " "Failed to lookup value '%s' from list '%s' " "with dict error: %s", str_sanitize(dlval->value, 256), dl->list->set->parsed.name, result->error); sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "extlists lookup[%u] in list '%s' failed", dlval->id, dl->list->set->parsed.name); dlctx->status = SIEVE_EXEC_TEMP_FAILURE; dlctx->lookup_finished = TRUE; io_loop_stop(dlctx->ioloop); return; } if (result->ret > 0) { sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "extlists lookup[%u] in list '%s' yielded result", dlval->id, dl->list->set->parsed.name); ext_extlists_list_cache_add(dl->list, dlval->value, TRUE); dlctx->found = TRUE; dlctx->match = dlval->value; dlctx->lookup_finished = TRUE; io_loop_stop(dlctx->ioloop); return; } sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "extlists lookup[%u] in list '%s' yielded no result", dlval->id, dl->list->set->parsed.name); ext_extlists_list_cache_add(dl->list, dlval->value, FALSE); if (dlval->lookups_pending == 0) { if (dlctx->match != dlval->value) i_free(dlval->value); i_zero(dlval); _dict_lookup_continue(dlctx); } } static int _dict_lookup_next_value(struct _dict_lookup_context *dlctx, const struct dict_op_settings *set, unsigned int index) { const struct sieve_runtime_env *renv = dlctx->renv; struct _dict_lookup_value *dlval; int ret; dlval = array_idx_get_space(&dlctx->lookup_values, index); if (dlval->context != NULL) return 0; string_t *value_item = NULL; ret = sieve_stringlist_next_item(dlctx->values, &value_item); if (ret == 0) return 0; if (ret < 0) { dlctx->status = dlctx->values->exec_status; return -1; } dlval->id = dlctx->lookup_id_counter++; dlval->context = dlctx; dlval->value = i_strdup(str_c(value_item)); sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "extlists lookup[%u] for '%s'", dlval->id, str_sanitize(dlval->value, 256)); const char *dict_path; dict_path = t_strconcat(DICT_EXTLISTS_PATH, dict_escape_string(str_c(value_item)), NULL); const struct _dict_lookup_list *dllst; unsigned int lists_count = array_count(&dlctx->lists); dlval->lookups_pending++; /* lock dlval for immediate callbacks */ array_foreach(&dlctx->lists, dllst) { struct ext_extlists_list *list = dllst->list; struct _dict_lookup *dl; dl = array_idx_get_space(&dlctx->lookups, (index * lists_count + array_foreach_idx(&dlctx->lists, dllst))); i_zero(dl); dl->value = dlval; dl->list = dllst->list; if (list->dict == NULL) { struct dict_lookup_result result; dlval->lookups_pending++; dlctx->lookups_pending++; i_zero(&result); _dict_lookup_callback(&result, dl); continue; } if (str_len(value_item) > list->set->max_lookup_size) { sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "skipping extlists lookup[%u] for list '%s': " "value is excessively large" "(size %zu > %zu bytes)", dlval->id, list->set->parsed.name, str_len(value_item), list->set->max_lookup_size); continue; } bool matched = FALSE; if (ext_extlists_list_cache_lookup(list, dlval->value, &matched)) { sieve_runtime_trace( renv, SIEVE_TRLVL_MATCHING, "cache hit for extlists lookup[%u] " "(mathed=%s)", dlval->id, (matched ? "yes" : "no")); if (matched) { dlctx->found = TRUE; dlctx->match = dlval->value; dlval->value = NULL; dlctx->lookup_finished = TRUE; io_loop_stop(dlctx->ioloop); break; } continue; } dlval->lookups_pending++; dlctx->lookups_pending++; dict_lookup_async(list->dict, set, dict_path, _dict_lookup_callback, dl); if (dlctx->lookup_finished) break; } if (--dlval->lookups_pending == 0) { if (dlctx->match != dlval->value) i_free(dlval->value); i_zero(dlval); _dict_lookup_continue(dlctx); } return 1; } static void _dict_lookup_continue(struct _dict_lookup_context *dlctx) { const struct sieve_runtime_env *renv = dlctx->renv; unsigned int i; if (dlctx->lookup_finished) return; if (dlctx->lookups_pending >= DICT_LOOKUP_BATCH_MIN) return; if (dlctx->lookup_continuing) return; const struct dict_op_settings *set = mail_user_get_dict_op_settings( renv->exec_env->scriptenv->user); int ret = 1; dlctx->lookup_continuing = TRUE; while (ret > 0 && !dlctx->lookup_finished && dlctx->lookups_pending < dlctx->lookups_max) { for (i = 0; i < dlctx->lookups_max && !dlctx->lookup_finished; i++) { ret = _dict_lookup_next_value(dlctx, set, i); if (ret <= 0) break; } } dlctx->lookup_continuing = FALSE; if (ret == 0 && dlctx->lookups_pending == 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "all lookups finished"); dlctx->lookup_finished = TRUE; io_loop_stop(dlctx->ioloop); } } static void ext_extlists_do_lookup(struct _dict_lookup_context *dlctx, struct sieve_stringlist *key_list) { const struct sieve_runtime_env *renv = dlctx->renv; string_t *key_item = NULL; int ret; while ((ret = sieve_stringlist_next_item(key_list, &key_item)) > 0 ) { ret = _dict_lookup_list_init(dlctx, key_item); if (ret != SIEVE_EXEC_OK) { dlctx->status = ret; return; } } if (ret < 0) { dlctx->status = key_list->exec_status; return; } if (array_count(&dlctx->lists) == 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "keylist yielded empty lists"); dlctx->status = SIEVE_EXEC_OK; return; } unsigned int lists_count = array_count(&dlctx->lists); dlctx->batch_max = I_MAX(DICT_LOOKUP_BATCH_MAX, lists_count); dlctx->lookups_max = dlctx->batch_max / lists_count; dlctx->batch_max = dlctx->lookups_max * lists_count; p_array_init(&dlctx->lookup_values, dlctx->pool, dlctx->lookups_max); p_array_init(&dlctx->lookups, dlctx->pool, dlctx->lookups_max * lists_count); _dict_lookup_continue(dlctx); while (!dlctx->lookup_finished) io_loop_run(dlctx->ioloop); struct _dict_lookup_list *dll; struct _dict_lookup_value *dlval; array_foreach_modifiable(&dlctx->lists, dll) { if (dll->list->dict != NULL) dict_wait(dll->list->dict); } array_foreach_modifiable(&dlctx->lookup_values, dlval) { if (dlval->value != dlctx->match) i_free(dlval->value); } } int ext_extlists_lookup(const struct sieve_runtime_env *renv, struct ext_extlists_context *extctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list, const char **match_r, bool *found_r) { struct _dict_lookup_context dlctx; struct ioloop *prev_ioloop; *found_r = FALSE; if (match_r != NULL) *match_r = NULL; if (extctx == NULL || array_count(&extctx->lists) == 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "no lists configured"); return SIEVE_EXEC_OK; } i_zero(&dlctx); dlctx.pool = pool_alloconly_create("sieve extlists lookup", 1024); dlctx.renv = renv; dlctx.extctx = extctx; dlctx.status = SIEVE_EXEC_OK; dlctx.return_match = (match_r != NULL); p_array_init(&dlctx.lists, dlctx.pool, array_count(&extctx->lists)); dlctx.values = value_list; struct _dict_lookup_list *dll; prev_ioloop = current_ioloop; i_assert(prev_ioloop != NULL); dlctx.ioloop = io_loop_create(); ext_extlists_do_lookup(&dlctx, key_list); io_loop_set_current(prev_ioloop); array_foreach_modifiable(&dlctx.lists, dll) { if (dll->list->dict != NULL) dict_switch_ioloop(dll->list->dict); } io_loop_set_current(dlctx.ioloop); io_loop_destroy(&dlctx.ioloop); if (match_r != NULL) *match_r = t_strdup(dlctx.match); i_free(dlctx.match); pool_unref(&dlctx.pool); *found_r = dlctx.found; return dlctx.status; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/ext-extlists.c0000644000175100001700000000307215100335616027630 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ /* Extension extlists -------------------- Author: Stephan Bosch Specification: RFC 6134 Implementation: :list match only */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-extlists-common.h" /* * Extension */ static bool ext_extlists_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def extlists_extension = { .name = "extlists", .load = ext_extlists_load, .unload = ext_extlists_unload, .validator_load = ext_extlists_validator_load, SIEVE_EXT_DEFINE_OPERATION(valid_ext_list_operation), SIEVE_EXT_DEFINE_OPERAND(list_match_type_operand), }; static bool ext_extlists_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new commands */ sieve_validator_register_command(valdtr, ext, &valid_ext_list_test); /* Register :list tag with redirect command and we don't care whether this command is registered or even whether it will be registered at all. The validator handles either situation gracefully. */ sieve_validator_register_external_tag( valdtr, "redirect", ext, &redirect_list_tag, 0); sieve_match_type_register(valdtr, ext, &list_match_type); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/ext-extlists-common.h0000644000175100001700000000307315100335616031124 0ustar00buildbotbuildbot00000000000000#ifndef EXT_EXTLISTS_COMMON_H #define EXT_EXTLISTS_COMMON_H #include "lib.h" #include "str.h" #include "sieve-common.h" /* * Configuration */ struct ext_extlists_cache_entry { const char *value; bool matched; }; struct ext_extlists_list { const struct ext_extlists_list_settings *set; struct dict *dict; pool_t cache_pool; ARRAY(struct ext_extlists_cache_entry) cache; }; struct ext_extlists_context { const struct ext_extlists_settings *set; ARRAY(struct ext_extlists_list) lists; }; int ext_extlists_load(const struct sieve_extension *ext, void **context_r); void ext_extlists_unload(const struct sieve_extension *ext); /* * Tagged arguments */ extern const struct sieve_argument_def redirect_list_tag; /* * Match types */ extern const struct sieve_match_type_def list_match_type; /* * Tests */ extern const struct sieve_command_def valid_ext_list_test; /* * Operation */ extern const struct sieve_operation_def valid_ext_list_operation; /* * Operand */ extern const struct sieve_operand_def list_match_type_operand; /* * Extension */ extern const struct sieve_extension_def extlists_extension; extern const struct sieve_extension_capabilities extlists_capabilities; /* * Runtime */ int ext_extlists_runtime_ext_list_validate(const struct sieve_runtime_env *renv, string_t *ext_list_name); /* * Lookup */ int ext_extlists_lookup(const struct sieve_runtime_env *renv, struct ext_extlists_context *extctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list, const char **match_r, bool *found_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/Makefile.in0000644000175100001700000005641115100335630027055 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/extlists ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_extlists_la_LIBADD = am__objects_1 = tag-redirect-list.lo am__objects_2 = mcht-list.lo am__objects_3 = tst-valid-ext-list.lo am_libsieve_ext_extlists_la_OBJECTS = $(am__objects_1) \ $(am__objects_2) $(am__objects_3) ext-extlists-settings.lo \ ext-extlists-common.lo ext-extlists.lo libsieve_ext_extlists_la_OBJECTS = \ $(am_libsieve_ext_extlists_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-extlists-common.Plo \ ./$(DEPDIR)/ext-extlists-settings.Plo \ ./$(DEPDIR)/ext-extlists.Plo ./$(DEPDIR)/mcht-list.Plo \ ./$(DEPDIR)/tag-redirect-list.Plo \ ./$(DEPDIR)/tst-valid-ext-list.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_extlists_la_SOURCES) DIST_SOURCES = $(libsieve_ext_extlists_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_extlists.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ $(LIBDOVECOT_INCLUDE) tags = \ tag-redirect-list.c match_types = \ mcht-list.c tests = \ tst-valid-ext-list.c libsieve_ext_extlists_la_SOURCES = \ $(tags) \ $(match_types) \ $(tests) \ ext-extlists-settings.c \ ext-extlists-common.c \ ext-extlists.c noinst_HEADERS = \ ext-extlists-settings.h \ ext-extlists-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/extlists/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/extlists/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_extlists.la: $(libsieve_ext_extlists_la_OBJECTS) $(libsieve_ext_extlists_la_DEPENDENCIES) $(EXTRA_libsieve_ext_extlists_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_extlists_la_OBJECTS) $(libsieve_ext_extlists_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-extlists-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-extlists-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-extlists.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-list.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-redirect-list.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-valid-ext-list.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-extlists-common.Plo -rm -f ./$(DEPDIR)/ext-extlists-settings.Plo -rm -f ./$(DEPDIR)/ext-extlists.Plo -rm -f ./$(DEPDIR)/mcht-list.Plo -rm -f ./$(DEPDIR)/tag-redirect-list.Plo -rm -f ./$(DEPDIR)/tst-valid-ext-list.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-extlists-common.Plo -rm -f ./$(DEPDIR)/ext-extlists-settings.Plo -rm -f ./$(DEPDIR)/ext-extlists.Plo -rm -f ./$(DEPDIR)/mcht-list.Plo -rm -f ./$(DEPDIR)/tag-redirect-list.Plo -rm -f ./$(DEPDIR)/tst-valid-ext-list.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/mcht-list.c0000644000175100001700000000462715100335616027066 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-stringlist.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-match.h" #include "ext-extlists-common.h" /* * Match-type objects */ static bool mcht_list_validate_context(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); static int match_list_match(struct sieve_match_context *mctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list); const struct sieve_match_type_def list_match_type = { SIEVE_OBJECT("list", &list_match_type_operand, 0), .validate_context = mcht_list_validate_context, .match = match_list_match, }; /* * Validation */ static bool mcht_list_validate_context(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *mtctx, struct sieve_ast_argument *key_arg ATTR_UNUSED) { if (mtctx->comparator_specified) { sieve_argument_validate_error( valdtr, arg, "the :%s match type does not allow a comparator", mtctx->match_type->object.def->identifier ); return FALSE; } return TRUE; } /* * Match-type implementation */ static int match_list_match(struct sieve_match_context *mctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list) { const struct sieve_runtime_env *renv = mctx->runenv; const struct sieve_extension *ext = SIEVE_OBJECT_EXTENSION(mctx->match_type); struct ext_extlists_context *extctx = ext->context; bool match_enabled = sieve_match_values_are_enabled(renv); const char *match = NULL; bool found = FALSE; mctx->exec_status = ext_extlists_lookup(renv, extctx, value_list, key_list, (match_enabled ? &match : NULL), &found); if (mctx->exec_status != SIEVE_EXEC_OK) return -1; if (found) { if (match_enabled) { struct sieve_match_values *mvalues; i_assert(match != NULL); mvalues = sieve_match_values_start(mctx->runenv); sieve_match_values_add_cstr(mvalues, match); sieve_match_values_commit(mctx->runenv, &mvalues); } return 1; } return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/extlists/ext-extlists-settings.c0000644000175100001700000000665115100335616031474 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2025 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "uri-util.h" #include "settings.h" #include "settings-parser.h" #include "urn.h" #include "ext-extlists-common.h" #include "ext-extlists-settings.h" static bool ext_extlists_list_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_extlists_list_"#name, name, \ struct ext_extlists_list_settings) static const struct setting_define ext_extlists_list_setting_defines[] = { DEF(STR, name), DEF(SIZE, max_lookup_size), SETTING_DEFINE_LIST_END, }; static const struct ext_extlists_list_settings ext_extlists_list_default_settings = { .name = "", .max_lookup_size = 1024, }; const struct setting_parser_info ext_extlists_list_setting_parser_info = { .name = "sieve_extlists_list", .defines = ext_extlists_list_setting_defines, .defaults = &ext_extlists_list_default_settings, .struct_size = sizeof(struct ext_extlists_list_settings), .check_func = ext_extlists_list_settings_check, .pool_offset1 = 1 + offsetof(struct ext_extlists_list_settings, pool), }; #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_extlists_"#name, name, \ struct ext_extlists_settings) static const struct setting_define ext_extlists_setting_defines[] = { { .type = SET_FILTER_ARRAY, .key = "sieve_extlists_list", .filter_array_field_name = "sieve_extlists_list_name", .offset = offsetof(struct ext_extlists_settings, lists), }, SETTING_DEFINE_LIST_END, }; static const struct ext_extlists_settings ext_extlists_default_settings = { .lists = ARRAY_INIT, }; const struct setting_parser_info ext_extlists_setting_parser_info = { .name = "sieve_extlists", .defines = ext_extlists_setting_defines, .defaults = &ext_extlists_default_settings, .struct_size = sizeof(struct ext_extlists_settings), .pool_offset1 = 1 + offsetof(struct ext_extlists_settings, pool), }; /* */ int ext_extlists_name_normalize(const char **name, const char **error_r) { const char *uri = *name, *scheme; const char *error; if (*uri == ':') uri = t_strconcat(SIEVE_URN_PREFIX, uri, NULL); if (uri_cut_scheme(&uri, &scheme) < 0) { *error_r = "Invalid URI scheme"; return -1; } scheme = t_str_lcase(scheme); if (strcmp(scheme, "urn") == 0) { if (urn_normalize(uri, URN_PARSE_SCHEME_EXTERNAL, &uri, &error) < 0) { *error_r = t_strconcat("Invalid URN: ", error, NULL); return -1; } *name = t_strconcat(scheme, ":", uri, NULL); return 1; } else if (strcmp(scheme, "tag") == 0) { if (uri_check(uri, URI_PARSE_SCHEME_EXTERNAL, &error) < 0) { *error_r = t_strconcat("Invalid TAG URI: ", error, NULL); return -1; } *name = t_strconcat(scheme, ":", uri, NULL); return 1; } *error_r = t_strconcat( scheme, ": scheme not supported for external list name", NULL); return -1; } static bool ext_extlists_list_settings_check(void *_set, pool_t pool, const char **error_r) { struct ext_extlists_list_settings *set = _set; const char *norm_name; const char *error; if (*set->name != '\0') { norm_name = set->name; if (ext_extlists_name_normalize(&norm_name, &error) < 0) { *error_r = t_strdup_printf("List name '%s' is invalid: %s", set->name, error); return FALSE; } set->parsed.name = p_strdup(pool, norm_name); } return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/0000755000175100001700000000000015100335670025260 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/mcht-count.c0000644000175100001700000000546115100335616027513 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Match-type ':count' */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-runtime-trace.h" #include "sieve-match.h" #include "ext-relational-common.h" /* * Forward declarations */ static int mcht_count_match(struct sieve_match_context *mctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list); /* * Match-type objects */ const struct sieve_match_type_def count_match_type = { SIEVE_OBJECT("count", &rel_match_type_operand, RELATIONAL_COUNT), .validate = mcht_relational_validate, }; #define COUNT_MATCH_TYPE(name, rel_match) \ const struct sieve_match_type_def rel_match_count_ ## name = { \ SIEVE_OBJECT("count-" #name, \ &rel_match_type_operand, \ REL_MATCH_INDEX(RELATIONAL_COUNT, rel_match)), \ .match = mcht_count_match, \ } COUNT_MATCH_TYPE(gt, REL_MATCH_GREATER); COUNT_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL); COUNT_MATCH_TYPE(lt, REL_MATCH_LESS); COUNT_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL); COUNT_MATCH_TYPE(eq, REL_MATCH_EQUAL); COUNT_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL); /* * Match-type implementation */ static int mcht_count_match(struct sieve_match_context *mctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list) { const struct sieve_runtime_env *renv = mctx->runenv; bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); int count; string_t *key_item; int match, ret; count = sieve_stringlist_get_length(value_list); if (count < 0) { mctx->exec_status = value_list->exec_status; return -1; } sieve_stringlist_reset(key_list); string_t *value = t_str_new(20); str_printfa(value, "%d", count); if (trace) { sieve_runtime_trace(renv, 0, "matching count value '%s'", str_sanitize(str_c(value), 80)); } sieve_runtime_trace_descend(renv); /* Match to all key values */ key_item = NULL; match = 0; while (match == 0 && (ret = sieve_stringlist_next_item(key_list, &key_item)) > 0) { match = mcht_value_match_key( mctx, str_c(value), str_len(value), str_c(key_item), str_len(key_item)); if (trace) { sieve_runtime_trace(renv, 0, "with key '%s' => %d", str_sanitize(str_c(key_item), 80), ret); } } sieve_runtime_trace_ascend(renv); if (ret < 0) { mctx->exec_status = key_list->exec_status; match = -1; } return match; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/Makefile.am0000644000175100001700000000041715100335616027316 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_relational.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_relational_la_SOURCES = \ ext-relational-common.c \ mcht-value.c \ mcht-count.c \ ext-relational.c noinst_HEADERS = \ ext-relational-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/mcht-value.c0000644000175100001700000000412615100335616027474 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-match.h" #include "ext-relational-common.h" /* * Match-type objects */ const struct sieve_match_type_def value_match_type = { SIEVE_OBJECT("value", &rel_match_type_operand, RELATIONAL_VALUE), .validate = mcht_relational_validate }; #define VALUE_MATCH_TYPE(name, rel_match) \ const struct sieve_match_type_def rel_match_value_ ## name = { \ SIEVE_OBJECT("value-" #name, \ &rel_match_type_operand, \ REL_MATCH_INDEX(RELATIONAL_VALUE, rel_match)), \ .match_key = mcht_value_match_key, \ } VALUE_MATCH_TYPE(gt, REL_MATCH_GREATER); VALUE_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL); VALUE_MATCH_TYPE(lt, REL_MATCH_LESS); VALUE_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL); VALUE_MATCH_TYPE(eq, REL_MATCH_EQUAL); VALUE_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL); /* * Match-type implementation */ int mcht_value_match_key (struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size) { const struct sieve_match_type *mtch = mctx->match_type; unsigned int rel_match = REL_MATCH(mtch->object.def->code); int cmp_result; cmp_result = mctx->comparator->def-> compare(mctx->comparator, val, val_size, key, key_size); switch ( rel_match ) { case REL_MATCH_GREATER: return ( cmp_result > 0 ? 1 : 0 ); case REL_MATCH_GREATER_EQUAL: return ( cmp_result >= 0 ? 1 : 0 ); case REL_MATCH_LESS: return ( cmp_result < 0 ? 1 : 0 ); case REL_MATCH_LESS_EQUAL: return ( cmp_result <= 0 ? 1 : 0 ); case REL_MATCH_EQUAL: return ( cmp_result == 0 ? 1 : 0); case REL_MATCH_NOT_EQUAL: return ( cmp_result != 0 ? 1 : 0); } i_unreached(); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/ext-relational-common.c0000644000175100001700000001042615100335616031645 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Syntax: MATCH-TYPE =/ COUNT / VALUE COUNT = ":count" relational-match VALUE = ":value" relational-match relational-match = DQUOTE ( "gt" / "ge" / "lt" / "le" / "eq" / "ne" ) DQUOTE */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-relational-common.h" /* * Forward declarations */ const struct sieve_match_type_def *rel_match_types[]; /* * Validation */ bool mcht_relational_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_match_type_context *ctx) { struct sieve_match_type *mcht; enum relational_match rel_match = REL_MATCH_INVALID; pool_t pool = sieve_ast_argument_pool(ctx->argument); string_t *rel_match_ident; /* Check syntax: relational-match = DQUOTE ( "gt" / "ge" / "lt" / "le" / "eq" / "ne" ) DQUOTE So, actually this must be a constant string and it is implemented as such. */ /* Did we get a string in the first place? */ if (*arg == NULL || (*arg)->type != SAAT_STRING) { sieve_argument_validate_error( valdtr, (*arg == NULL ? ctx->argument : *arg), "the :%s match-type requires a constant string argument being " "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", " "but %s was found", sieve_match_type_name(ctx->match_type), (*arg == NULL ? "none" : sieve_ast_argument_name(*arg))); return FALSE; } /* Check the relational match id */ rel_match_ident = sieve_ast_argument_str(*arg); if (str_len(rel_match_ident) == 2) { const char *rel_match_id = str_c(rel_match_ident); switch (rel_match_id[0]) { /* "gt" or "ge" */ case 'g': switch (rel_match_id[1]) { case 't': rel_match = REL_MATCH_GREATER; break; case 'e': rel_match = REL_MATCH_GREATER_EQUAL; break; default: rel_match = REL_MATCH_INVALID; } break; /* "lt" or "le" */ case 'l': switch (rel_match_id[1]) { case 't': rel_match = REL_MATCH_LESS; break; case 'e': rel_match = REL_MATCH_LESS_EQUAL; break; default: rel_match = REL_MATCH_INVALID; } break; /* "eq" */ case 'e': if (rel_match_id[1] == 'q') rel_match = REL_MATCH_EQUAL; else rel_match = REL_MATCH_INVALID; break; /* "ne" */ case 'n': if (rel_match_id[1] == 'e') rel_match = REL_MATCH_NOT_EQUAL; else rel_match = REL_MATCH_INVALID; break; /* invalid */ default: rel_match = REL_MATCH_INVALID; } } if (rel_match >= REL_MATCH_INVALID) { sieve_argument_validate_error( valdtr, *arg, "the :%s match-type requires a constant string argument being " "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", " "but \"%s\" was found", sieve_match_type_name(ctx->match_type), str_sanitize(str_c(rel_match_ident), 32)); return FALSE; } /* Delete argument */ *arg = sieve_ast_arguments_detach(*arg, 1); /* Not used just yet */ ctx->ctx_data = (void *)rel_match; /* Override the actual match type with a parameter-specific one * FIXME: ugly! */ mcht = p_new(pool, struct sieve_match_type, 1); mcht->object.ext = ctx->match_type->object.ext; SIEVE_OBJECT_SET_DEF(mcht, rel_match_types[ REL_MATCH_INDEX(ctx->match_type->object.def->code, rel_match)]); ctx->match_type = mcht; return TRUE; } /* * Relational match-type operand */ const struct sieve_match_type_def *rel_match_types[] = { &rel_match_value_gt, &rel_match_value_ge, &rel_match_value_lt, &rel_match_value_le, &rel_match_value_eq, &rel_match_value_ne, &rel_match_count_gt, &rel_match_count_ge, &rel_match_count_lt, &rel_match_count_le, &rel_match_count_eq, &rel_match_count_ne, }; static const struct sieve_extension_objects ext_match_types = SIEVE_EXT_DEFINE_MATCH_TYPES(rel_match_types); const struct sieve_operand_def rel_match_type_operand = { .name = "relational match", .ext_def = &relational_extension, .class = &sieve_match_type_operand_class, .interface = &ext_match_types, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/ext-relational-common.h0000644000175100001700000000403315100335616031647 0ustar00buildbotbuildbot00000000000000#ifndef EXT_RELATIONAL_COMMON_H #define EXT_RELATIONAL_COMMON_H #include "lib.h" #include "str.h" #include "sieve-common.h" /* * Types */ enum ext_relational_match_type { RELATIONAL_VALUE, RELATIONAL_COUNT }; enum relational_match { REL_MATCH_GREATER, REL_MATCH_GREATER_EQUAL, REL_MATCH_LESS, REL_MATCH_LESS_EQUAL, REL_MATCH_EQUAL, REL_MATCH_NOT_EQUAL, REL_MATCH_INVALID }; #define REL_MATCH_INDEX(type, match) (type * REL_MATCH_INVALID + match) #define REL_MATCH_TYPE(index) (index / REL_MATCH_INVALID) #define REL_MATCH(index) (index % REL_MATCH_INVALID) /* * Extension definitions */ extern const struct sieve_extension_def relational_extension; /* * Match types */ /* Registered for validation */ extern const struct sieve_match_type_def value_match_type; extern const struct sieve_match_type_def count_match_type; /* Used in byte code */ extern const struct sieve_match_type_def rel_match_count_gt; extern const struct sieve_match_type_def rel_match_count_ge; extern const struct sieve_match_type_def rel_match_count_lt; extern const struct sieve_match_type_def rel_match_count_le; extern const struct sieve_match_type_def rel_match_count_eq; extern const struct sieve_match_type_def rel_match_count_ne; extern const struct sieve_match_type_def rel_match_value_gt; extern const struct sieve_match_type_def rel_match_value_ge; extern const struct sieve_match_type_def rel_match_value_lt; extern const struct sieve_match_type_def rel_match_value_le; extern const struct sieve_match_type_def rel_match_value_eq; extern const struct sieve_match_type_def rel_match_value_ne; /* * Operand */ extern const struct sieve_operand_def rel_match_type_operand; /* * Match type validation */ bool mcht_relational_validate(struct sieve_validator *validator, struct sieve_ast_argument **arg, struct sieve_match_type_context *ctx); /* * Value match function (also used by :count) */ int mcht_value_match_key(struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/ext-relational.c0000644000175100001700000000221015100335616030347 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension relational * -------------------- * * Author: Stephan Bosch * Specification: RFC 3431 * Implementation: full * Status: testing * */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-relational-common.h" /* * Extension */ static bool ext_relational_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def relational_extension = { .name = "relational", .validator_load = ext_relational_validator_load, SIEVE_EXT_DEFINE_OPERAND(rel_match_type_operand) }; static bool ext_relational_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { sieve_match_type_register(valdtr, ext, &value_match_type); sieve_match_type_register(valdtr, ext, &count_match_type); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/relational/Makefile.in0000644000175100001700000005500715100335630027330 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/relational ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_relational_la_LIBADD = am_libsieve_ext_relational_la_OBJECTS = ext-relational-common.lo \ mcht-value.lo mcht-count.lo ext-relational.lo libsieve_ext_relational_la_OBJECTS = \ $(am_libsieve_ext_relational_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-relational-common.Plo \ ./$(DEPDIR)/ext-relational.Plo ./$(DEPDIR)/mcht-count.Plo \ ./$(DEPDIR)/mcht-value.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_relational_la_SOURCES) DIST_SOURCES = $(libsieve_ext_relational_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_relational.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_relational_la_SOURCES = \ ext-relational-common.c \ mcht-value.c \ mcht-count.c \ ext-relational.c noinst_HEADERS = \ ext-relational-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/relational/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/relational/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_relational.la: $(libsieve_ext_relational_la_OBJECTS) $(libsieve_ext_relational_la_DEPENDENCIES) $(EXTRA_libsieve_ext_relational_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_relational_la_OBJECTS) $(libsieve_ext_relational_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-relational-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-relational.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-count.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-value.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-relational-common.Plo -rm -f ./$(DEPDIR)/ext-relational.Plo -rm -f ./$(DEPDIR)/mcht-count.Plo -rm -f ./$(DEPDIR)/mcht-value.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-relational-common.Plo -rm -f ./$(DEPDIR)/ext-relational.Plo -rm -f ./$(DEPDIR)/mcht-count.Plo -rm -f ./$(DEPDIR)/mcht-value.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/0000755000175100001700000000000015100335670025076 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-settings.h0000644000175100001700000000052615100335616031656 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_SETTINGS_H #define EXT_VARIABLES_SETTINGS_H struct ext_variables_settings { pool_t pool; /* Maximum number of variables (in a scope) */ unsigned int max_scope_count; /* Maximum size of variable value */ uoff_t max_value_size; }; extern const struct setting_parser_info ext_variables_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/tst-string.c0000644000175100001700000001532315100335616027364 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-variables-common.h" /* * String test * * Syntax: * string [COMPARATOR] [MATCH-TYPE] * */ static bool tst_string_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_string_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_string_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def tst_string = { .identifier = "string", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_string_registered, .validate = tst_string_validate, .generate = tst_string_generate }; /* * String operation */ static bool tst_string_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_string_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_string_operation = { .mnemonic = "STRING", .ext_def = &variables_extension, .code = EXT_VARIABLES_OPERATION_STRING, .dump = tst_string_operation_dump, .execute = tst_string_operation_execute }; /* * Optional arguments */ enum tst_string_optional { OPT_END, OPT_COMPARATOR, OPT_MATCH_TYPE }; /* * Test registration */ static bool tst_string_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, OPT_MATCH_TYPE); return TRUE; } /* * Test validation */ static bool tst_string_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "source", 1, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate (valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Test generation */ static bool tst_string_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &tst_string_operation); /* Generate arguments */ if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; return TRUE; } /* * Code dump */ static bool tst_string_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "STRING-TEST"); sieve_code_descend(denv); /* Optional operands */ if ( sieve_match_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return sieve_opr_stringlist_dump(denv, address, "source") && sieve_opr_stringlist_dump(denv, address, "key list"); } /* * Code execution */ static int tst_string_stringlist_next_item (struct sieve_stringlist *_strlist, string_t **str_r); static void tst_string_stringlist_reset (struct sieve_stringlist *_strlist); static int tst_string_stringlist_get_length (struct sieve_stringlist *_strlist); struct tst_string_stringlist { struct sieve_stringlist strlist; struct sieve_stringlist *value_list; }; static struct sieve_stringlist *tst_string_stringlist_create (const struct sieve_runtime_env *renv, struct sieve_stringlist *value_list) { struct tst_string_stringlist *strlist; strlist = t_new(struct tst_string_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = tst_string_stringlist_next_item; strlist->strlist.reset = tst_string_stringlist_reset; strlist->strlist.get_length = tst_string_stringlist_get_length; strlist->value_list = value_list; return &strlist->strlist; } static int tst_string_stringlist_next_item (struct sieve_stringlist *_strlist, string_t **str_r) { struct tst_string_stringlist *strlist = (struct tst_string_stringlist *)_strlist; return sieve_stringlist_next_item(strlist->value_list, str_r); } static void tst_string_stringlist_reset (struct sieve_stringlist *_strlist) { struct tst_string_stringlist *strlist = (struct tst_string_stringlist *)_strlist; sieve_stringlist_reset(strlist->value_list); } static int tst_string_stringlist_get_length (struct sieve_stringlist *_strlist) { struct tst_string_stringlist *strlist = (struct tst_string_stringlist *)_strlist; string_t *item; int length = 0; int ret; while ( (ret=sieve_stringlist_next_item(strlist->value_list, &item)) > 0 ) { if ( str_len(item) > 0 ) length++; } return ( ret < 0 ? -1 : length ); } static int tst_string_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_stringlist *source, *value_list, *key_list; int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ if ( sieve_match_opr_optional_read (renv, address, NULL, &ret, &cmp, &mcht) < 0 ) return ret; /* Read source */ if ( (ret=sieve_opr_stringlist_read(renv, address, "source", &source)) <= 0 ) return ret; /* Read key-list */ if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) <= 0 ) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "string test"); /* Create wrapper string list wich does not count empty string items */ value_list = tst_string_stringlist_create(renv, source); /* Perform match */ if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-common.c0000644000175100001700000005573015100335616031310 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "hash.h" #include "str.h" #include "array.h" #include "settings.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-objects.h" #include "sieve-match-types.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-dump.h" #include "sieve-interpreter.h" #include "ext-variables-common.h" #include "ext-variables-name.h" #include "ext-variables-modifiers.h" /* * Limits */ unsigned int sieve_variables_get_max_scope_count(const struct sieve_extension *var_ext) { const struct ext_variables_context *extctx = ext_variables_get_context(var_ext); return extctx->set->max_scope_count; } size_t sieve_variables_get_max_value_size( const struct sieve_extension *var_ext) { const struct ext_variables_context *extctx = ext_variables_get_context(var_ext); return extctx->set->max_value_size; } /* * Extension configuration */ int ext_variables_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct ext_variables_settings *set; struct ext_variables_context *extctx; const char *error; if (settings_get(svinst->event, &ext_variables_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_variables_context, 1); extctx->set = set; *context_r = extctx; return 0; } void ext_variables_unload(const struct sieve_extension *ext) { struct ext_variables_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); i_free(extctx); } const struct ext_variables_context * ext_variables_get_context(const struct sieve_extension *var_ext) { const struct ext_variables_context *extctx = var_ext->context; i_assert(var_ext->def == &variables_extension); return extctx; } /* * Variable scope */ struct sieve_variable_scope { pool_t pool; int refcount; struct sieve_instance *svinst; const struct sieve_extension *var_ext; const struct sieve_extension *ext; struct sieve_variable *error_var; HASH_TABLE(const char *, struct sieve_variable *) variables; ARRAY(struct sieve_variable *) variable_index; }; struct sieve_variable_scope_binary { struct sieve_variable_scope *scope; unsigned int count; struct sieve_binary_block *sblock; sieve_size_t address; }; struct sieve_variable_scope_iter { struct sieve_variable_scope *scope; struct hash_iterate_context *hctx; }; struct sieve_variable_scope * sieve_variable_scope_create(struct sieve_instance *svinst, const struct sieve_extension *var_ext, const struct sieve_extension *ext) { struct sieve_variable_scope *scope; pool_t pool; i_assert(var_ext->def == &variables_extension); pool = pool_alloconly_create("sieve_variable_scope", 4096); scope = p_new(pool, struct sieve_variable_scope, 1); scope->pool = pool; scope->refcount = 1; scope->svinst = svinst; scope->var_ext = var_ext; scope->ext = ext; hash_table_create(&scope->variables, pool, 0, strcase_hash, strcasecmp); p_array_init(&scope->variable_index, pool, 128); return scope; } void sieve_variable_scope_ref(struct sieve_variable_scope *scope) { scope->refcount++; } void sieve_variable_scope_unref(struct sieve_variable_scope **_scope) { struct sieve_variable_scope *scope = *_scope; i_assert(scope->refcount > 0); if (--scope->refcount != 0) return; hash_table_destroy(&scope->variables); *_scope = NULL; pool_unref(&scope->pool); } pool_t sieve_variable_scope_pool(struct sieve_variable_scope *scope) { return scope->pool; } struct sieve_variable * sieve_variable_scope_declare(struct sieve_variable_scope *scope, const char *identifier) { unsigned int max_scope_count; struct sieve_variable *var; var = hash_table_lookup(scope->variables, identifier); if (var != NULL) return var; max_scope_count = sieve_variables_get_max_scope_count(scope->var_ext); if (array_count(&scope->variable_index) >= max_scope_count) { if (scope->error_var == NULL) { var = p_new(scope->pool, struct sieve_variable, 1); var->identifier = "@ERROR@"; var->index = 0; scope->error_var = var; return NULL; } return scope->error_var; } var = p_new(scope->pool, struct sieve_variable, 1); var->ext = scope->ext; var->identifier = p_strdup(scope->pool, identifier); var->index = array_count(&scope->variable_index); hash_table_insert(scope->variables, var->identifier, var); array_append(&scope->variable_index, &var, 1); return var; } struct sieve_variable * sieve_variable_scope_get_variable(struct sieve_variable_scope *scope, const char *identifier) { return hash_table_lookup(scope->variables, identifier); } struct sieve_variable * sieve_variable_scope_import(struct sieve_variable_scope *scope, struct sieve_variable *var) { struct sieve_variable *old_var, *new_var; old_var = sieve_variable_scope_get_variable(scope, var->identifier); if (old_var != NULL) { i_assert(memcmp(old_var, var, sizeof(*var)) == 0); return old_var; } new_var = p_new(scope->pool, struct sieve_variable, 1); memcpy(new_var, var, sizeof(*new_var)); hash_table_insert(scope->variables, new_var->identifier, new_var); /* Not entered into the index because it is an external variable (This can be done unlimited; only limited by the size of the external scope) */ return new_var; } struct sieve_variable_scope_iter * sieve_variable_scope_iterate_init(struct sieve_variable_scope *scope) { struct sieve_variable_scope_iter *iter; iter = t_new(struct sieve_variable_scope_iter, 1); iter->scope = scope; iter->hctx = hash_table_iterate_init(scope->variables); return iter; } bool sieve_variable_scope_iterate(struct sieve_variable_scope_iter *iter, struct sieve_variable **var_r) { const char *key; return hash_table_iterate(iter->hctx, iter->scope->variables, &key, var_r); } void sieve_variable_scope_iterate_deinit( struct sieve_variable_scope_iter **iter) { hash_table_iterate_deinit(&(*iter)->hctx); *iter = NULL; } unsigned int sieve_variable_scope_declarations(struct sieve_variable_scope *scope) { return hash_table_count(scope->variables); } unsigned int sieve_variable_scope_size(struct sieve_variable_scope *scope) { return array_count(&scope->variable_index); } struct sieve_variable *const * sieve_variable_scope_get_variables(struct sieve_variable_scope *scope, unsigned int *size_r) { return array_get(&scope->variable_index, size_r); } struct sieve_variable * sieve_variable_scope_get_indexed(struct sieve_variable_scope *scope, unsigned int index) { struct sieve_variable *const *var; if (index >= array_count(&scope->variable_index)) return NULL; var = array_idx(&scope->variable_index, index); return *var; } /* Scope binary */ struct sieve_variable_scope * sieve_variable_scope_binary_dump(struct sieve_instance *svinst, const struct sieve_extension *var_ext, const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct sieve_variable_scope *local_scope; unsigned int i, scope_size; sieve_size_t pc; sieve_offset_t end_offset; /* Read scope size */ sieve_code_mark(denv); if (!sieve_binary_read_unsigned(denv->sblock, address, &scope_size)) return NULL; /* Read offset */ pc = *address; if (!sieve_binary_read_offset(denv->sblock, address, &end_offset)) return NULL; /* Create scope */ local_scope = sieve_variable_scope_create(svinst, var_ext, ext); /* Read and dump scope itself */ sieve_code_dumpf(denv, "VARIABLES SCOPE [%u] (end: %08x)", scope_size, (unsigned int)(pc + end_offset)); for (i = 0; i < scope_size; i++) { string_t *identifier; sieve_code_mark(denv); if (!sieve_binary_read_string(denv->sblock, address, &identifier)) return NULL; sieve_code_dumpf(denv, "%3d: '%s'", i, str_c(identifier)); (void)sieve_variable_scope_declare(local_scope, str_c(identifier)); } return local_scope; } struct sieve_variable_scope_binary * sieve_variable_scope_binary_create(struct sieve_variable_scope *scope) { struct sieve_variable_scope_binary *scpbin; scpbin = p_new(scope->pool, struct sieve_variable_scope_binary, 1); scpbin->scope = scope; return scpbin; } void sieve_variable_scope_binary_ref(struct sieve_variable_scope_binary *scpbin) { sieve_variable_scope_ref(scpbin->scope); } void sieve_variable_scope_binary_unref( struct sieve_variable_scope_binary **scpbin) { sieve_variable_scope_unref(&(*scpbin)->scope); *scpbin = NULL; } struct sieve_variable_scope_binary * sieve_variable_scope_binary_read(struct sieve_instance *svinst, const struct sieve_extension *var_ext, const struct sieve_extension *ext, struct sieve_binary_block *sblock, sieve_size_t *address) { struct sieve_variable_scope *scope; struct sieve_variable_scope_binary *scpbin; unsigned int scope_count, max_scope_count; const char *ext_name = (ext == NULL ? "variables" : sieve_extension_name(ext)); sieve_size_t pc; sieve_offset_t end_offset; /* Read scope size */ if (!sieve_binary_read_unsigned(sblock, address, &scope_count)) { e_error(svinst->event, "%s: " "variable scope: failed to read count", ext_name); return NULL; } /* Check size limit */ max_scope_count = sieve_variables_get_max_scope_count(var_ext); if (scope_count > max_scope_count) { e_error(svinst->event, "%s: " "variable scope: count exceeds the limit (%u > %u)", ext_name, scope_count, max_scope_count); return NULL; } /* Read offset */ pc = *address; if (!sieve_binary_read_offset(sblock, address, &end_offset)) { e_error(svinst->event, "%s: " "variable scope: failed to read end offset", ext_name); return NULL; } /* Create scope */ scope = sieve_variable_scope_create(svinst, var_ext, ext); scpbin = sieve_variable_scope_binary_create(scope); scpbin->count = scope_count; scpbin->sblock = sblock; scpbin->address = *address; *address = pc + end_offset; return scpbin; } struct sieve_variable_scope * sieve_variable_scope_binary_get(struct sieve_variable_scope_binary *scpbin) { const struct sieve_extension *ext = scpbin->scope->ext; struct sieve_instance *svinst = scpbin->scope->svinst; const char *ext_name = (ext == NULL ? "variables" : sieve_extension_name(ext)); unsigned int i; if (scpbin->sblock != NULL) { sieve_size_t *address = &scpbin->address; /* Read scope itself */ for (i = 0; i < scpbin->count; i++) { struct sieve_variable *var; string_t *identifier; if (!sieve_binary_read_string(scpbin->sblock, address, &identifier)) { e_error(svinst->event, "%s: variable scope: " "failed to read variable name", ext_name); return NULL; } var = sieve_variable_scope_declare(scpbin->scope, str_c(identifier)); i_assert(var != NULL); i_assert(var->index == i); } scpbin->sblock = NULL; } return scpbin->scope; } unsigned int sieve_variable_scope_binary_get_count( struct sieve_variable_scope_binary *scpbin) { if (scpbin->sblock != NULL) return scpbin->count; return array_count(&scpbin->scope->variable_index); } /* * Variable storage */ struct sieve_variable_storage { pool_t pool; const struct sieve_extension *var_ext; struct sieve_variable_scope *scope; struct sieve_variable_scope_binary *scope_bin; unsigned int max_count; ARRAY(string_t *) var_values; }; struct sieve_variable_storage * sieve_variable_storage_create(const struct sieve_extension *var_ext, pool_t pool, struct sieve_variable_scope_binary *scpbin) { struct sieve_variable_storage *storage; storage = p_new(pool, struct sieve_variable_storage, 1); storage->pool = pool; storage->var_ext = var_ext; storage->scope_bin = scpbin; storage->scope = NULL; storage->max_count = sieve_variable_scope_binary_get_count(scpbin); p_array_init(&storage->var_values, pool, 4); return storage; } static inline bool sieve_variable_valid(struct sieve_variable_storage *storage, unsigned int index) { if (storage->scope_bin == NULL) return TRUE; return (index < storage->max_count); } bool sieve_variable_get_identifier(struct sieve_variable_storage *storage, unsigned int index, const char **identifier) { struct sieve_variable *const *var; *identifier = NULL; if (storage->scope_bin == NULL) return TRUE; if (storage->scope == NULL) { storage->scope = sieve_variable_scope_binary_get(storage->scope_bin); if (storage->scope == NULL) return FALSE; } /* FIXME: direct invasion of the scope object is a bit ugly */ if (index >= array_count(&storage->scope->variable_index)) return FALSE; var = array_idx(&storage->scope->variable_index, index); if (*var != NULL) *identifier = (*var)->identifier; return TRUE; } const char * sieve_variable_get_varid(struct sieve_variable_storage *storage, unsigned int index) { if (storage->scope_bin == NULL) return t_strdup_printf("%ld", (long)index); if (storage->scope == NULL) { storage->scope = sieve_variable_scope_binary_get(storage->scope_bin); if (storage->scope == NULL) return NULL; } return sieve_ext_variables_get_varid(storage->scope->ext, index); } bool sieve_variable_get(struct sieve_variable_storage *storage, unsigned int index, string_t **value) { *value = NULL; if (index < array_count(&storage->var_values)) { string_t *const *varent; varent = array_idx(&storage->var_values, index); *value = *varent; } else if (!sieve_variable_valid(storage, index)) { return FALSE; } return TRUE; } bool sieve_variable_get_modifiable(struct sieve_variable_storage *storage, unsigned int index, string_t **value) { string_t *dummy; if (value == NULL) value = &dummy; if (!sieve_variable_get(storage, index, value)) return FALSE; if (*value == NULL) { *value = str_new(storage->pool, 256); array_idx_set(&storage->var_values, index, value); } return TRUE; } bool sieve_variable_assign(struct sieve_variable_storage *storage, unsigned int index, const string_t *value) { const struct ext_variables_context *extctx = ext_variables_get_context(storage->var_ext); string_t *varval; if (!sieve_variable_get_modifiable(storage, index, &varval)) return FALSE; str_truncate(varval, 0); str_append_str(varval, value); /* Just a precaution, caller should prevent this in the first place */ if (str_len(varval) > extctx->set->max_value_size) str_truncate_utf8(varval, extctx->set->max_value_size); return TRUE; } bool sieve_variable_assign_cstr(struct sieve_variable_storage *storage, unsigned int index, const char *value) { const struct ext_variables_context *extctx = ext_variables_get_context(storage->var_ext); string_t *varval; if (!sieve_variable_get_modifiable(storage, index, &varval)) return FALSE; str_truncate(varval, 0); str_append(varval, value); /* Just a precaution, caller should prevent this in the first place */ if (str_len(varval) > extctx->set->max_value_size) str_truncate_utf8(varval, extctx->set->max_value_size); return TRUE; } /* * AST Context */ static void ext_variables_ast_free(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_ast *ast ATTR_UNUSED, void *context) { struct sieve_variable_scope *local_scope = (struct sieve_variable_scope *)context; /* Unreference main variable scope */ sieve_variable_scope_unref(&local_scope); } static const struct sieve_ast_extension variables_ast_extension = { &variables_extension, ext_variables_ast_free, }; static struct sieve_variable_scope * ext_variables_create_local_scope(const struct sieve_extension *this_ext, struct sieve_ast *ast) { struct sieve_variable_scope *scope; scope = sieve_variable_scope_create(this_ext->svinst, this_ext, NULL); sieve_ast_extension_register(ast, this_ext, &variables_ast_extension, scope); return scope; } static struct sieve_variable_scope * ext_variables_ast_get_local_scope(const struct sieve_extension *this_ext, struct sieve_ast *ast) { struct sieve_variable_scope *local_scope = (struct sieve_variable_scope *) sieve_ast_extension_get_context(ast, this_ext); return local_scope; } /* * Validator context */ static struct ext_variables_validator_context * ext_variables_validator_context_create(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { pool_t pool = sieve_validator_pool(valdtr); struct ext_variables_validator_context *ctx; struct sieve_ast *ast = sieve_validator_ast(valdtr); ctx = p_new(pool, struct ext_variables_validator_context, 1); ctx->modifiers = sieve_validator_object_registry_create(valdtr); ctx->namespaces = sieve_validator_object_registry_create(valdtr); ctx->local_scope = ext_variables_create_local_scope(this_ext, ast); sieve_validator_extension_set_context(valdtr, this_ext, ctx); return ctx; } struct ext_variables_validator_context * ext_variables_validator_context_get(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_variables_validator_context *ctx; i_assert(sieve_extension_is(this_ext, variables_extension)); ctx = (struct ext_variables_validator_context *) sieve_validator_extension_get_context(valdtr, this_ext); if (ctx == NULL) ctx = ext_variables_validator_context_create(this_ext, valdtr); return ctx; } void ext_variables_validator_initialize(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_variables_validator_context *ctx; /* Create our context */ ctx = ext_variables_validator_context_get(this_ext, valdtr); ext_variables_register_core_modifiers(this_ext, ctx); ctx->active = TRUE; } struct sieve_variable *ext_variables_validator_get_variable( const struct sieve_extension *this_ext, struct sieve_validator *validator, const char *variable) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(this_ext, validator); return sieve_variable_scope_get_variable(ctx->local_scope, variable); } struct sieve_variable * ext_variables_validator_declare_variable(const struct sieve_extension *this_ext, struct sieve_validator *validator, const char *variable) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(this_ext, validator); return sieve_variable_scope_declare(ctx->local_scope, variable); } struct sieve_variable_scope * sieve_ext_variables_get_local_scope(const struct sieve_extension *var_ext, struct sieve_validator *validator) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, validator); return ctx->local_scope; } bool sieve_ext_variables_is_active(const struct sieve_extension *var_ext, struct sieve_validator *valdtr) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); return (ctx != NULL && ctx->active); } /* * Code generation */ bool ext_variables_generator_load(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv) { struct sieve_variable_scope *local_scope = ext_variables_ast_get_local_scope(ext, cgenv->ast); unsigned int count = sieve_variable_scope_size(local_scope); sieve_size_t jump; sieve_binary_emit_unsigned(cgenv->sblock, count); jump = sieve_binary_emit_offset(cgenv->sblock, 0); if (count > 0) { unsigned int size, i; struct sieve_variable *const *vars = sieve_variable_scope_get_variables(local_scope, &size); for (i = 0; i < size; i++) { sieve_binary_emit_cstring(cgenv->sblock, vars[i]->identifier); } } sieve_binary_resolve_offset(cgenv->sblock, jump); return TRUE; } /* * Interpreter context */ struct ext_variables_interpreter_context { pool_t pool; struct sieve_variable_scope *local_scope; struct sieve_variable_scope_binary *local_scope_bin; struct sieve_variable_storage *local_storage; ARRAY(struct sieve_variable_storage *) ext_storages; }; static void ext_variables_interpreter_free(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_interpreter *interp ATTR_UNUSED, void *context) { struct ext_variables_interpreter_context *ctx = (struct ext_variables_interpreter_context *)context; sieve_variable_scope_binary_unref(&ctx->local_scope_bin); } static struct sieve_interpreter_extension variables_interpreter_extension = { .ext_def = &variables_extension, .free = ext_variables_interpreter_free, }; static struct ext_variables_interpreter_context * ext_variables_interpreter_context_create( const struct sieve_extension *this_ext, struct sieve_interpreter *interp, struct sieve_variable_scope_binary *scpbin) { pool_t pool = sieve_interpreter_pool(interp); struct ext_variables_interpreter_context *ctx; ctx = p_new(pool, struct ext_variables_interpreter_context, 1); ctx->pool = pool; ctx->local_scope = NULL; ctx->local_scope_bin = scpbin; ctx->local_storage = sieve_variable_storage_create(this_ext, pool, scpbin); p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count(this_ext->svinst)); sieve_interpreter_extension_register(interp, this_ext, &variables_interpreter_extension, ctx); return ctx; } bool ext_variables_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_execute_env *eenv = renv->exec_env; struct sieve_variable_scope_binary *scpbin; scpbin = sieve_variable_scope_binary_read(eenv->svinst, ext, NULL, renv->sblock, address); if (scpbin == NULL) return FALSE; /* Create our context */ (void)ext_variables_interpreter_context_create(ext, renv->interp, scpbin); /* Enable support for match values */ (void)sieve_match_values_set_enabled(renv, TRUE); return TRUE; } static inline struct ext_variables_interpreter_context * ext_variables_interpreter_context_get(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_variables_interpreter_context *ctx; i_assert(sieve_extension_is(this_ext, variables_extension)); ctx = (struct ext_variables_interpreter_context *) sieve_interpreter_extension_get_context(interp, this_ext); return ctx; } struct sieve_variable_storage * sieve_ext_variables_runtime_get_storage(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv, const struct sieve_extension *ext) { struct ext_variables_interpreter_context *ctx = ext_variables_interpreter_context_get(var_ext, renv->interp); struct sieve_variable_storage *const *storage; if (ext == NULL) return ctx->local_storage; if (ext->id >= (int)array_count(&ctx->ext_storages)) storage = NULL; else storage = array_idx(&ctx->ext_storages, ext->id); if (storage == NULL) return NULL; return *storage; } void sieve_ext_variables_runtime_set_storage( const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv, const struct sieve_extension *ext, struct sieve_variable_storage *storage) { struct ext_variables_interpreter_context *ctx = ext_variables_interpreter_context_get(var_ext, renv->interp); if (ctx == NULL || ext == NULL || storage == NULL) return; if (ext->id < 0) return; array_idx_set(&ctx->ext_storages, (unsigned int) ext->id, &storage); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/Makefile.am0000644000175100001700000000153515100335616027136 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_variables.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) cmds = \ cmd-set.c tsts = \ tst-string.c libsieve_ext_variables_la_SOURCES = \ ext-variables-settings.c \ ext-variables-common.c \ ext-variables-name.c \ ext-variables-namespaces.c \ ext-variables-arguments.c \ ext-variables-operands.c \ ext-variables-modifiers.c \ ext-variables-dump.c \ $(cmds) \ $(tsts) \ ext-variables.c public_headers = \ sieve-ext-variables.h headers = \ ext-variables-settings.h \ ext-variables-common.h \ ext-variables-limits.h \ ext-variables-name.h \ ext-variables-namespaces.h \ ext-variables-arguments.h \ ext-variables-operands.h \ ext-variables-modifiers.h \ ext-variables-dump.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-dump.c0000644000175100001700000000646415100335616030765 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-code.h" #include "ext-variables-common.h" #include "ext-variables-dump.h" /* * Code dumper extension */ static void ext_variables_code_dumper_free (struct sieve_code_dumper *dumper, void *context); static const struct sieve_code_dumper_extension variables_dump_extension = { &variables_extension, ext_variables_code_dumper_free }; /* * Code dump context */ struct ext_variables_dump_context { struct sieve_variable_scope *local_scope; ARRAY(struct sieve_variable_scope *) ext_scopes; }; static void ext_variables_code_dumper_free (struct sieve_code_dumper *dumper ATTR_UNUSED, void *context) { struct ext_variables_dump_context *dctx = (struct ext_variables_dump_context *) context; if ( dctx == NULL || dctx->local_scope == NULL ) return; sieve_variable_scope_unref(&dctx->local_scope); } static struct ext_variables_dump_context *ext_variables_dump_get_context (const struct sieve_extension *this_ext, const struct sieve_dumptime_env *denv) { struct sieve_code_dumper *dumper = denv->cdumper; struct ext_variables_dump_context *dctx; pool_t pool; i_assert( sieve_extension_is(this_ext, variables_extension) ); dctx = sieve_dump_extension_get_context(dumper, this_ext); if ( dctx == NULL ) { /* Create dumper context */ pool = sieve_code_dumper_pool(dumper); dctx = p_new(pool, struct ext_variables_dump_context, 1); p_array_init(&dctx->ext_scopes, pool, sieve_extensions_get_count(this_ext->svinst)); sieve_dump_extension_register (dumper, this_ext, &variables_dump_extension, dctx); } return dctx; } bool ext_variables_code_dump (const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct ext_variables_dump_context *dctx; struct sieve_variable_scope *local_scope; local_scope = sieve_variable_scope_binary_dump (ext->svinst, ext, NULL, denv, address); dctx = ext_variables_dump_get_context(ext, denv); dctx->local_scope = local_scope; return TRUE; } /* * Scope registry */ void sieve_ext_variables_dump_set_scope (const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, struct sieve_variable_scope *scope) { struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(var_ext, denv); if ( ext->id < 0 ) return; array_idx_set(&dctx->ext_scopes, (unsigned int) ext->id, &scope); } /* * Variable identifier dump */ const char *ext_variables_dump_get_identifier (const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, unsigned int index) { struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(var_ext, denv); struct sieve_variable_scope *scope; struct sieve_variable *var; if ( ext == NULL ) scope = dctx->local_scope; else { struct sieve_variable_scope *const *ext_scope; if ( ext->id < 0 || ext->id >= (int) array_count(&dctx->ext_scopes) ) return NULL; ext_scope = array_idx(&dctx->ext_scopes, (unsigned int) ext->id); scope = *ext_scope; } if ( scope == NULL ) return NULL; var = sieve_variable_scope_get_indexed(scope, index); return var->identifier; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-name.h0000644000175100001700000000312715100335616030736 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_NAME_H #define EXT_VARIABLES_NAME_H /* Variable Substitution * --------------------- * * The variable strings are preprocessed into an AST list consisting of variable * substitutions and constant parts of the string. The variables to which * the substitutions link are looked up and their index in their scope storage * is what is added to the list and eventually emitted as byte code. So, in * bytecode a variable string will look as a series of substrings interrupted by * integer operands that refer to variables. During execution, the strings and * the looked-up variables are concatenated to obtain the desired result. The * the variable references are simple indexes into an array of variables, so * looking these up during execution is a trivial process. * * However (RFC 5229): * Tests or actions in future extensions may need to access the * unexpanded version of the string argument and, e.g., do the expansion * after setting variables in its namespace. The design of the * implementation should allow this. * * Various options exist to provide this feature. If the extension is entirely * namespace-based there is actually not very much of a problem. The variable * list can easily be extended with new argument-types that refer to a variable * identifier instead of an index in the variable's storage. */ #include "lib.h" #include "array.h" #include "sieve-common.h" #include "ext-variables-common.h" /* * Variable name parsing */ int ext_variable_name_parse (ARRAY_TYPE(sieve_variable_name) *vname, const char **str, const char *strend); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/cmd-set.c0000644000175100001700000001273615100335616026607 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "array.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-ast.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-variables-common.h" /* * Set command * * Syntax: * set [MODIFIER] */ static bool cmd_set_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_set_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_set_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def cmd_set = { .identifier = "set", .type = SCT_COMMAND, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_set_registered, .validate = cmd_set_validate, .generate = cmd_set_generate, }; /* * Set operation */ static bool cmd_set_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_set_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def cmd_set_operation = { .mnemonic = "SET", .ext_def = &variables_extension, .code = EXT_VARIABLES_OPERATION_SET, .dump = cmd_set_operation_dump, .execute = cmd_set_operation_execute, }; /* * Compiler context */ struct cmd_set_context { ARRAY_TYPE(sieve_variables_modifier) modifiers; }; /* Command registration */ static bool cmd_set_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_variables_modifiers_link_tag(valdtr, ext, cmd_reg); return TRUE; } /* * Command validation */ static bool cmd_set_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; pool_t pool = sieve_command_pool(cmd); struct cmd_set_context *sctx; /* Create command context */ sctx = p_new(pool, struct cmd_set_context, 1); p_array_init(&sctx->modifiers, pool, 4); cmd->data = sctx; /* Validate modifiers */ if (!sieve_variables_modifiers_validate(valdtr, cmd, &sctx->modifiers)) return FALSE; /* Validate name argument */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "name", 1, SAAT_STRING)) return FALSE; if (!sieve_variable_argument_activate(this_ext, this_ext, valdtr, cmd, arg, TRUE)) return FALSE; arg = sieve_ast_argument_next(arg); /* Validate value argument */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "value", 2, SAAT_STRING)) return FALSE; return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } /* * Code generation */ static bool cmd_set_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_binary_block *sblock = cgenv->sblock; struct cmd_set_context *sctx = (struct cmd_set_context *) cmd->data; sieve_operation_emit(sblock, this_ext, &cmd_set_operation); /* Generate arguments */ if (!sieve_generate_arguments(cgenv, cmd, NULL)) return FALSE; /* Generate modifiers */ if (!sieve_variables_modifiers_generate(cgenv, &sctx->modifiers)) return FALSE; return TRUE; } /* * Code dump */ static bool cmd_set_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "SET"); sieve_code_descend(denv); /* Print both variable name and string value */ if (!sieve_opr_string_dump(denv, address, "variable") || !sieve_opr_string_dump(denv, address, "value")) return FALSE; return sieve_variables_modifiers_code_dump(denv, address); } /* * Code execution */ static int cmd_set_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct sieve_variable_storage *storage; ARRAY_TYPE(sieve_variables_modifier) modifiers; unsigned int var_index; string_t *value; int ret = SIEVE_EXEC_OK; /* * Read the normal operands */ ret = sieve_variable_operand_read(renv, address, "variable", &storage, &var_index); if (ret <= 0) return ret; ret = sieve_opr_string_read(renv, address, "string", &value); if (ret <= 0) return ret; ret = sieve_variables_modifiers_code_read(renv, this_ext, address, &modifiers); if (ret <= 0) return ret; /* * Determine and assign the value */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "set command"); sieve_runtime_trace_descend(renv); /* Apply modifiers */ ret = sieve_variables_modifiers_apply(renv, this_ext, &modifiers, &value); if (ret <= 0) return ret; /* Actually assign the value if all is well */ i_assert (value != NULL); if (!sieve_variable_assign(storage, var_index, value)) return SIEVE_EXEC_BIN_CORRUPT; /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { const char *var_name, *var_id; (void)sieve_variable_get_identifier(storage, var_index, &var_name); var_id = sieve_variable_get_varid(storage, var_index); sieve_runtime_trace_here(renv, 0, "assign '%s' [%s] = \"%s\"", var_name, var_id, str_c(value)); } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-arguments.h0000644000175100001700000000060315100335616032017 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_ARGUMENTS_H #define EXT_VARIABLES_ARGUMENTS_H #include "sieve-common.h" /* * Variable argument */ extern const struct sieve_argument_def variable_argument; /* * Match value argument */ extern const struct sieve_argument_def match_value_argument; /* * Variable string argument */ extern const struct sieve_argument_def variable_string_argument; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-operands.c0000644000175100001700000002040015100335616031615 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "hash.h" #include "str.h" #include "array.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-match-types.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-dump.h" #include "sieve-interpreter.h" #include "ext-variables-common.h" #include "ext-variables-limits.h" #include "ext-variables-name.h" #include "ext-variables-dump.h" #include "ext-variables-operands.h" /* * Variable operand */ static bool opr_variable_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); static int opr_variable_read_value(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface variable_interface = { opr_variable_dump, opr_variable_read_value, }; const struct sieve_operand_def variable_operand = { .name = "variable", .ext_def = &variables_extension, .code = EXT_VARIABLES_OPERAND_VARIABLE, .class = &string_class, .interface = &variable_interface, }; void sieve_variables_opr_variable_emit(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, struct sieve_variable *var) { i_assert(sieve_extension_is(var_ext, variables_extension)); if (var->ext == NULL) { /* Default variable storage */ (void)sieve_operand_emit(sblock, var_ext, &variable_operand); (void)sieve_binary_emit_byte(sblock, 0); /* Default */ (void)sieve_binary_emit_unsigned(sblock, var->index); return; } (void)sieve_operand_emit(sblock, var_ext, &variable_operand); (void)sieve_binary_emit_extension(sblock, var->ext, 1); /* Extension */ (void)sieve_binary_emit_unsigned(sblock, var->index); } static bool opr_variable_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { const struct sieve_extension *this_ext = oprnd->ext; unsigned int index = 0; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ const char *identifier; if (!sieve_binary_read_extension(denv->sblock, address, &code, &ext)) return FALSE; if (!sieve_binary_read_unsigned(denv->sblock, address, &index)) return FALSE; identifier = ext_variables_dump_get_identifier(this_ext, denv, ext, index); identifier = (identifier == NULL ? "??" : identifier); if (oprnd->field_name != NULL) { sieve_code_dumpf(denv, "%s: VAR[%s] ${%s}", oprnd->field_name, sieve_ext_variables_get_varid(ext, index), identifier); } else { sieve_code_dumpf(denv, "VAR[%s] ${%s}", sieve_ext_variables_get_varid(ext, index), identifier); } return TRUE; } static int opr_variable_read_value(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r) { const struct sieve_extension *this_ext = oprnd->ext; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ struct sieve_variable_storage *storage; unsigned int index = 0; if (!sieve_binary_read_extension(renv->sblock, address, &code, &ext)) { sieve_runtime_trace_operand_error( renv, oprnd, "variable operand corrupt: " "invalid extension byte"); return SIEVE_EXEC_BIN_CORRUPT; } storage = sieve_ext_variables_runtime_get_storage(this_ext, renv, ext); if (storage == NULL) { sieve_runtime_trace_operand_error( renv, oprnd, "variable operand corrupt: " "extension has no storage"); return SIEVE_EXEC_BIN_CORRUPT; } if (sieve_binary_read_unsigned(renv->sblock, address, &index)) { /* Parameter str can be NULL if we are requested to only skip and not actually read the argument. */ if (str_r != NULL) { if (!sieve_variable_get(storage, index, str_r)) return SIEVE_EXEC_FAILURE; if (*str_r == NULL) *str_r = t_str_new(0); } return SIEVE_EXEC_OK; } sieve_runtime_trace_operand_error( renv, oprnd, "variable operand corrupt: " "invalid variable index"); return SIEVE_EXEC_BIN_CORRUPT; } int sieve_variable_operand_read_data( const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, struct sieve_variable_storage **storage_r, unsigned int *var_index_r) { const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ unsigned int idx = 0; oprnd->field_name = field_name; if (!sieve_operand_is_variable(oprnd)) { sieve_runtime_trace_operand_error( renv, oprnd, "expected variable operand but found %s", sieve_operand_name(oprnd)); return SIEVE_EXEC_BIN_CORRUPT; } if (!sieve_binary_read_extension(renv->sblock, address, &code, &ext)) { sieve_runtime_trace_operand_error( renv, oprnd, "variable operand corrupt: " "invalid extension byte"); return SIEVE_EXEC_BIN_CORRUPT; } *storage_r = sieve_ext_variables_runtime_get_storage( oprnd->ext, renv, ext); if (*storage_r == NULL) { sieve_runtime_trace_operand_error( renv, oprnd, "variable operand corrupt: " "extension has no storage"); return SIEVE_EXEC_BIN_CORRUPT; } if (!sieve_binary_read_unsigned(renv->sblock, address, &idx)) { sieve_runtime_trace_operand_error( renv, oprnd, "variable operand corrupt: " "invalid variable index"); return SIEVE_EXEC_BIN_CORRUPT; } *var_index_r = idx; return SIEVE_EXEC_OK; } int sieve_variable_operand_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_variable_storage **storage_r, unsigned int *var_index_r) { struct sieve_operand operand; int ret; ret = sieve_operand_runtime_read(renv, address, field_name, &operand); if (ret <= 0) return ret; return sieve_variable_operand_read_data( renv, &operand, address, field_name, storage_r, var_index_r); } /* * Match value operand */ static bool opr_match_value_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); static int opr_match_value_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface match_value_interface = { opr_match_value_dump, opr_match_value_read, }; const struct sieve_operand_def match_value_operand = { .name = "match-value", .ext_def = &variables_extension, .code = EXT_VARIABLES_OPERAND_MATCH_VALUE, .class = &string_class, .interface = &match_value_interface, }; void sieve_variables_opr_match_value_emit(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, unsigned int index) { i_assert(sieve_extension_is(var_ext, variables_extension)); (void)sieve_operand_emit(sblock, var_ext, &match_value_operand); (void)sieve_binary_emit_unsigned(sblock, index); } static bool opr_match_value_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { unsigned int index = 0; if (sieve_binary_read_unsigned(denv->sblock, address, &index)) { if (oprnd->field_name != NULL) { sieve_code_dumpf(denv, "%s: MATCHVAL %lu", oprnd->field_name, (unsigned long)index); } else { sieve_code_dumpf(denv, "MATCHVAL %lu", (unsigned long)index); } return TRUE; } return FALSE; } static int opr_match_value_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r) { const struct sieve_extension *this_ext = oprnd->ext; const struct ext_variables_context *extctx = ext_variables_get_context(this_ext); unsigned int index = 0; if (sieve_binary_read_unsigned(renv->sblock, address, &index)) { /* Parameter str can be NULL if we are requested to only skip and not actually read the argument. */ if (str_r != NULL) { sieve_match_values_get(renv, index, str_r); if (*str_r == NULL) *str_r = t_str_new(0); else if (str_len(*str_r) > extctx->set->max_value_size) { str_truncate_utf8( *str_r, extctx->set->max_value_size); } } return SIEVE_EXEC_OK; } sieve_runtime_trace_operand_error( renv, oprnd, "match value operand corrupt: invalid index data"); return SIEVE_EXEC_BIN_CORRUPT; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-operands.h0000644000175100001700000000131415100335616031625 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_OPERANDS_H #define EXT_VARIABLES_OPERANDS_H #include "lib.h" #include "hash.h" #include "str.h" #include "array.h" #include "sieve-common.h" #include "ext-variables-common.h" /* * Variable operand */ extern const struct sieve_operand_def variable_operand; bool ext_variables_opr_variable_read(const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_variable_storage **storage, unsigned int *var_index); /* * Match value operand */ extern const struct sieve_operand_def match_value_operand; /* * Variable string operand */ void ext_variables_opr_variable_string_emit(struct sieve_binary *sbin, unsigned int elements); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-modifiers.c0000644000175100001700000003544715100335616032004 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "unichar.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-runtime.h" #include "ext-variables-common.h" #include "ext-variables-limits.h" #include "ext-variables-modifiers.h" #include /* * Core modifiers */ extern const struct sieve_variables_modifier_def lower_modifier; extern const struct sieve_variables_modifier_def upper_modifier; extern const struct sieve_variables_modifier_def lowerfirst_modifier; extern const struct sieve_variables_modifier_def upperfirst_modifier; extern const struct sieve_variables_modifier_def quotewildcard_modifier; extern const struct sieve_variables_modifier_def length_modifier; enum ext_variables_modifier_code { EXT_VARIABLES_MODIFIER_LOWER, EXT_VARIABLES_MODIFIER_UPPER, EXT_VARIABLES_MODIFIER_LOWERFIRST, EXT_VARIABLES_MODIFIER_UPPERFIRST, EXT_VARIABLES_MODIFIER_QUOTEWILDCARD, EXT_VARIABLES_MODIFIER_LENGTH, EXT_VARIABLES_MODIFIER_COUNT }; const struct sieve_variables_modifier_def *ext_variables_core_modifiers[] = { &lower_modifier, &upper_modifier, &lowerfirst_modifier, &upperfirst_modifier, "ewildcard_modifier, &length_modifier, }; static_assert_array_size(ext_variables_core_modifiers, EXT_VARIABLES_MODIFIER_COUNT); const unsigned int ext_variables_core_modifiers_count = N_ELEMENTS(ext_variables_core_modifiers); #define ext_variables_modifier_name(modf) \ (modf)->object->def->name #define ext_variables_modifiers_equal(modf1, modf2) \ ((modf1)->def == (modf2)->def) #define ext_variables_modifiers_equal_precedence(modf1, modf2) \ ((modf1)->def->precedence == (modf2)->def->precendence) /* * Modifier registry */ void sieve_variables_modifier_register( const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_variables_modifier_def *smodf_def) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); sieve_validator_object_registry_add(ctx->modifiers, ext, &smodf_def->obj_def); } bool ext_variables_modifier_exists(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const char *identifier) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); return sieve_validator_object_registry_find(ctx->modifiers, identifier, NULL); } const struct sieve_variables_modifier * ext_variables_modifier_create_instance(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); struct sieve_object object; struct sieve_variables_modifier *modf; pool_t pool; if (!sieve_validator_object_registry_find(ctx->modifiers, identifier, &object)) return NULL; pool = sieve_command_pool(cmd); modf = p_new(pool, struct sieve_variables_modifier, 1); modf->object = object; modf->var_ext = var_ext; modf->def = (const struct sieve_variables_modifier_def *) object.def; return modf; } void ext_variables_register_core_modifiers( const struct sieve_extension *ext, struct ext_variables_validator_context *ctx) { unsigned int i; /* Register core modifiers*/ for (i = 0; i < ext_variables_core_modifiers_count; i++) { sieve_validator_object_registry_add( ctx->modifiers, ext, &(ext_variables_core_modifiers[i]->obj_def)); } } /* * Core modifiers */ /* Forward declarations */ static bool mod_lower_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); static bool mod_upper_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); static bool mod_lowerfirst_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); static bool mod_upperfirst_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); static bool mod_length_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); static bool mod_quotewildcard_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); /* Modifier objects */ const struct sieve_variables_modifier_def lower_modifier = { SIEVE_OBJECT("lower", &modifier_operand, EXT_VARIABLES_MODIFIER_LOWER), 40, mod_lower_modify, }; const struct sieve_variables_modifier_def upper_modifier = { SIEVE_OBJECT("upper", &modifier_operand, EXT_VARIABLES_MODIFIER_UPPER), 40, mod_upper_modify, }; const struct sieve_variables_modifier_def lowerfirst_modifier = { SIEVE_OBJECT("lowerfirst", &modifier_operand, EXT_VARIABLES_MODIFIER_LOWERFIRST), 30, mod_lowerfirst_modify, }; const struct sieve_variables_modifier_def upperfirst_modifier = { SIEVE_OBJECT("upperfirst", &modifier_operand, EXT_VARIABLES_MODIFIER_UPPERFIRST), 30, mod_upperfirst_modify, }; const struct sieve_variables_modifier_def quotewildcard_modifier = { SIEVE_OBJECT("quotewildcard", &modifier_operand, EXT_VARIABLES_MODIFIER_QUOTEWILDCARD), 20, mod_quotewildcard_modify, }; const struct sieve_variables_modifier_def length_modifier = { SIEVE_OBJECT("length", &modifier_operand, EXT_VARIABLES_MODIFIER_LENGTH), 10, mod_length_modify, }; /* Modifier implementations */ static bool mod_upperfirst_modify(const struct sieve_variables_modifier *modf ATTR_UNUSED, string_t *in, string_t **result) { char *content; if (str_len(in) == 0) { *result = in; return TRUE; } *result = t_str_new(str_len(in)); str_append_str(*result, in); content = str_c_modifiable(*result); content[0] = i_toupper(content[0]); return TRUE; } static bool mod_lowerfirst_modify(const struct sieve_variables_modifier *modf ATTR_UNUSED, string_t *in, string_t **result) { char *content; if (str_len(in) == 0) { *result = in; return TRUE; } *result = t_str_new(str_len(in)); str_append_str(*result, in); content = str_c_modifiable(*result); content[0] = i_tolower(content[0]); return TRUE; } static bool mod_upper_modify(const struct sieve_variables_modifier *modf ATTR_UNUSED, string_t *in, string_t **result) { char *content; if (str_len(in) == 0) { *result = in; return TRUE; } *result = t_str_new(str_len(in)); str_append_str(*result, in); content = str_c_modifiable(*result); (void)str_ucase(content); return TRUE; } static bool mod_lower_modify(const struct sieve_variables_modifier *modf ATTR_UNUSED, string_t *in, string_t **result) { char *content; if (str_len(in) == 0) { *result = in; return TRUE; } *result = t_str_new(str_len(in)); str_append_str(*result, in); content = str_c_modifiable(*result); (void)str_lcase(content); return TRUE; } static bool mod_length_modify(const struct sieve_variables_modifier *modf ATTR_UNUSED, string_t *in, string_t **result) { *result = t_str_new(64); str_printfa(*result, "%llu", (unsigned long long) uni_utf8_strlen_n(str_data(in), str_len(in))); return TRUE; } static bool mod_quotewildcard_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result) { size_t max_val_size = sieve_variables_get_max_value_size(modf->var_ext); const unsigned char *p, *poff, *pend; size_t new_size; if (str_len(in) == 0) { /* Empty string */ *result = in; return TRUE; } /* Allocate new string */ new_size = str_len(in) + 16; if (new_size > max_val_size) new_size = max_val_size; *result = t_str_new(new_size + 1); /* Escape string */ p = str_data(in); pend = p + str_len(in); poff = p; while (p < pend) { unsigned int n = uni_utf8_char_bytes((char)*p); if (n == 1 && (*p == '*' || *p == '?' || *p == '\\')) { str_append_data(*result, poff, p - poff); poff = p; if (str_len(*result) + 2 > max_val_size) break; str_append_c(*result, '\\'); } else if ((str_len(*result) + (p - poff) + n) > max_val_size) { break; } if (p + n > pend) { p = pend; break; } p += n; } str_append_data(*result, poff, p - poff); return TRUE; } /* * Modifier argument */ /* [MODIFIER]: * ":lower" / ":upper" / ":lowerfirst" / ":upperfirst" / * ":quotewildcard" / ":length" */ /* Forward declarations */ static bool tag_modifier_is_instance_of(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext, const char *identifier, void **context); /* Modifier tag object */ static const struct sieve_argument_def modifier_tag = { .identifier = "MODIFIER", .flags = SIEVE_ARGUMENT_FLAG_MULTIPLE, .is_instance_of = tag_modifier_is_instance_of, }; /* Modifier tag implementation */ static bool tag_modifier_is_instance_of(struct sieve_validator *valdtr, struct sieve_command *cmd, const struct sieve_extension *ext, const char *identifier, void **data) { const struct sieve_variables_modifier *modf; if (data == NULL) return ext_variables_modifier_exists(ext, valdtr, identifier); modf = ext_variables_modifier_create_instance(ext, valdtr, cmd, identifier); if (modf == NULL) return FALSE; *data = (void *)modf; return TRUE; } /* Registration */ void sieve_variables_modifiers_link_tag( struct sieve_validator *valdtr, const struct sieve_extension *var_ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, var_ext, &modifier_tag, 0); } /* Validation */ bool sieve_variables_modifiers_validate( struct sieve_validator *valdtr, struct sieve_command *cmd, ARRAY_TYPE(sieve_variables_modifier) *modifiers) { struct sieve_ast_argument *arg; arg = sieve_command_first_argument(cmd); while (arg != NULL && arg != cmd->first_positional) { const struct sieve_variables_modifier *modfs; const struct sieve_variables_modifier *modf; unsigned int i, modf_count; bool inserted; if (!sieve_argument_is(arg, modifier_tag)) { arg = sieve_ast_argument_next(arg); continue; } modf = (const struct sieve_variables_modifier *) arg->argument->data; inserted = FALSE; modfs = array_get(modifiers, &modf_count); for (i = 0; i < modf_count && !inserted; i++) { if (modfs[i].def->precedence == modf->def->precedence) { sieve_argument_validate_error( valdtr, arg, "modifiers :%s and :%s specified for the set command conflict " "having equal precedence", modfs[i].def->obj_def.identifier, modf->def->obj_def.identifier); return FALSE; } if (modfs[i].def->precedence < modf->def->precedence) { array_insert(modifiers, i, modf, 1); inserted = TRUE; } } if (!inserted) array_append(modifiers, modf, 1); /* Added to modifier list; self-destruct to prevent implicit code generation. */ arg = sieve_ast_arguments_detach(arg, 1); } return TRUE; } bool sieve_variables_modifiers_generate( const struct sieve_codegen_env *cgenv, ARRAY_TYPE(sieve_variables_modifier) *modifiers) { struct sieve_binary_block *sblock = cgenv->sblock; const struct sieve_variables_modifier *modfs; unsigned int i, modf_count; sieve_binary_emit_byte(sblock, array_count(modifiers)); modfs = array_get(modifiers, &modf_count); for (i = 0; i < modf_count; i++) { ext_variables_opr_modifier_emit( sblock, modfs[i].object.ext, modfs[i].def); } return TRUE; } /* * Modifier coding */ const struct sieve_operand_class sieve_variables_modifier_operand_class = { "modifier" }; static const struct sieve_extension_objects core_modifiers = SIEVE_VARIABLES_DEFINE_MODIFIERS(ext_variables_core_modifiers); const struct sieve_operand_def modifier_operand = { .name = "modifier", .ext_def = &variables_extension, .code = EXT_VARIABLES_OPERAND_MODIFIER, .class = &sieve_variables_modifier_operand_class, .interface = &core_modifiers, }; bool sieve_variables_modifiers_code_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int mdfs, i; /* Read the number of applied modifiers we need to read */ if (!sieve_binary_read_byte(denv->sblock, address, &mdfs)) return FALSE; /* Print all modifiers (sorted during code generation already) */ for (i = 0; i < mdfs; i++) { if (!ext_variables_opr_modifier_dump(denv, address)) return FALSE; } return TRUE; } int sieve_variables_modifiers_code_read( const struct sieve_runtime_env *renv, const struct sieve_extension *var_ext, sieve_size_t *address, ARRAY_TYPE(sieve_variables_modifier) *modifiers) { unsigned int lprec, mdfs, i; if (!sieve_binary_read_byte(renv->sblock, address, &mdfs)) { sieve_runtime_trace_error(renv, "invalid modifier count"); return SIEVE_EXEC_BIN_CORRUPT; } t_array_init(modifiers, mdfs); lprec = (unsigned int)-1; for (i = 0; i < mdfs; i++) { struct sieve_variables_modifier modf; if (!ext_variables_opr_modifier_read(renv, var_ext, address, &modf)) return SIEVE_EXEC_BIN_CORRUPT; if (modf.def != NULL) { if (modf.def->precedence >= lprec) { sieve_runtime_trace_error( renv, "unsorted modifier precedence"); return SIEVE_EXEC_BIN_CORRUPT; } lprec = modf.def->precedence; } array_append(modifiers, &modf, 1); } return SIEVE_EXEC_OK; } /* * Modifier application */ int sieve_variables_modifiers_apply( const struct sieve_runtime_env *renv, const struct sieve_extension *var_ext, ARRAY_TYPE(sieve_variables_modifier) *modifiers, string_t **value) { const struct ext_variables_context *extctx = ext_variables_get_context(var_ext); const struct sieve_variables_modifier *modfs; unsigned int i, modf_count; /* Hold value within limits */ if (str_len(*value) > extctx->set->max_value_size) { /* assume variable originates from code, so copy it first */ string_t *new_value = t_str_new(extctx->set->max_value_size+3); str_append_str(new_value, *value); *value = new_value; str_truncate_utf8(*value, extctx->set->max_value_size); } if (!array_is_created(modifiers)) return SIEVE_EXEC_OK; modfs = array_get(modifiers, &modf_count); if (modf_count == 0) return SIEVE_EXEC_OK; for (i = 0; i < modf_count; i++) { string_t *new_value; const struct sieve_variables_modifier *modf = &modfs[i]; if (modf->def != NULL && modf->def->modify != NULL) { if (!modf->def->modify(modf, *value, &new_value)) return SIEVE_EXEC_FAILURE; *value = new_value; if (*value == NULL) return SIEVE_EXEC_FAILURE; sieve_runtime_trace_here( renv, SIEVE_TRLVL_COMMANDS, "modify :%s \"%s\" => \"%s\"", sieve_variables_modifier_name(modf), str_sanitize(str_c(*value), 256), str_sanitize(str_c(new_value), 256)); /* Hold value within limits */ if (str_len(*value) > extctx->set->max_value_size) { str_truncate_utf8( *value, extctx->set->max_value_size); } } } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-limits.h0000644000175100001700000000221715100335616031316 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_LIMITS_H #define EXT_VARIABLES_LIMITS_H #include "sieve-limits.h" /* From RFC 5229: * * 6. Implementation Limits * * An implementation of this document MUST support at least 128 distinct * variables. The supported length of variable names MUST be at least * 32 characters. Each variable MUST be able to hold at least 4000 * characters. Attempts to set the variable to a value larger than what * the implementation supports SHOULD be reported as an error at * compile-time if possible. If the attempt is discovered during run- * time, the value SHOULD be truncated, and it MUST NOT be treated as an * error. * Match variables ${1} through ${9} MUST be supported. References to * higher indices than those the implementation supports MUST be treated * as a syntax error, which SHOULD be discovered at compile-time. */ #define EXT_VARIABLES_REQUIRED_MAX_SCOPE_COUNT 128 #define EXT_VARIABLES_REQUIRED_MAX_VALUE_SIZE 4000 #define EXT_VARIABLES_MAX_VARIABLE_NAME_LEN 64 #define EXT_VARIABLES_MAX_NAMESPACE_ELEMENTS 10 #define EXT_VARIABLES_MAX_MATCH_INDEX SIEVE_MAX_MATCH_VALUES #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-name.c0000644000175100001700000000427315100335616030734 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "array.h" #include "sieve-common.h" #include "ext-variables-common.h" #include "ext-variables-limits.h" #include "ext-variables-name.h" #include bool sieve_variable_identifier_is_valid(const char *identifier) { const char *p = identifier; size_t plen = strlen(identifier); const char *pend; if ( plen == 0 || plen >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN ) return FALSE; pend = PTR_OFFSET(identifier, plen); if ( *p == '_' || i_isalpha(*p) ) { p++; while ( p < pend && (*p == '_' || i_isalnum(*p)) ) { p++; } } return ( p == pend ); } int ext_variable_name_parse (ARRAY_TYPE(sieve_variable_name) *vname, const char **str, const char *strend) { const char *p = *str; array_clear(vname); while ( p < strend ) { struct sieve_variable_name *cur_element; string_t *cur_ident; /* Acquire current position in the array */ if ( array_count(vname) >= EXT_VARIABLES_MAX_NAMESPACE_ELEMENTS ) return -1; cur_element = array_append_space(vname); cur_ident = cur_element->identifier = t_str_new(32); /* Parse element */ /* Identifier */ if ( *p == '_' || i_isalpha(*p) ) { cur_element->num_variable = -1; str_truncate(cur_ident, 0); str_append_c(cur_ident, *p); p++; while ( p < strend && (*p == '_' || i_isalnum(*p)) ) { if ( str_len(cur_ident) >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN ) return -1; str_append_c(cur_ident, *p); p++; } /* Num-variable */ } else if ( i_isdigit(*p) ) { cur_element->num_variable = *p - '0'; p++; while ( p < strend && i_isdigit(*p) ) { cur_element->num_variable = cur_element->num_variable*10 + (*p - '0'); p++; } /* If a num-variable is first, no more elements can follow because no * namespace is specified. */ if ( array_count(vname) == 1 ) { *str = p; return 1; } } else { *str = p; return -1; } /* Check whether next name element is present */ if ( p < strend && *p == '.' ) { p++; /* It may not be empty */ if ( p >= strend ) return -1; } else break; } *str = p; return array_count(vname); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-settings.c0000644000175100001700000000362015100335616031647 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-variables-limits.h" #include "ext-variables-settings.h" static bool ext_variables_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_variables_"#name, name, \ struct ext_variables_settings) static const struct setting_define ext_variables_setting_defines[] = { DEF(UINT, max_scope_count), DEF(SIZE, max_value_size), SETTING_DEFINE_LIST_END, }; static const struct ext_variables_settings ext_variables_default_settings = { .max_scope_count = 255, .max_value_size = (4 * 1024), }; const struct setting_parser_info ext_variables_setting_parser_info = { .name = "sieve_variables", .defines = ext_variables_setting_defines, .defaults = &ext_variables_default_settings, .struct_size = sizeof(struct ext_variables_settings), .check_func = ext_variables_settings_check, .pool_offset1 = 1 + offsetof(struct ext_variables_settings, pool), }; /* */ static bool ext_variables_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct ext_variables_settings *set = _set; if (set->max_scope_count < EXT_VARIABLES_REQUIRED_MAX_SCOPE_COUNT) { *error_r = t_strdup_printf( "Setting sieve_variables_max_scope_count " "is lower than required by standards " "(>= %u items)", EXT_VARIABLES_REQUIRED_MAX_SCOPE_COUNT); return FALSE; } if (set->max_value_size < EXT_VARIABLES_REQUIRED_MAX_VALUE_SIZE) { *error_r = t_strdup_printf( "Setting sieve_variables_max_variable_size " "is lower than required by standards " "(>= %zu bytes)", (size_t)EXT_VARIABLES_REQUIRED_MAX_VALUE_SIZE); return FALSE; } return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/Makefile.in0000644000175100001700000006635415100335630027155 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/variables ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(pkginc_lib_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_variables_la_LIBADD = am__objects_1 = cmd-set.lo am__objects_2 = tst-string.lo am_libsieve_ext_variables_la_OBJECTS = ext-variables-settings.lo \ ext-variables-common.lo ext-variables-name.lo \ ext-variables-namespaces.lo ext-variables-arguments.lo \ ext-variables-operands.lo ext-variables-modifiers.lo \ ext-variables-dump.lo $(am__objects_1) $(am__objects_2) \ ext-variables.lo libsieve_ext_variables_la_OBJECTS = \ $(am_libsieve_ext_variables_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-set.Plo \ ./$(DEPDIR)/ext-variables-arguments.Plo \ ./$(DEPDIR)/ext-variables-common.Plo \ ./$(DEPDIR)/ext-variables-dump.Plo \ ./$(DEPDIR)/ext-variables-modifiers.Plo \ ./$(DEPDIR)/ext-variables-name.Plo \ ./$(DEPDIR)/ext-variables-namespaces.Plo \ ./$(DEPDIR)/ext-variables-operands.Plo \ ./$(DEPDIR)/ext-variables-settings.Plo \ ./$(DEPDIR)/ext-variables.Plo ./$(DEPDIR)/tst-string.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_variables_la_SOURCES) DIST_SOURCES = $(libsieve_ext_variables_la_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(noinst_HEADERS) $(pkginc_lib_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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_variables.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) cmds = \ cmd-set.c tsts = \ tst-string.c libsieve_ext_variables_la_SOURCES = \ ext-variables-settings.c \ ext-variables-common.c \ ext-variables-name.c \ ext-variables-namespaces.c \ ext-variables-arguments.c \ ext-variables-operands.c \ ext-variables-modifiers.c \ ext-variables-dump.c \ $(cmds) \ $(tsts) \ ext-variables.c public_headers = \ sieve-ext-variables.h headers = \ ext-variables-settings.h \ ext-variables-common.h \ ext-variables-limits.h \ ext-variables-name.h \ ext-variables-namespaces.h \ ext-variables-arguments.h \ ext-variables-operands.h \ ext-variables-modifiers.h \ ext-variables-dump.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/variables/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/variables/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_variables.la: $(libsieve_ext_variables_la_OBJECTS) $(libsieve_ext_variables_la_DEPENDENCIES) $(EXTRA_libsieve_ext_variables_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_variables_la_OBJECTS) $(libsieve_ext_variables_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-set.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-arguments.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-dump.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-modifiers.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-name.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-namespaces.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-operands.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-string.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-set.Plo -rm -f ./$(DEPDIR)/ext-variables-arguments.Plo -rm -f ./$(DEPDIR)/ext-variables-common.Plo -rm -f ./$(DEPDIR)/ext-variables-dump.Plo -rm -f ./$(DEPDIR)/ext-variables-modifiers.Plo -rm -f ./$(DEPDIR)/ext-variables-name.Plo -rm -f ./$(DEPDIR)/ext-variables-namespaces.Plo -rm -f ./$(DEPDIR)/ext-variables-operands.Plo -rm -f ./$(DEPDIR)/ext-variables-settings.Plo -rm -f ./$(DEPDIR)/ext-variables.Plo -rm -f ./$(DEPDIR)/tst-string.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-set.Plo -rm -f ./$(DEPDIR)/ext-variables-arguments.Plo -rm -f ./$(DEPDIR)/ext-variables-common.Plo -rm -f ./$(DEPDIR)/ext-variables-dump.Plo -rm -f ./$(DEPDIR)/ext-variables-modifiers.Plo -rm -f ./$(DEPDIR)/ext-variables-name.Plo -rm -f ./$(DEPDIR)/ext-variables-namespaces.Plo -rm -f ./$(DEPDIR)/ext-variables-operands.Plo -rm -f ./$(DEPDIR)/ext-variables-settings.Plo -rm -f ./$(DEPDIR)/ext-variables.Plo -rm -f ./$(DEPDIR)/tst-string.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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-pkginc_libHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables.c0000644000175100001700000000364015100335616030013 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension variables * ------------------- * * Authors: Stephan Bosch * Specification: RFC 5229 * Implementation: full * Status: testing * */ #include "lib.h" #include "str.h" #include "unichar.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-validator.h" #include "ext-variables-common.h" #include "ext-variables-arguments.h" #include "ext-variables-operands.h" #include "ext-variables-namespaces.h" #include "ext-variables-modifiers.h" #include "ext-variables-dump.h" /* * Operations */ const struct sieve_operation_def *ext_variables_operations[] = { &cmd_set_operation, &tst_string_operation }; /* * Operands */ const struct sieve_operand_def *ext_variables_operands[] = { &variable_operand, &match_value_operand, &namespace_variable_operand, &modifier_operand }; /* * Extension */ static bool ext_variables_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def variables_extension = { .name = "variables", .load = ext_variables_load, .unload = ext_variables_unload, .validator_load = ext_variables_validator_load, .generator_load = ext_variables_generator_load, .interpreter_load = ext_variables_interpreter_load, .code_dump = ext_variables_code_dump, SIEVE_EXT_DEFINE_OPERATIONS(ext_variables_operations), SIEVE_EXT_DEFINE_OPERANDS(ext_variables_operands) }; static bool ext_variables_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator) { sieve_validator_argument_override (validator, SAT_VAR_STRING, ext, &variable_string_argument); sieve_validator_register_command(validator, ext, &cmd_set); sieve_validator_register_command(validator, ext, &tst_string); ext_variables_validator_initialize(ext, validator); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/sieve-ext-variables.h0000644000175100001700000002611115100335616031127 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXT_VARIABLES_H #define SIEVE_EXT_VARIABLES_H #include "lib.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-objects.h" #include "sieve-code.h" /* Public interface for other extensions to use */ /* * Limits */ unsigned int sieve_variables_get_max_scope_count(const struct sieve_extension *var_ext); size_t sieve_variables_get_max_value_size( const struct sieve_extension *var_ext); /* * Variable extension */ /* FIXME: this is not suitable for future plugin support */ extern const struct sieve_extension_def variables_extension; static inline int sieve_ext_variables_get_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_register(svinst, &variables_extension, FALSE, ext_r); } /* * Variable name */ struct sieve_variable_name { string_t *identifier; int num_variable; }; ARRAY_DEFINE_TYPE(sieve_variable_name, struct sieve_variable_name); bool sieve_variable_identifier_is_valid(const char *identifier); /* * Variable scope */ struct sieve_variable { const char *identifier; unsigned int index; const struct sieve_extension *ext; void *context; }; struct sieve_variable_scope; struct sieve_variable_scope * sieve_variable_scope_create(struct sieve_instance *svinst, const struct sieve_extension *var_ext, const struct sieve_extension *ext); void sieve_variable_scope_ref(struct sieve_variable_scope *scope); void sieve_variable_scope_unref(struct sieve_variable_scope **scope); pool_t sieve_variable_scope_pool(struct sieve_variable_scope *scope); struct sieve_variable * sieve_variable_scope_declare(struct sieve_variable_scope *scope, const char *identifier); struct sieve_variable * sieve_variable_scope_import(struct sieve_variable_scope *scope, struct sieve_variable *var); struct sieve_variable * sieve_variable_scope_get_variable(struct sieve_variable_scope *scope, const char *identifier); struct sieve_variable * sieve_variable_scope_get_indexed(struct sieve_variable_scope *scope, unsigned int index); /* Binary */ struct sieve_variable_scope_binary * sieve_variable_scope_binary_create(struct sieve_variable_scope *scope); void sieve_variable_scope_binary_ref( struct sieve_variable_scope_binary *scpbin); void sieve_variable_scope_binary_unref( struct sieve_variable_scope_binary **scpbin); struct sieve_variable_scope * sieve_variable_scope_binary_dump(struct sieve_instance *svinst, const struct sieve_extension *var_ext, const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address); struct sieve_variable_scope_binary * sieve_variable_scope_binary_read(struct sieve_instance *svinst, const struct sieve_extension *var_ext, const struct sieve_extension *ext, struct sieve_binary_block *sblock, sieve_size_t *address); struct sieve_variable_scope * sieve_variable_scope_binary_get(struct sieve_variable_scope_binary *scpbin); unsigned int sieve_variable_scope_binary_get_count( struct sieve_variable_scope_binary *scpbin); /* * Variable namespaces */ struct sieve_variables_namespace; struct sieve_variables_namespace_def { struct sieve_object_def obj_def; bool (*validate)(struct sieve_validator *valdtr, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, bool assignment); bool (*generate)(const struct sieve_codegen_env *cgenv, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd, void *var_data); bool (*dump_variable)(const struct sieve_dumptime_env *denv, const struct sieve_variables_namespace *nspc, const struct sieve_operand *oprnd, sieve_size_t *address); int (*read_variable)(const struct sieve_runtime_env *renv, const struct sieve_variables_namespace *nspc, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str); }; #define SIEVE_VARIABLES_DEFINE_NAMESPACE(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_VARIABLES_DEFINE_NAMESPACES(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) struct sieve_variables_namespace { struct sieve_object object; const struct sieve_variables_namespace_def *def; }; void sieve_variables_namespace_register( const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_variables_namespace_def *nspc_def); extern const struct sieve_operand_class sieve_variables_namespace_operand_class; void sieve_variables_opr_namespace_variable_emit( struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, const struct sieve_extension *ext, const struct sieve_variables_namespace_def *nspc_def); /* Iteration over all declared variables */ struct sieve_variable_scope_iter; struct sieve_variable_scope_iter * sieve_variable_scope_iterate_init(struct sieve_variable_scope *scope); bool sieve_variable_scope_iterate(struct sieve_variable_scope_iter *iter, struct sieve_variable **var_r); void sieve_variable_scope_iterate_deinit( struct sieve_variable_scope_iter **iter); /* Statistics */ unsigned int sieve_variable_scope_declarations(struct sieve_variable_scope *scope); unsigned int sieve_variable_scope_size(struct sieve_variable_scope *scope); /* Get all native variables */ struct sieve_variable *const * sieve_variable_scope_get_variables(struct sieve_variable_scope *scope, unsigned int *size_r); /* * Variable storage */ struct sieve_variable_storage; struct sieve_variable_storage * sieve_variable_storage_create(const struct sieve_extension *var_ext, pool_t pool, struct sieve_variable_scope_binary *scpbin); bool sieve_variable_get(struct sieve_variable_storage *storage, unsigned int index, string_t **value); bool sieve_variable_get_modifiable(struct sieve_variable_storage *storage, unsigned int index, string_t **value); bool sieve_variable_assign(struct sieve_variable_storage *storage, unsigned int index, const string_t *value); bool sieve_variable_assign_cstr(struct sieve_variable_storage *storage, unsigned int index, const char *value); bool sieve_variable_get_identifier(struct sieve_variable_storage *storage, unsigned int index, const char **identifier); const char *sieve_variable_get_varid(struct sieve_variable_storage *storage, unsigned int index); /* * Variables access */ bool sieve_ext_variables_is_active(const struct sieve_extension *var_ext, struct sieve_validator *valdtr); struct sieve_variable_scope * sieve_ext_variables_get_local_scope(const struct sieve_extension *var_ext, struct sieve_validator *valdtr); /* Runtime */ static inline const char * sieve_ext_variables_get_varid(const struct sieve_extension *ext, unsigned int index) { if (ext == NULL) return t_strdup_printf("%ld", (long)index); return t_strdup_printf("%s:%ld", sieve_extension_name(ext), (long)index); } struct sieve_variable_storage * sieve_ext_variables_runtime_get_storage(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv, const struct sieve_extension *ext); void sieve_ext_variables_runtime_set_storage( const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv, const struct sieve_extension *ext, struct sieve_variable_storage *storage); const char * sieve_ext_variables_runtime_get_identifier( const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv, const struct sieve_extension *ext, unsigned int index); /* * Variable arguments */ bool sieve_variable_argument_activate(const struct sieve_extension *var_ext, const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool assignment); /* * Variable operands */ extern const struct sieve_operand_def variable_operand; void sieve_variables_opr_variable_emit(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, struct sieve_variable *var); void sieve_variables_opr_match_value_emit(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, unsigned int index); int sieve_variable_operand_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, struct sieve_variable_storage **storage_r, unsigned int *var_index_r); int sieve_variable_operand_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_variable_storage **storage_r, unsigned int *var_index_r); static inline bool sieve_operand_is_variable(const struct sieve_operand *operand) { return (operand != NULL && operand->def != NULL && operand->def == &variable_operand); } /* * Modifiers */ /* Definition */ struct sieve_variables_modifier; struct sieve_variables_modifier_def { struct sieve_object_def obj_def; unsigned int precedence; bool (*modify)(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); }; struct sieve_variables_modifier { struct sieve_object object; const struct sieve_extension *var_ext; const struct sieve_variables_modifier_def *def; }; #define SIEVE_VARIABLES_DEFINE_MODIFIER(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_VARIABLES_DEFINE_MODIFIERS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) #define sieve_variables_modifier_name(smodf) \ ((smodf)->object.def->identifier) ARRAY_DEFINE_TYPE(sieve_variables_modifier, struct sieve_variables_modifier); /* Registry */ void sieve_variables_modifier_register( const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_variables_modifier_def *smodf); /* Tagged argument */ void sieve_variables_modifiers_link_tag( struct sieve_validator *valdtr, const struct sieve_extension *var_ext, struct sieve_command_registration *cmd_reg); bool sieve_variables_modifiers_validate( struct sieve_validator *valdtr, struct sieve_command *cmd, ARRAY_TYPE(sieve_variables_modifier) *modifiers); bool sieve_variables_modifiers_generate( const struct sieve_codegen_env *cgenv, ARRAY_TYPE(sieve_variables_modifier) *modifiers); /* Coding */ extern const struct sieve_operand_class sieve_variables_modifier_operand_class; bool sieve_variables_modifiers_code_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); int sieve_variables_modifiers_code_read( const struct sieve_runtime_env *renv, const struct sieve_extension *var_ext, sieve_size_t *address, ARRAY_TYPE(sieve_variables_modifier) *modifiers); /* Application */ int sieve_variables_modifiers_apply( const struct sieve_runtime_env *renv, const struct sieve_extension *var_ext, ARRAY_TYPE(sieve_variables_modifier) *modifiers, string_t **value); /* * Code dumping */ void sieve_ext_variables_dump_set_scope(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, struct sieve_variable_scope *scope); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-namespaces.c0000644000175100001700000001574115100335616032135 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-dump.h" #include "ext-variables-common.h" #include "ext-variables-namespaces.h" #include /* * Namespace registry */ void sieve_variables_namespace_register( const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const struct sieve_extension *ext, const struct sieve_variables_namespace_def *nspc_def) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); sieve_validator_object_registry_add(ctx->namespaces, ext, &nspc_def->obj_def); } bool ext_variables_namespace_exists(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const char *identifier) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); return sieve_validator_object_registry_find(ctx->namespaces, identifier, NULL); } const struct sieve_variables_namespace * ext_variables_namespace_create_instance(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier) { struct ext_variables_validator_context *ctx = ext_variables_validator_context_get(var_ext, valdtr); struct sieve_object object; struct sieve_variables_namespace *nspc; pool_t pool; if (!sieve_validator_object_registry_find(ctx->namespaces, identifier, &object)) return NULL; pool = sieve_command_pool(cmd); nspc = p_new(pool, struct sieve_variables_namespace, 1); nspc->object = object; nspc->def = (const struct sieve_variables_namespace_def *) object.def; return nspc; } /* * Namespace variable argument */ struct arg_namespace_variable { const struct sieve_variables_namespace *namespace; void *data; }; static bool arg_namespace_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context ATTR_UNUSED); const struct sieve_argument_def namespace_argument = { .identifier = "@namespace", .generate = arg_namespace_generate, }; bool ext_variables_namespace_argument_activate( const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name, bool assignment) { pool_t pool = sieve_command_pool(cmd); struct sieve_ast *ast = arg->ast; const struct sieve_variables_namespace *nspc; struct arg_namespace_variable *var; const struct sieve_variable_name *name_element = array_idx(var_name, 0); void *var_data = NULL; nspc = ext_variables_namespace_create_instance( this_ext, valdtr, cmd, str_c(name_element->identifier)); if (nspc == NULL) { sieve_argument_validate_error( valdtr, arg, "referring to variable in unknown namespace '%s'", str_c(name_element->identifier)); return FALSE; } if (nspc->def != NULL && nspc->def->validate != NULL && !nspc->def->validate(valdtr, nspc, arg, cmd, var_name, &var_data, assignment)) return FALSE; var = p_new(pool, struct arg_namespace_variable, 1); var->namespace = nspc; var->data = var_data; arg->argument = sieve_argument_create(ast, &namespace_argument, this_ext, 0); arg->argument->data = var; return TRUE; } struct sieve_ast_argument * ext_variables_namespace_argument_create( const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *parent_arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name) { struct sieve_ast *ast = parent_arg->ast; struct sieve_ast_argument *new_arg; new_arg = sieve_ast_argument_create( ast, sieve_ast_argument_line(parent_arg)); new_arg->type = SAAT_STRING; if (!ext_variables_namespace_argument_activate( this_ext, valdtr, new_arg, cmd, var_name, FALSE)) return NULL; return new_arg; } static bool arg_namespace_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { struct sieve_argument *argument = arg->argument; struct arg_namespace_variable *var = (struct arg_namespace_variable *)argument->data; const struct sieve_variables_namespace *nspc = var->namespace; if (nspc->def != NULL && nspc->def->generate != NULL) return nspc->def->generate(cgenv, nspc, arg, cmd, var->data); return TRUE; } /* * Namespace variable operands */ const struct sieve_operand_class sieve_variables_namespace_operand_class = { "variable-namespace" }; static bool opr_namespace_variable_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); static int opr_namespace_variable_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); static const struct sieve_opr_string_interface namespace_variable_interface = { opr_namespace_variable_dump, opr_namespace_variable_read, }; const struct sieve_operand_def namespace_variable_operand = { .name = "namespace", .ext_def = &variables_extension, .code = EXT_VARIABLES_OPERAND_NAMESPACE_VARIABLE, .class = &string_class, .interface = &namespace_variable_interface, }; void sieve_variables_opr_namespace_variable_emit( struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, const struct sieve_extension *ext, const struct sieve_variables_namespace_def *nspc_def) { i_assert(sieve_extension_is(var_ext, variables_extension)); sieve_operand_emit(sblock, var_ext, &namespace_variable_operand); sieve_opr_object_emit(sblock, ext, &nspc_def->obj_def); } static bool opr_namespace_variable_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { struct sieve_variables_namespace nspc; struct sieve_operand nsoprnd; if (!sieve_operand_read(denv->sblock, address, NULL, &nsoprnd)) return FALSE; if (!sieve_opr_object_read_data( denv->sblock, &nsoprnd, &sieve_variables_namespace_operand_class, address, &nspc.object)) return FALSE; nspc.def = (const struct sieve_variables_namespace_def *) nspc.object.def; if (nspc.def == NULL || nspc.def->dump_variable == NULL) return FALSE; return nspc.def->dump_variable(denv, &nspc, oprnd, address); } static int opr_namespace_variable_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r) { struct sieve_variables_namespace nspc; if (!sieve_opr_object_read( renv, &sieve_variables_namespace_operand_class, address, &nspc.object)) { sieve_runtime_trace_operand_error(renv, oprnd, "variable namespace operand corrupt: failed to read"); return SIEVE_EXEC_BIN_CORRUPT; } nspc.def = (const struct sieve_variables_namespace_def *) nspc.object.def; if (nspc.def == NULL || nspc.def->read_variable == NULL) return SIEVE_EXEC_FAILURE; return nspc.def->read_variable(renv, &nspc, oprnd, address, str_r); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-arguments.c0000644000175100001700000002700315100335616032015 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "array.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-dump.h" #include "ext-variables-common.h" #include "ext-variables-limits.h" #include "ext-variables-name.h" #include "ext-variables-operands.h" #include "ext-variables-namespaces.h" #include "ext-variables-arguments.h" /* * Variable argument implementation */ static bool arg_variable_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); const struct sieve_argument_def variable_argument = { .identifier = "@variable", .generate = arg_variable_generate, }; static bool ext_variables_variable_argument_activate(const struct sieve_extension *var_ext, const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *arg, const char *variable) { struct sieve_ast *ast = arg->ast; struct sieve_variable *var; var = ext_variables_validator_declare_variable( this_ext, valdtr, variable); if (var == NULL) { sieve_argument_validate_error( valdtr, arg, "(implicit) declaration of new variable '%s' exceeds the limit " "(max variables: %u)", variable, sieve_variables_get_max_scope_count(var_ext)); return FALSE; } arg->argument = sieve_argument_create(ast, &variable_argument, this_ext, 0); arg->argument->data = var; return TRUE; } static struct sieve_ast_argument * ext_variables_variable_argument_create(const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *parent_arg, const char *variable) { struct sieve_ast *ast = parent_arg->ast; struct sieve_ast_argument *new_arg; new_arg = sieve_ast_argument_create( ast, sieve_ast_argument_line(parent_arg)); new_arg->type = SAAT_STRING; if (!ext_variables_variable_argument_activate( this_ext, this_ext, valdtr, new_arg, variable)) return NULL; return new_arg; } static bool arg_variable_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context ATTR_UNUSED) { struct sieve_argument *argument = arg->argument; struct sieve_variable *var = (struct sieve_variable *) argument->data; sieve_variables_opr_variable_emit(cgenv->sblock, argument->ext, var); return TRUE; } /* * Match value argument implementation */ static bool arg_match_value_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context ATTR_UNUSED); const struct sieve_argument_def match_value_argument = { .identifier = "@match_value", .generate = arg_match_value_generate, }; static bool ext_variables_match_value_argument_activate( const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *arg, unsigned int index, bool assignment) { struct sieve_ast *ast = arg->ast; if (assignment) { sieve_argument_validate_error( valdtr, arg, "cannot assign to match variable"); return FALSE; } if (index > EXT_VARIABLES_MAX_MATCH_INDEX) { sieve_argument_validate_error( valdtr, arg, "match value index %u out of range " "(max: %u)", index, EXT_VARIABLES_MAX_MATCH_INDEX); return FALSE; } arg->argument = sieve_argument_create(ast, &match_value_argument, this_ext, 0); arg->argument->data = POINTER_CAST(index); return TRUE; } static struct sieve_ast_argument * ext_variables_match_value_argument_create( const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *parent_arg, unsigned int index) { struct sieve_ast *ast = parent_arg->ast; struct sieve_ast_argument *new_arg; new_arg = sieve_ast_argument_create( ast, sieve_ast_argument_line(parent_arg)); new_arg->type = SAAT_STRING; if (!ext_variables_match_value_argument_activate( this_ext, valdtr, new_arg, index, FALSE)) return NULL; return new_arg; } static bool arg_match_value_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context ATTR_UNUSED) { struct sieve_argument *argument = arg->argument; unsigned int index = POINTER_CAST_TO(argument->data, unsigned int); sieve_variables_opr_match_value_emit(cgenv->sblock, argument->ext, index); return TRUE; } /* * Variable string argument implementation */ static bool arg_variable_string_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); const struct sieve_argument_def variable_string_argument = { .identifier = "@variable-string", .validate = arg_variable_string_validate, .generate = sieve_arg_catenated_string_generate, }; static bool arg_variable_string_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { const struct sieve_extension *this_ext = (*arg)->argument->ext; enum { ST_NONE, ST_OPEN, ST_VARIABLE, ST_CLOSE } state = ST_NONE; pool_t pool = sieve_ast_pool((*arg)->ast); struct sieve_arg_catenated_string *catstr = NULL; string_t *str = sieve_ast_argument_str(*arg); const char *p, *strstart, *substart = NULL; const char *strval = (const char *) str_data(str); const char *strend = strval + str_len(str); bool result = TRUE; ARRAY_TYPE(sieve_variable_name) substitution; int nelements = 0; T_BEGIN { /* Initialize substitution structure */ t_array_init(&substitution, 2); p = strval; strstart = p; while (result && p < strend) { switch (state) { /* Nothing found yet */ case ST_NONE: if (*p == '$') { substart = p; state = ST_OPEN; } p++; break; /* Got '$' */ case ST_OPEN: if (*p == '{') { state = ST_VARIABLE; p++; } else state = ST_NONE; break; /* Got '${' */ case ST_VARIABLE: nelements = ext_variable_name_parse( &substitution, &p, strend); if (nelements < 0) state = ST_NONE; else state = ST_CLOSE; break; /* Finished parsing name, expecting '}' */ case ST_CLOSE: if (*p == '}') { struct sieve_ast_argument *strarg; /* We now know that the substitution is valid */ if (catstr == NULL) catstr = sieve_arg_catenated_string_create(*arg); /* Add the substring that is before the substitution to the variable-string AST. FIXME: For efficiency, if the variable is not found we should coalesce this substring with the one after the substitution. */ if (substart > strstart) { string_t *newstr = str_new(pool, substart - strstart); str_append_data(newstr, strstart, substart - strstart); strarg = sieve_ast_argument_string_create_raw( (*arg)->ast, newstr, (*arg)->source_line); sieve_arg_catenated_string_add_element(catstr, strarg); /* Give other substitution extensions a chance to do their work. */ if (!sieve_validator_argument_activate_super( valdtr, cmd, strarg, FALSE)) { result = FALSE; break; } } /* Find the variable */ if (nelements == 1) { const struct sieve_variable_name *cur_element = array_idx(&substitution, 0); if (cur_element->num_variable == -1) { /* Add variable argument '${identifier}' */ strarg = ext_variables_variable_argument_create( this_ext, valdtr, *arg, str_c(cur_element->identifier)); } else { /* Add match value argument '${000}' */ strarg = ext_variables_match_value_argument_create( this_ext, valdtr, *arg, cur_element->num_variable); } } else { strarg = ext_variables_namespace_argument_create( this_ext, valdtr, *arg, cmd, &substitution); } if (strarg != NULL) sieve_arg_catenated_string_add_element(catstr, strarg); strstart = p + 1; substart = strstart; p++; } /* Finished, reset for the next substitution */ state = ST_NONE; } } } T_END; /* Bail out early if substitution is invalid */ if (!result) return FALSE; /* Check whether any substitutions were found */ if (catstr == NULL) { /* No substitutions in this string, pass it on to any other substution extension. */ return sieve_validator_argument_activate_super( valdtr, cmd, *arg, TRUE); } /* Add the final substring that comes after the last substitution to the variable-string AST. */ if (strend > strstart) { struct sieve_ast_argument *strarg; string_t *newstr = str_new(pool, strend - strstart); str_append_data(newstr, strstart, strend - strstart); strarg = sieve_ast_argument_string_create_raw( (*arg)->ast, newstr, (*arg)->source_line); sieve_arg_catenated_string_add_element(catstr, strarg); /* Give other substitution extensions a chance to do their work. */ if (!sieve_validator_argument_activate_super( valdtr, cmd, strarg, FALSE)) return FALSE; } return TRUE; } /* * Variable argument interface */ static bool _sieve_variable_argument_activate(const struct sieve_extension *var_ext, const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool assignment) { bool result = FALSE; string_t *variable; const char *varstr, *varend; ARRAY_TYPE(sieve_variable_name) vname; int nelements = 0; T_BEGIN { t_array_init(&vname, 2); variable = sieve_ast_argument_str(arg); varstr = str_c(variable); varend = PTR_OFFSET(varstr, str_len(variable)); nelements = ext_variable_name_parse(&vname, &varstr, varend); /* Check whether name parsing succeeded */ if (nelements <= 0 || varstr != varend) { /* Parse failed */ sieve_argument_validate_error( valdtr, arg, "invalid variable name '%s'", str_sanitize(str_c(variable),80)); } else if (nelements == 1) { /* Normal (match) variable */ const struct sieve_variable_name *cur_element = array_idx(&vname, 0); if (cur_element->num_variable < 0) { /* Variable */ result = ext_variables_variable_argument_activate( var_ext, this_ext, valdtr, arg, str_c(cur_element->identifier)); } else { /* Match value */ result = ext_variables_match_value_argument_activate( this_ext, valdtr, arg, cur_element->num_variable, assignment); } } else { /* Namespace variable */ result = ext_variables_namespace_argument_activate( this_ext, valdtr, arg, cmd, &vname, assignment); } } T_END; return result; } bool sieve_variable_argument_activate(const struct sieve_extension *var_ext, const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool assignment) { if (sieve_ast_argument_type(arg) == SAAT_STRING) { /* Single string */ return _sieve_variable_argument_activate( var_ext, this_ext, valdtr, cmd, arg, assignment); } else if (sieve_ast_argument_type(arg) == SAAT_STRING_LIST) { /* String list */ struct sieve_ast_argument *stritem; i_assert (!assignment); stritem = sieve_ast_strlist_first(arg); while (stritem != NULL) { if (!_sieve_variable_argument_activate( var_ext, this_ext, valdtr, cmd, stritem, assignment)) return FALSE; stritem = sieve_ast_strlist_next(stritem); } arg->argument = sieve_argument_create( arg->ast, &string_list_argument, NULL, 0); return TRUE; } return FALSE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-common.h0000644000175100001700000000445615100335616031314 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_COMMON_H #define EXT_VARIABLES_COMMON_H #include "sieve-common.h" #include "sieve-validator.h" #include "sieve-ext-variables.h" #include "ext-variables-settings.h" /* * Extension */ struct ext_variables_context { const struct ext_variables_settings *set; }; extern const struct sieve_extension_def variables_extension; int ext_variables_load(const struct sieve_extension *ext, void **context_r); void ext_variables_unload(const struct sieve_extension *ext); const struct ext_variables_context * ext_variables_get_context(const struct sieve_extension *var_ext); /* * Commands */ extern const struct sieve_command_def cmd_set; extern const struct sieve_command_def tst_string; /* * Operands */ enum ext_variables_operand { EXT_VARIABLES_OPERAND_VARIABLE, EXT_VARIABLES_OPERAND_MATCH_VALUE, EXT_VARIABLES_OPERAND_NAMESPACE_VARIABLE, EXT_VARIABLES_OPERAND_MODIFIER }; /* * Operations */ extern const struct sieve_operation_def cmd_set_operation; extern const struct sieve_operation_def tst_string_operation; enum ext_variables_opcode { EXT_VARIABLES_OPERATION_SET, EXT_VARIABLES_OPERATION_STRING }; /* * Validator context */ struct ext_variables_validator_context { bool active; struct sieve_validator_object_registry *modifiers; struct sieve_validator_object_registry *namespaces; struct sieve_variable_scope *local_scope; }; void ext_variables_validator_initialize(const struct sieve_extension *this_ext, struct sieve_validator *validator); struct ext_variables_validator_context * ext_variables_validator_context_get(const struct sieve_extension *this_ext, struct sieve_validator *valdtr); struct sieve_variable * ext_variables_validator_get_variable(const struct sieve_extension *this_ext, struct sieve_validator *validator, const char *variable); struct sieve_variable * ext_variables_validator_declare_variable(const struct sieve_extension *this_ext, struct sieve_validator *validator, const char *variable); /* * Code generation */ bool ext_variables_generator_load(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); /* * Interpreter context */ bool ext_variables_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-dump.h0000644000175100001700000000073115100335616030761 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_DUMP_H #define EXT_VARIABLES_DUMP_H #include "sieve-common.h" /* * Code dump context */ bool ext_variables_code_dump (const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address); /* * Variable identifier dump */ const char *ext_variables_dump_get_identifier (const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, unsigned int index); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-namespaces.h0000644000175100001700000000246015100335616032134 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_NAMESPACES_H #define EXT_VARIABLES_NAMESPACES_H #include "sieve-common.h" #include "ext-variables-common.h" #include "sieve-ext-variables.h" /* * Namespace registry */ bool ext_variables_namespace_exists(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const char *identifier); const struct sieve_variables_namespace * ext_variables_namespace_create_instance(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier); void ext_variables_register_core_namespaces( const struct sieve_extension *var_ext, struct ext_variables_validator_context *ctx); /* * Namespace argument */ struct sieve_ast_argument * ext_variables_namespace_argument_create( const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *parent_arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name); bool ext_variables_namespace_argument_activate( const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name, bool assignment); /* * Namespace operand */ extern const struct sieve_operand_def namespace_variable_operand; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/variables/ext-variables-modifiers.h0000644000175100001700000000361115100335616031775 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VARIABLES_MODIFIERS_H #define EXT_VARIABLES_MODIFIERS_H #include "sieve-common.h" #include "sieve-runtime-trace.h" #include "ext-variables-common.h" #define ext_variables_namespace_name(nspc) \ (nspc)->object->def->name #define ext_variables_namespaces_equal(nspc1, nspc2) \ ((nspc1)->def == (nspc2)->def)) /* * Modifier registry */ bool ext_variables_modifier_exists(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, const char *identifier); const struct sieve_variables_modifier * ext_variables_modifier_create_instance(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, struct sieve_command *cmd, const char *identifier); void ext_variables_register_core_modifiers( const struct sieve_extension *var_ext, struct ext_variables_validator_context *ctx); /* * Modifier operand */ extern const struct sieve_operand_def modifier_operand; static inline void ext_variables_opr_modifier_emit( struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_variables_modifier_def *modf_def) { sieve_opr_object_emit(sblock, ext, &modf_def->obj_def); } static inline bool ext_variables_opr_modifier_read(const struct sieve_runtime_env *renv, const struct sieve_extension *var_ext, sieve_size_t *address, struct sieve_variables_modifier *modf) { if (!sieve_opr_object_read( renv, &sieve_variables_modifier_operand_class, address, &modf->object)) { sieve_runtime_trace_error(renv, "invalid modifier operand"); return FALSE; } modf->def = (const struct sieve_variables_modifier_def *)modf->object.def; modf->var_ext = var_ext; return TRUE; } static inline bool ext_variables_opr_modifier_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { return sieve_opr_object_dump( denv, &sieve_variables_modifier_operand_class, address, NULL); } #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/Makefile.in0000644000175100001700000005451215100335630025176 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = 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 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 distdir-am 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)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in 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_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @BUILD_UNFINISHED_TRUE@UNFINISHED = SUBDIRS = \ vacation \ subaddress \ comparator-i-ascii-numeric \ relational \ regex \ imap4flags \ copy \ include \ body \ variables \ enotify \ environment \ mailbox \ date \ spamvirustest \ ihave \ editheader \ duplicate \ index \ metadata \ mime \ special-use \ extlists \ vnd.dovecot \ $(UNFINISHED) all: all-recursive .SUFFIXES: $(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) --foreign src/lib-sieve/plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 installdirs: installdirs-recursive installdirs-am: 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 clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am 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 mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/0000755000175100001700000000000015100335670024603 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c0000644000175100001700000000565015100335616030046 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "unichar.h" #include "str.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-ext-variables.h" #include "ext-enotify-common.h" /* * Encodeurl modifier */ static bool mod_encodeurl_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result); const struct sieve_variables_modifier_def encodeurl_modifier = { SIEVE_OBJECT("encodeurl", &encodeurl_operand, 0), 15, mod_encodeurl_modify }; /* * Modifier operand */ static const struct sieve_extension_objects ext_enotify_modifiers = SIEVE_VARIABLES_DEFINE_MODIFIER(encodeurl_modifier); const struct sieve_operand_def encodeurl_operand = { .name = "modifier", .ext_def = &enotify_extension, .class = &sieve_variables_modifier_operand_class, .interface = &ext_enotify_modifiers }; /* * Modifier implementation */ static const char _uri_reserved_lookup[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 00 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, // 20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, // 30 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 50 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 70 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 80 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 90 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // F0 }; static bool mod_encodeurl_modify(const struct sieve_variables_modifier *modf, string_t *in, string_t **result) { size_t max_val_size = sieve_variables_get_max_value_size(modf->var_ext); const unsigned char *p, *poff, *pend; size_t new_size; if ( str_len(in) == 0 ) { *result = in; return TRUE; } /* allocate new string */ new_size = str_len(in) + 32; if (new_size > max_val_size) new_size = max_val_size; *result = t_str_new(new_size + 1); /* escape string */ p = str_data(in); pend = p + str_len(in); poff = p; while (p < pend) { unsigned int i, n = uni_utf8_char_bytes(*p); if (n > 1 || (_uri_reserved_lookup[*p] & 0x01) != 0) { str_append_data(*result, poff, p - poff); poff = p; if (str_len(*result) + 3 * n > max_val_size) break; str_printfa(*result, "%%%02X", *p); for (i = 1; i < n && p < pend; i++) { p++; poff++; str_printfa(*result, "%%%02X", *p); } poff++; } else if ((str_len(*result) + (p - poff) + 1) > max_val_size) { break; } p++; } str_append_data(*result, poff, p - poff); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/ext-enotify-limits.h0000644000175100001700000000015215100335616030524 0ustar00buildbotbuildbot00000000000000#ifndef EXT_ENOTIFY_LIMITS_H #define EXT_ENOTIFY_LIMITS_H #define EXT_ENOTIFY_MAX_SCHEME_LEN 32 #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/0000755000175100001700000000000015100335670026070 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/uri-mailto.c0000644000175100001700000003755215100335616030332 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* FIXME: URI syntax conforms to something somewhere in between RFC 2368 and draft-duerst-mailto-bis-05.txt. Should fully migrate to new specification when it matures. This requires modifications to the address parser (no whitespace allowed within the address itself) and UTF-8 support will be required in the URL. */ #include "lib.h" #include "array.h" #include "str.h" #include "str-sanitize.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-address.h" #include "sieve-message.h" #include "uri-mailto.h" /* Parser object */ struct uri_mailto_parser { pool_t pool; const struct uri_mailto_log *log; struct uri_mailto *uri; const char **reserved_headers; const char **unique_headers; int max_recipients; int max_headers; }; /* Error handling */ #define uri_mailto_error(PARSER, ...) \ uri_mailto_log((PARSER), LOG_TYPE_ERROR, \ __FILE__, __LINE__, __VA_ARGS__) #define uri_mailto_warning(PARSER, ...) \ uri_mailto_log((PARSER), LOG_TYPE_WARNING, \ __FILE__, __LINE__, __VA_ARGS__) static inline void ATTR_FORMAT(5, 6) uri_mailto_log(struct uri_mailto_parser *parser, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { va_list args; if (parser->log == NULL || parser->log->logv == NULL) return; va_start(args, fmt); parser->log->logv(parser->log->context, log_type, csrc_filename, csrc_linenum, fmt, args); va_end(args); } /* * Error handling */ /* * Reserved and unique headers */ static inline bool uri_mailto_header_is_reserved(struct uri_mailto_parser *parser, const char *field_name) { const char **hdr = parser->reserved_headers; if (hdr == NULL) return FALSE; /* Check whether it is reserved */ while (*hdr != NULL) { if (strcasecmp(field_name, *hdr) == 0) return TRUE; hdr++; } return FALSE; } static inline bool uri_mailto_header_is_unique(struct uri_mailto_parser *parser, const char *field_name) { const char **hdr = parser->unique_headers; if (hdr == NULL) return FALSE; /* Check whether it is supposed to be unique */ while (*hdr != NULL) { if (strcasecmp(field_name, *hdr) == 0) return TRUE; hdr++; } return FALSE; } /* * Low-level URI parsing. * * FIXME: much of this implementation will be common to other URI schemes. This * should be merged into a common implementation. */ static const char _qchar_lookup[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 20 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 30 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 50 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, // 70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F0 }; static inline bool _is_qchar(char c) { return ((_qchar_lookup[(unsigned char)c] & 0x01) != 0); } static inline int _decode_hex_digit(unsigned char digit) { switch (digit) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return (int) digit - '0'; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': return (int) digit - 'a' + 0x0a; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': return (int) digit - 'A' + 0x0A; } return -1; } static bool _parse_hex_value(const char **in, char *out) { int value, digit; if ((digit = _decode_hex_digit((unsigned char)**in)) < 0) return FALSE; value = digit << 4; (*in)++; if ((digit = _decode_hex_digit((unsigned char)**in)) < 0) return FALSE; value |= digit; (*in)++; if (value == 0) return FALSE; *out = (char)value; return TRUE; } /* * URI recipient parsing */ static bool uri_mailto_add_valid_recipient(struct uri_mailto_parser *parser, string_t *recipient, bool cc) { struct uri_mailto *uri = parser->uri; struct uri_mailto_recipient *new_recipient; struct uri_mailto_recipient *rcpts; unsigned int count, i; const char *error; const struct smtp_address *address; /* Verify recipient */ if ((address = sieve_address_parse_str(recipient, &error)) == NULL) { uri_mailto_error(parser, "invalid recipient '%s': %s", str_sanitize(str_c(recipient), 80), error); return FALSE; } /* Add recipient to the uri */ if (uri != NULL) { /* Get current recipients */ rcpts = array_get_modifiable(&uri->recipients, &count); /* Enforce limits */ if (parser->max_recipients > 0 && (int)count >= parser->max_recipients) { if ((int)count == parser->max_recipients) { uri_mailto_warning( parser, "more than the maximum %u recipients specified; " "rest is discarded", parser->max_recipients); } return TRUE; } /* Check for duplicate first */ for (i = 0; i < count; i++) { if (smtp_address_equals(rcpts[i].address, address)) { /* Upgrade existing Cc: recipient to a To: recipient if possible */ rcpts[i].carbon_copy = (rcpts[i].carbon_copy && cc); uri_mailto_warning( parser, "ignored duplicate recipient '%s'", str_sanitize(str_c(recipient), 80)); return TRUE; } } /* Add */ new_recipient = array_append_space(&uri->recipients); new_recipient->carbon_copy = cc; new_recipient->full = p_strdup(parser->pool, str_c(recipient)); new_recipient->address = smtp_address_clone(parser->pool, address); } return TRUE; } static bool uri_mailto_parse_recipients(struct uri_mailto_parser *parser, const char **uri_p) { string_t *to = t_str_new(128); const char *p = *uri_p; if (*p == '\0' || *p == '?') return TRUE; while (*p != '\0' && *p != '?') { if (*p == '%') { /* % encoded character */ char ch; p++; /* Parse 2-digit hex value */ if (!_parse_hex_value(&p, &ch)) { uri_mailto_error(parser, "invalid %% encoding"); return FALSE; } /* Check for delimiter */ if (ch == ',') { /* Verify and add recipient */ if (!uri_mailto_add_valid_recipient( parser, to, FALSE)) return FALSE; /* Reset for next recipient */ str_truncate(to, 0); } else { /* Content character */ str_append_c(to, ch); } } else { if (*p == ':' || *p == ';' || *p == ',' || !_is_qchar(*p)) { uri_mailto_error( parser, "invalid character '%c' in 'to' part", *p); return FALSE; } /* Content character */ str_append_c(to, *p); p++; } } i_assert(*p == '\0' || *p == '?'); /* Verify and add recipient */ if (!uri_mailto_add_valid_recipient(parser, to, FALSE)) return FALSE; *uri_p = p; return TRUE; } static bool uri_mailto_parse_header_recipients(struct uri_mailto_parser *parser, string_t *rcpt_header, bool cc) { string_t *to = t_str_new(128); const char *p = (const char *)str_data(rcpt_header); const char *pend = p + str_len(rcpt_header); while (p < pend) { if (*p == ',') { /* Verify and add recipient */ if (!uri_mailto_add_valid_recipient(parser, to, cc)) return FALSE; /* Reset for next recipient */ str_truncate(to, 0); } else { /* Content character */ str_append_c(to, *p); } p++; } /* Verify and add recipient */ if (!uri_mailto_add_valid_recipient(parser, to, cc)) return FALSE; return TRUE; } /* URI header parsing */ static bool uri_mailto_header_is_duplicate(struct uri_mailto_parser *parser, const char *field_name) { struct uri_mailto *uri = parser->uri; if (uri == NULL) return FALSE; if (uri_mailto_header_is_unique(parser, field_name)) { const struct uri_mailto_header_field *hdrs; unsigned int count, i; hdrs = array_get(&uri->headers, &count); for (i = 0; i < count; i++) { if (strcasecmp(hdrs[i].name, field_name) == 0) return TRUE; } } return FALSE; } static bool uri_mailto_parse_headers(struct uri_mailto_parser *parser, const char **uri_p) { struct uri_mailto *uri = parser->uri; unsigned int header_count = 0; string_t *field = t_str_new(128); const char *p = *uri_p; while (*p != '\0') { enum { _HNAME_IGNORED, _HNAME_GENERIC, _HNAME_TO, _HNAME_CC, _HNAME_SUBJECT, _HNAME_BODY, } hname_type = _HNAME_GENERIC; struct uri_mailto_header_field *hdrf = NULL; const char *field_name; /* Parse field name */ while (*p != '\0' && *p != '=') { char ch = *p; p++; if (ch == '%') { /* Encoded, parse 2-digit hex value */ if (!_parse_hex_value(&p, &ch)) { uri_mailto_error(parser, "invalid %% encoding"); return FALSE; } } else if (ch != '=' && !_is_qchar(ch)) { uri_mailto_error( parser, "invalid character '%c' in header field name part", ch); return FALSE; } str_append_c(field, ch); } if (*p != '\0') p++; /* Verify field name */ if (!rfc2822_header_field_name_verify(str_c(field), str_len(field))) { uri_mailto_error(parser, "invalid header field name"); return FALSE; } if (parser->max_headers > -1 && (int)header_count >= parser->max_headers) { /* Refuse to accept more headers than allowed by policy */ if ((int)header_count == parser->max_headers) { uri_mailto_warning( parser, "more than the maximum %u headers specified; " "rest is discarded", parser->max_headers); } hname_type = _HNAME_IGNORED; } else { /* Add new header field to array and assign its name */ field_name = str_c(field); if (strcasecmp(field_name, "to") == 0) hname_type = _HNAME_TO; else if (strcasecmp(field_name, "cc") == 0) hname_type = _HNAME_CC; else if (strcasecmp(field_name, "subject") == 0) hname_type = _HNAME_SUBJECT; else if (strcasecmp(field_name, "body") == 0) hname_type = _HNAME_BODY; else if (!uri_mailto_header_is_reserved(parser, field_name)) { if (uri != NULL) { if (!uri_mailto_header_is_duplicate(parser, field_name)) { hdrf = array_append_space(&uri->headers); hdrf->name = p_strdup(parser->pool, field_name); } else { uri_mailto_warning( parser, "ignored duplicate for unique header field '%s'", str_sanitize(field_name, 32)); hname_type = _HNAME_IGNORED; } } else { hname_type = _HNAME_IGNORED; } } else { uri_mailto_warning( parser, "ignored reserved header field '%s'", str_sanitize(field_name, 32)); hname_type = _HNAME_IGNORED; } } header_count++; /* Reset for field body */ str_truncate(field, 0); /* Parse field body */ while (*p != '\0' && *p != '&') { char ch = *p; p++; if (ch == '%') { /* Encoded, parse 2-digit hex value */ if (!_parse_hex_value(&p, &ch)) { uri_mailto_error(parser, "invalid %% encoding"); return FALSE; } } else if (ch != '=' && !_is_qchar(ch)) { uri_mailto_error( parser, "invalid character '%c' in header field value part", ch); return FALSE; } str_append_c(field, ch); } if (*p != '\0') p++; /* Verify field body */ if (hname_type == _HNAME_BODY) { // FIXME: verify body ... } else { if (!rfc2822_header_field_body_verify( str_c(field), str_len(field), FALSE, FALSE)) { uri_mailto_error(parser, "invalid header field body"); return FALSE; } } /* Assign field body */ switch (hname_type) { case _HNAME_IGNORED: break; case _HNAME_TO: /* Gracefully allow duplicate To fields */ if (!uri_mailto_parse_header_recipients( parser, field, FALSE)) return FALSE; break; case _HNAME_CC: /* Gracefully allow duplicate Cc fields */ if (!uri_mailto_parse_header_recipients( parser, field, TRUE)) return FALSE; break; case _HNAME_SUBJECT: /* Ignore duplicate subject field */ if (uri != NULL) { if (uri->subject == NULL) { uri->subject = p_strdup(parser->pool, str_c(field)); } else { uri_mailto_warning( parser, "ignored duplicate subject field"); } } break; case _HNAME_BODY: /* Ignore duplicate body field */ if (uri != NULL) { if (uri->body == NULL) { uri->body = p_strdup( parser->pool, str_c(field)); } else { uri_mailto_warning( parser, "ignored duplicate body field"); } } break; case _HNAME_GENERIC: if (uri != NULL && hdrf != NULL) hdrf->body = p_strdup(parser->pool, str_c(field)); break; } /* Reset for next name */ str_truncate(field, 0); } /* Skip '&' */ if (*p != '\0') p++; *uri_p = p; return TRUE; } static bool uri_mailto_parse_uri(struct uri_mailto_parser *parser, const char *uri_body) { const char *p = uri_body; /* * mailtoURI = "mailto:" [ to ] [ hfields ] * to = [ addr-spec *("%2C" addr-spec ) ] * hfields = "?" hfield *( "&" hfield ) * hfield = hfname "=" hfvalue * hfname = *qchar * hfvalue = *qchar * addr-spec = local-part "@" domain * local-part = dot-atom / quoted-string * qchar = unreserved / pct-encoded / some-delims * some-delims = "!" / "$" / "'" / "(" / ")" / "*" * / "+" / "," / ";" / ":" / "@" * * to ~= *tqchar * tqchar ~= without ";" and ":" * * Scheme 'mailto:' already parsed, starting parse after colon */ /* First extract to-part by searching for '?' and decoding % items */ if (!uri_mailto_parse_recipients(parser, &p)) return FALSE; if (*p == '\0') return TRUE; i_assert(*p == '?'); p++; /* Extract hfield items */ while (*p != '\0') { /* Extract hfield item by searching for '&' and decoding '%' items */ if (!uri_mailto_parse_headers(parser, &p)) return FALSE; } return TRUE; } /* * Validation */ bool uri_mailto_validate(const char *uri_body, const char **reserved_headers, const char **unique_headers, int max_recipients, int max_headers, const struct uri_mailto_log *log) { struct uri_mailto_parser parser; i_zero(&parser); parser.log = log; parser.max_recipients = max_recipients; parser.max_headers = max_headers; parser.reserved_headers = reserved_headers; parser.unique_headers = unique_headers; /* If no errors are reported, we don't need to record any data */ if (log != NULL) { parser.pool = pool_datastack_create(); parser.uri = p_new(parser.pool, struct uri_mailto, 1); p_array_init(&parser.uri->recipients, parser.pool, max_recipients); p_array_init(&parser.uri->headers, parser.pool, max_headers); } if (!uri_mailto_parse_uri(&parser, uri_body)) return FALSE; if (log != NULL) { if (array_count(&parser.uri->recipients) == 0) { uri_mailto_warning( &parser, "notification URI specifies no recipients"); } } return TRUE; } /* * Parsing */ struct uri_mailto * uri_mailto_parse(const char *uri_body, pool_t pool, const char **reserved_headers, const char **unique_headers, int max_recipients, int max_headers, const struct uri_mailto_log *log) { struct uri_mailto_parser parser; parser.pool = pool; parser.log = log; parser.max_recipients = max_recipients; parser.max_headers = max_headers; parser.reserved_headers = reserved_headers; parser.unique_headers = unique_headers; parser.uri = p_new(pool, struct uri_mailto, 1); p_array_init(&parser.uri->recipients, pool, max_recipients); p_array_init(&parser.uri->headers, pool, max_headers); if (!uri_mailto_parse_uri(&parser, uri_body)) return NULL; if (log != NULL) { if (array_count(&parser.uri->recipients) == 0) { uri_mailto_warning( &parser, "notification URI specifies no recipients"); } } return parser.uri; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/Makefile.am0000644000175100001700000000050415100335616030123 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_enotify_mailto.la AM_CPPFLAGS = \ -I$(srcdir)/.. \ -I$(srcdir)/../../.. \ -I$(srcdir)/../../../util \ $(LIBDOVECOT_INCLUDE) libsieve_ext_enotify_mailto_la_SOURCES = \ uri-mailto.c \ ntfy-mailto-settings.c \ ntfy-mailto.c noinst_HEADERS = \ uri-mailto.h \ ntfy-mailto-settings.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/uri-mailto.h0000644000175100001700000000213215100335616030321 0ustar00buildbotbuildbot00000000000000#ifndef URI_MAILTO_H #define URI_MAILTO_H /* * Types */ struct uri_mailto_header_field { const char *name; const char *body; }; struct uri_mailto_recipient { const char *full; const struct smtp_address *address; bool carbon_copy; }; ARRAY_DEFINE_TYPE(recipients, struct uri_mailto_recipient); ARRAY_DEFINE_TYPE(headers, struct uri_mailto_header_field); struct uri_mailto_log { void *context; void (*logv)(void *context, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, va_list args) ATTR_FORMAT(5, 0); }; struct uri_mailto { ARRAY_TYPE(recipients) recipients; ARRAY_TYPE(headers) headers; const char *subject; const char *body; }; bool uri_mailto_validate (const char *uri_body, const char **reserved_headers, const char **unique_headers, int max_recipients, int max_headers, const struct uri_mailto_log *log); struct uri_mailto *uri_mailto_parse (const char *uri_body, pool_t pool, const char **reserved_headers, const char **unique_headers, int max_recipients, int max_headers, const struct uri_mailto_log *log); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto-settings.c0000644000175100001700000000266315100335616032344 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ntfy-mailto-settings.h" static bool ntfy_mailto_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_notify_mailto_"#name, name, \ struct ntfy_mailto_settings) static const struct setting_define ntfy_mailto_setting_defines[] = { DEF(STR, envelope_from), SETTING_DEFINE_LIST_END, }; static const struct ntfy_mailto_settings ntfy_mailto_default_settings = { .envelope_from = "", }; const struct setting_parser_info ntfy_mailto_setting_parser_info = { .name = "sieve_notify_mailto", .defines = ntfy_mailto_setting_defines, .defaults = &ntfy_mailto_default_settings, .struct_size = sizeof(struct ntfy_mailto_settings), .check_func = ntfy_mailto_settings_check, .pool_offset1 = 1 + offsetof(struct ntfy_mailto_settings, pool), }; /* */ static bool ntfy_mailto_settings_check(void *_set, pool_t pool, const char **error_r) { struct ntfy_mailto_settings *set = _set; if (!sieve_address_source_parse(pool, set->envelope_from, &set->parsed.envelope_from)) { *error_r = t_strdup_printf("sieve_notify_mailto_envelope_from: " "Invalid address source '%s'", set->envelope_from); return FALSE; } return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/Makefile.in0000644000175100001700000005462215100335630030142 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/enotify/mailto ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_enotify_mailto_la_LIBADD = am_libsieve_ext_enotify_mailto_la_OBJECTS = uri-mailto.lo \ ntfy-mailto-settings.lo ntfy-mailto.lo libsieve_ext_enotify_mailto_la_OBJECTS = \ $(am_libsieve_ext_enotify_mailto_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ntfy-mailto-settings.Plo \ ./$(DEPDIR)/ntfy-mailto.Plo ./$(DEPDIR)/uri-mailto.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_enotify_mailto_la_SOURCES) DIST_SOURCES = $(libsieve_ext_enotify_mailto_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_enotify_mailto.la AM_CPPFLAGS = \ -I$(srcdir)/.. \ -I$(srcdir)/../../.. \ -I$(srcdir)/../../../util \ $(LIBDOVECOT_INCLUDE) libsieve_ext_enotify_mailto_la_SOURCES = \ uri-mailto.c \ ntfy-mailto-settings.c \ ntfy-mailto.c noinst_HEADERS = \ uri-mailto.h \ ntfy-mailto-settings.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/enotify/mailto/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/enotify/mailto/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_enotify_mailto.la: $(libsieve_ext_enotify_mailto_la_OBJECTS) $(libsieve_ext_enotify_mailto_la_DEPENDENCIES) $(EXTRA_libsieve_ext_enotify_mailto_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_enotify_mailto_la_OBJECTS) $(libsieve_ext_enotify_mailto_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntfy-mailto-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntfy-mailto.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uri-mailto.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ntfy-mailto-settings.Plo -rm -f ./$(DEPDIR)/ntfy-mailto.Plo -rm -f ./$(DEPDIR)/uri-mailto.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ntfy-mailto-settings.Plo -rm -f ./$(DEPDIR)/ntfy-mailto.Plo -rm -f ./$(DEPDIR)/uri-mailto.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c0000644000175100001700000005061315100335616030504 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Notify method mailto * -------------------- * * Authors: Stephan Bosch * Specification: RFC 5436 * Implementation: full * Status: testing * */ /* FIXME: URI syntax conforms to something somewhere in between RFC 2368 and draft-duerst-mailto-bis-05.txt. Should fully migrate to new specification when it matures. This requires modifications to the address parser (no whitespace allowed within the address itself) and UTF-8 support will be required in the URL. */ #include "lib.h" #include "array.h" #include "str.h" #include "ioloop.h" #include "str-sanitize.h" #include "ostream.h" #include "settings.h" #include "message-date.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-address.h" #include "sieve-address-source.h" #include "sieve-message.h" #include "sieve-smtp.h" #include "sieve-ext-enotify.h" #include "rfc2822.h" #include "uri-mailto.h" #include "ntfy-mailto-settings.h" /* * Configuration */ #define NTFY_MAILTO_MAX_RECIPIENTS 8 #define NTFY_MAILTO_MAX_HEADERS 16 /* * Mailto notification method */ static int ntfy_mailto_load(const struct sieve_enotify_method *nmth, void **context_r); static void ntfy_mailto_unload(const struct sieve_enotify_method *nmth); static bool ntfy_mailto_compile_check_uri(const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body); static bool ntfy_mailto_compile_check_from(const struct sieve_enotify_env *nenv, string_t *from); static const char * ntfy_mailto_runtime_get_notify_capability(const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body, const char *capability); static bool ntfy_mailto_runtime_check_uri(const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body); static bool ntfy_mailto_runtime_check_operands(const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body, string_t *message, string_t *from, pool_t context_pool, void **method_context); static int ntfy_mailto_action_check_duplicates( const struct sieve_enotify_env *nenv, const struct sieve_enotify_action *nact, const struct sieve_enotify_action *nact_other); static void ntfy_mailto_action_print(const struct sieve_enotify_print_env *penv, const struct sieve_enotify_action *nact); static int ntfy_mailto_action_execute(const struct sieve_enotify_exec_env *nenv, const struct sieve_enotify_action *nact); const struct sieve_enotify_method_def mailto_notify = { "mailto", ntfy_mailto_load, ntfy_mailto_unload, ntfy_mailto_compile_check_uri, NULL, ntfy_mailto_compile_check_from, NULL, ntfy_mailto_runtime_check_uri, ntfy_mailto_runtime_get_notify_capability, ntfy_mailto_runtime_check_operands, NULL, ntfy_mailto_action_check_duplicates, ntfy_mailto_action_print, ntfy_mailto_action_execute, }; /* * Reserved and unique headers */ static const char *_reserved_headers[] = { "auto-submitted", "received", "message-id", "data", "bcc", "in-reply-to", "references", "resent-date", "resent-from", "resent-sender", "resent-to", "resent-cc", "resent-bcc", "resent-msg-id", "from", "sender", NULL }; static const char *_unique_headers[] = { "reply-to", NULL }; /* * Method context data */ struct ntfy_mailto_action_context { struct uri_mailto *uri; const struct smtp_address *from_address; }; /* * Method registration */ struct ntfy_mailto_context { const struct ntfy_mailto_settings *set; }; static int ntfy_mailto_load(const struct sieve_enotify_method *nmth, void **context_r) { struct sieve_instance *svinst = nmth->svinst; const struct ntfy_mailto_settings *set; struct ntfy_mailto_context *mtctx; const char *error; if (settings_get(svinst->event, &ntfy_mailto_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } mtctx = i_new(struct ntfy_mailto_context, 1); mtctx->set = set; *context_r = mtctx; return 0; } static void ntfy_mailto_unload(const struct sieve_enotify_method *nmth) { struct ntfy_mailto_context *mtctx = nmth->context; if (mtctx == NULL) return; settings_free(mtctx->set); i_free(mtctx); } /* * URI parsing */ struct ntfy_mailto_uri_env { const struct sieve_enotify_env *nenv; struct event *event; struct uri_mailto_log uri_log; }; static void ATTR_FORMAT(5, 0) ntfy_mailto_uri_logv(void *context, enum log_type log_type, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, va_list args) { struct ntfy_mailto_uri_env *nmuenv = context; const struct sieve_enotify_env *nenv = nmuenv->nenv; sieve_event_logv(nenv->svinst, nenv->ehandler, nmuenv->event, log_type, csrc_filename, csrc_linenum, nenv->location, 0, fmt, args); } static void ntfy_mailto_uri_env_init(struct ntfy_mailto_uri_env *nmuenv, const struct sieve_enotify_env *nenv) { i_zero(nmuenv); nmuenv->nenv = nenv; nmuenv->event = event_create(nenv->event); event_set_append_log_prefix(nmuenv->event, "mailto URI: "); nmuenv->uri_log.context = nmuenv; nmuenv->uri_log.logv = ntfy_mailto_uri_logv; } static void ntfy_mailto_uri_env_deinit(struct ntfy_mailto_uri_env *nmuenv) { event_unref(&nmuenv->event); } /* * Validation */ static bool ntfy_mailto_compile_check_uri(const struct sieve_enotify_env *nenv, const char *uri ATTR_UNUSED, const char *uri_body) { struct ntfy_mailto_uri_env nmuenv; bool result; ntfy_mailto_uri_env_init(&nmuenv, nenv); result = uri_mailto_validate( uri_body, _reserved_headers, _unique_headers, NTFY_MAILTO_MAX_RECIPIENTS, NTFY_MAILTO_MAX_HEADERS, &nmuenv.uri_log); ntfy_mailto_uri_env_deinit(&nmuenv); return result; } static bool ntfy_mailto_compile_check_from(const struct sieve_enotify_env *nenv, string_t *from) { const char *error; bool result = FALSE; T_BEGIN { result = sieve_address_validate_str(from, &error); if (!result) { sieve_enotify_error( nenv, "specified :from address '%s' is invalid for " "the mailto method: %s", str_sanitize(str_c(from), 128), error); } } T_END; return result; } /* * Runtime */ struct ntfy_mailto_runtime_env { const struct sieve_enotify_env *nenv; struct event *event; }; static const char * ntfy_mailto_runtime_get_notify_capability( const struct sieve_enotify_env *nenv ATTR_UNUSED, const char *uri ATTR_UNUSED, const char *uri_body, const char *capability) { if (!uri_mailto_validate(uri_body, _reserved_headers, _unique_headers, NTFY_MAILTO_MAX_RECIPIENTS, NTFY_MAILTO_MAX_HEADERS, NULL)) return NULL; if (strcasecmp(capability, "online") == 0) return "maybe"; return NULL; } static bool ntfy_mailto_runtime_check_uri(const struct sieve_enotify_env *nenv ATTR_UNUSED, const char *uri ATTR_UNUSED, const char *uri_body) { return uri_mailto_validate(uri_body, _reserved_headers, _unique_headers, NTFY_MAILTO_MAX_RECIPIENTS, NTFY_MAILTO_MAX_HEADERS, NULL); } static bool ntfy_mailto_runtime_check_operands(const struct sieve_enotify_env *nenv, const char *uri ATTR_UNUSED, const char *uri_body, string_t *message ATTR_UNUSED, string_t *from, pool_t context_pool, void **method_context) { struct ntfy_mailto_action_context *mtactx; struct uri_mailto *parsed_uri; const struct smtp_address *address; struct ntfy_mailto_uri_env nmuenv; const char *error; /* Need to create context before validation to have arrays present */ mtactx = p_new(context_pool, struct ntfy_mailto_action_context, 1); /* Validate :from */ if (from != NULL) { T_BEGIN { address = sieve_address_parse_str(from, &error); if (address == NULL) { sieve_enotify_error( nenv, "specified :from address '%s' is invalid for " "the mailto method: %s", str_sanitize(str_c(from), 128), error); } else { mtactx->from_address = smtp_address_clone(context_pool, address); } } T_END; if (address == NULL) return FALSE; } ntfy_mailto_uri_env_init(&nmuenv, nenv); parsed_uri = uri_mailto_parse(uri_body, context_pool, _reserved_headers, _unique_headers, NTFY_MAILTO_MAX_RECIPIENTS, NTFY_MAILTO_MAX_HEADERS, &nmuenv.uri_log); ntfy_mailto_uri_env_deinit(&nmuenv); if (parsed_uri == NULL) return FALSE; mtactx->uri = parsed_uri; *method_context = mtactx; return TRUE; } /* * Action duplicates */ static int ntfy_mailto_action_check_duplicates( const struct sieve_enotify_env *nenv ATTR_UNUSED, const struct sieve_enotify_action *nact, const struct sieve_enotify_action *nact_other) { struct ntfy_mailto_action_context *mtactx = nact->method_context; struct ntfy_mailto_action_context *mtactx_other = nact_other->method_context; const struct uri_mailto_recipient *new_rcpts, *old_rcpts; unsigned int new_count, old_count, i, j; unsigned int del_start = 0, del_len = 0; new_rcpts = array_get(&mtactx->uri->recipients, &new_count); old_rcpts = array_get(&mtactx_other->uri->recipients, &old_count); for (i = 0; i < new_count; i++) { for (j = 0; j < old_count; j++) { if (smtp_address_equals(new_rcpts[i].address, old_rcpts[j].address)) break; } if (j == old_count) { /* Not duplicate */ if (del_len > 0) { /* Perform pending deletion */ array_delete(&mtactx->uri->recipients, del_start, del_len); /* Make sure the loop integrity is maintained */ i -= del_len; new_rcpts = array_get(&mtactx->uri->recipients, &new_count); } del_len = 0; } else { /* Mark deletion */ if (del_len == 0) del_start = i; del_len++; } } /* Perform pending deletion */ if (del_len > 0) array_delete(&mtactx->uri->recipients, del_start, del_len); return (array_count(&mtactx->uri->recipients) > 0 ? 0 : 1); } /* * Action printing */ static void ntfy_mailto_action_print(const struct sieve_enotify_print_env *penv, const struct sieve_enotify_action *nact) { unsigned int count, i; const struct uri_mailto_recipient *recipients; const struct uri_mailto_header_field *headers; struct ntfy_mailto_action_context *mtactx = nact->method_context; /* Print main method parameters */ sieve_enotify_method_printf(penv, " => importance : %llu\n", (unsigned long long)nact->importance); if (nact->message != NULL) { sieve_enotify_method_printf( penv, " => subject : %s\n", nact->message); } else if (mtactx->uri->subject != NULL) { sieve_enotify_method_printf( penv, " => subject : %s\n", mtactx->uri->subject); } if (nact->from != NULL) { sieve_enotify_method_printf( penv, " => from : %s\n", nact->from); } /* Print mailto: recipients */ sieve_enotify_method_printf(penv, " => recipients :\n"); recipients = array_get(&mtactx->uri->recipients, &count); if (count == 0) { sieve_enotify_method_printf( penv, " NONE, action has no effect\n"); } else { for (i = 0; i < count; i++) { if (recipients[i].carbon_copy) { sieve_enotify_method_printf( penv, " + Cc: %s\n", recipients[i].full); } else { sieve_enotify_method_printf( penv, " + To: %s\n", recipients[i].full); } } } /* Print accepted headers for notification message */ headers = array_get(&mtactx->uri->headers, &count); if (count > 0) { sieve_enotify_method_printf(penv, " => headers :\n"); for (i = 0; i < count; i++) { sieve_enotify_method_printf( penv, " + %s: %s\n", headers[i].name, headers[i].body); } } /* Print body for notification message */ if (mtactx->uri->body != NULL) { sieve_enotify_method_printf( penv, " => body : \n--\n%s\n--\n", mtactx->uri->body); } /* Finish output with an empty line */ sieve_enotify_method_printf(penv, "\n"); } /* * Action execution */ static bool _contains_8bit(const char *msg) { const unsigned char *s = (const unsigned char *)msg; for (; *s != '\0'; s++) { if ((*s & 0x80) != 0) return TRUE; } return FALSE; } static int ntfy_mailto_send(const struct sieve_enotify_exec_env *nenv, const struct sieve_enotify_action *nact, const struct smtp_address *owner_email) { struct sieve_instance *svinst = nenv->svinst; const struct sieve_message_data *msgdata = nenv->msgdata; const struct sieve_script_env *senv = nenv->scriptenv; struct ntfy_mailto_action_context *mtactx = nact->method_context; struct ntfy_mailto_context *mtctx = nenv->method->context; struct sieve_address_source env_from = mtctx->set->parsed.envelope_from; const char *from = NULL; const struct smtp_address *from_smtp = NULL; const char *subject = mtactx->uri->subject; const char *body = mtactx->uri->body; string_t *to, *cc, *all; const struct uri_mailto_recipient *recipients; const struct uri_mailto_header_field *headers; struct sieve_smtp_context *sctx; struct ostream *output; string_t *msg; unsigned int count, i, hcount, h; const char *outmsgid, *error; int ret; /* Get recipients */ recipients = array_get(&mtactx->uri->recipients, &count); if (count == 0) { sieve_enotify_warning( nenv, "notify mailto uri specifies no recipients; " "action has no effect"); return 0; } /* Just to be sure */ if (!sieve_smtp_available(senv)) { sieve_enotify_global_warning( nenv, "notify mailto method has no means to send mail"); return 0; } /* Determine which sender to use From RFC 5436, Section 2.3: The ":from" tag overrides the default sender of the notification message. "Sender", here, refers to the value used in the [RFC5322] "From" header. Implementations MAY also use this value in the [RFC5321] "MAIL FROM" command (the "envelope sender"), or they may prefer to establish a mailbox that receives bounces from notification messages. */ if ((nenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) { from_smtp = sieve_message_get_sender(nenv->msgctx); if (from_smtp == NULL) { /* "<>" */ i_zero(&env_from); env_from.type = SIEVE_ADDRESS_SOURCE_EXPLICIT; } } from = nact->from; ret = sieve_address_source_get_address( &env_from, svinst, senv, nenv->msgctx, nenv->flags, &from_smtp); if (ret < 0) { from_smtp = NULL; } else if (ret == 0) { if (mtactx->from_address != NULL) from_smtp = mtactx->from_address; else if (svinst->set->parsed.user_email != NULL) from_smtp = svinst->set->parsed.user_email; else { from_smtp = sieve_get_postmaster_smtp(senv); if (from == NULL) from = sieve_get_postmaster_address(senv); } } /* Determine message from address */ if (from == NULL) { if (from_smtp == NULL) from = sieve_get_postmaster_address(senv); else { from = t_strdup_printf("<%s>", smtp_address_encode(from_smtp)); } } /* Determine subject */ if (nact->message != NULL) { subject = str_sanitize_utf8( nact->message, SIEVE_MAX_SUBJECT_HEADER_CODEPOINTS); } else if (subject == NULL) { const char *const *hsubject; /* Fetch subject from original message */ if (mail_get_headers_utf8(msgdata->mail, "subject", &hsubject) > 0) { subject = str_sanitize_utf8( t_strdup_printf("Notification: %s", hsubject[0]), SIEVE_MAX_SUBJECT_HEADER_CODEPOINTS); } else { subject = "Notification: (no subject)"; } } /* Compose To and Cc headers */ to = NULL; cc = NULL; all = t_str_new(256); for (i = 0; i < count; i++) { if (recipients[i].carbon_copy) { if (cc == NULL) { cc = t_str_new(256); str_append(cc, recipients[i].full); } else { str_append(cc, ", "); str_append(cc, recipients[i].full); } } else { if (to == NULL) { to = t_str_new(256); str_append(to, recipients[i].full); } else { str_append(to, ", "); str_append(to, recipients[i].full); } } if (i < 3) { if (i > 0) str_append(all, ", "); str_append( all, smtp_address_encode_path( recipients[i].address)); } else if (i == 3) { str_printfa(all, ", ... (%u total)", count); } } msg = t_str_new(512); outmsgid = sieve_message_get_new_id(svinst); rfc2822_header_write(msg, "X-Sieve", SIEVE_IMPLEMENTATION); rfc2822_header_write(msg, "Message-ID", outmsgid); rfc2822_header_write(msg, "Date", message_date_create(ioloop_time)); rfc2822_header_utf8_printf(msg, "Subject", "%s", subject); rfc2822_header_write_address(msg, "From", from); if (to != NULL) rfc2822_header_write_address(msg, "To", str_c(to)); if (cc != NULL) rfc2822_header_write_address(msg, "Cc", str_c(cc)); rfc2822_header_printf(msg, "Auto-Submitted", "auto-notified; owner-email=\"%s\"", smtp_address_encode(owner_email)); rfc2822_header_write(msg, "Precedence", "bulk"); /* Set importance */ switch (nact->importance) { case 1: rfc2822_header_write(msg, "X-Priority", "1 (Highest)"); rfc2822_header_write(msg, "Importance", "High"); break; case 3: rfc2822_header_write(msg, "X-Priority", "5 (Lowest)"); rfc2822_header_write(msg, "Importance", "Low"); break; case 2: default: rfc2822_header_write(msg, "X-Priority", "3 (Normal)"); rfc2822_header_write(msg, "Importance", "Normal"); break; } /* Add custom headers */ headers = array_get(&mtactx->uri->headers, &hcount); for (h = 0; h < hcount; h++) { const char *name = rfc2822_header_field_name_sanitize(headers[h].name); rfc2822_header_write(msg, name, headers[h].body); } /* Generate message body */ rfc2822_header_write(msg, "MIME-Version", "1.0"); if (body != NULL) { if (_contains_8bit(body)) { rfc2822_header_write(msg, "Content-Type", "text/plain; charset=utf-8"); rfc2822_header_write(msg, "Content-Transfer-Encoding", "8bit"); } else { rfc2822_header_write(msg, "Content-Type", "text/plain; charset=us-ascii"); rfc2822_header_write(msg, "Content-Transfer-Encoding", "7bit"); } str_printfa(msg, "\r\n%s\r\n", body); } else { rfc2822_header_write(msg, "Content-Type", "text/plain; charset=US-ASCII"); rfc2822_header_write(msg, "Content-Transfer-Encoding", "7bit"); str_append(msg, "\r\nNotification of new message.\r\n"); } sctx = sieve_smtp_start(senv, from_smtp); /* Send message to all recipients */ for (i = 0; i < count; i++) sieve_smtp_add_rcpt(sctx, recipients[i].address); output = sieve_smtp_send(sctx); o_stream_nsend(output, str_data(msg), str_len(msg)); if ((ret = sieve_smtp_finish(sctx, &error)) <= 0) { if (ret < 0) { sieve_enotify_global_error( nenv, "failed to send mail notification to %s: " "%s (temporary failure)", str_c(all), str_sanitize(error, 512)); } else { sieve_enotify_global_log_error( nenv, "failed to send mail notification to %s: " "%s (permanent failure)", str_c(all), str_sanitize(error, 512)); } } else { struct event_passthrough *e = sieve_enotify_create_finish_event(nenv)-> add_str("notify_target", str_c(all)); sieve_enotify_event_log(nenv, e->event(), "sent mail notification to %s", str_c(all)); } return 0; } static int ntfy_mailto_action_execute(const struct sieve_enotify_exec_env *nenv, const struct sieve_enotify_action *nact) { struct sieve_instance *svinst = nenv->svinst; const struct sieve_script_env *senv = nenv->scriptenv; struct mail *mail = nenv->msgdata->mail; const struct smtp_address *owner_email; const char *const *hdsp; int ret; owner_email = svinst->set->parsed.user_email; if (owner_email == NULL && (nenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) owner_email = sieve_message_get_final_recipient(nenv->msgctx); if (owner_email == NULL) owner_email = sieve_get_postmaster_smtp(senv); i_assert(owner_email != NULL); /* Is the message an automatic reply ? */ ret = mail_get_headers(mail, "auto-submitted", &hdsp); if (ret < 0) { sieve_enotify_critical( nenv, "mailto notification: " "failed to read 'auto-submitted' header field", "mailto notification: " "failed to read 'auto-submitted' header field: %s", mailbox_get_last_internal_error(mail->box, NULL)); return -1; } /* Theoretically multiple headers could exist, so lets make sure */ if (ret > 0) { while (*hdsp != NULL) { if (strcasecmp(*hdsp, "no") != 0) { const struct smtp_address *sender = NULL; const char *from; if ((nenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) sender = sieve_message_get_sender(nenv->msgctx); from = (sender == NULL ? "" : t_strdup_printf(" from <%s>", smtp_address_encode(sender))); sieve_enotify_global_info( nenv, "not sending notification " "for auto-submitted message%s", from); return 0; } hdsp++; } } T_BEGIN { ret = ntfy_mailto_send(nenv, nact, owner_email); } T_END; return ret; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto-settings.h0000644000175100001700000000050315100335616032340 0ustar00buildbotbuildbot00000000000000#ifndef NTFY_MAILTO_SETTINGS_H #define NTFY_MAILTO_SETTINGS_H #include "sieve-address-source.h" struct ntfy_mailto_settings { pool_t pool; const char *envelope_from; struct { struct sieve_address_source envelope_from; } parsed; }; extern const struct setting_parser_info ntfy_mailto_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/Makefile.am0000644000175100001700000000144215100335616026640 0ustar00buildbotbuildbot00000000000000SUBDIRS = mailto noinst_LTLIBRARIES = libsieve_ext_enotify.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-notify.c tests = \ tst-valid-notify-method.c \ tst-notify-method-capability.c var_modifiers = \ vmodf-encodeurl.c notify_methods = \ ./mailto/libsieve_ext_enotify_mailto.la libsieve_ext_enotify_la_DEPENDENCIES = \ $(notify_methods) libsieve_ext_enotify_la_LIBADD = \ $(notify_methods) libsieve_ext_enotify_la_SOURCES = \ ext-enotify.c \ ext-enotify-common.c \ $(commands) \ $(tests) \ $(var_modifiers) public_headers = \ sieve-ext-enotify.h headers = \ ext-enotify-limits.h \ ext-enotify-common.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c0000644000175100001700000000646315100335616031453 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-enotify-common.h" /* * Valid_notify_method test * * Syntax: * valid_notify_method */ static bool tst_vnotifym_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_vnotifym_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def valid_notify_method_test = { .identifier = "valid_notify_method", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_vnotifym_validate, .generate = tst_vnotifym_generate }; /* * Valid_notify_method operation */ static bool tst_vnotifym_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_vnotifym_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def valid_notify_method_operation = { .mnemonic = "VALID_NOTIFY_METHOD", .ext_def = &enotify_extension, .code = EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD, .dump = tst_vnotifym_operation_dump, .execute = tst_vnotifym_operation_execute }; /* * Test validation */ static bool tst_vnotifym_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if ( !sieve_validate_positional_argument (valdtr, tst, arg, "notification-uris", 1, SAAT_STRING_LIST) ) { return FALSE; } return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* * Test generation */ static bool tst_vnotifym_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &valid_notify_method_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool tst_vnotifym_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "VALID_NOTIFY_METHOD"); sieve_code_descend(denv); return sieve_opr_stringlist_dump(denv, address, "notify-uris"); } /* * Code execution */ static int tst_vnotifym_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_stringlist *notify_uris; string_t *uri_item; bool all_valid = TRUE; int ret; /* * Read operands */ /* Read notify uris */ if ( (ret=sieve_opr_stringlist_read (renv, address, "notify-uris", ¬ify_uris)) <= 0 ) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "valid_notify_method test"); uri_item = NULL; while ( (ret=sieve_stringlist_next_item(notify_uris, &uri_item)) > 0 ) { if ( !ext_enotify_runtime_method_validate(renv, uri_item) ) { all_valid = FALSE; break; } } if ( ret < 0 ) { sieve_runtime_trace_error(renv, "invalid method uri item"); return SIEVE_EXEC_BIN_CORRUPT; } sieve_interpreter_set_test_result(renv->interp, all_valid); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/Makefile.in0000644000175100001700000007421115100335630026651 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/enotify ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(pkginc_lib_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__objects_1 = cmd-notify.lo am__objects_2 = tst-valid-notify-method.lo \ tst-notify-method-capability.lo am__objects_3 = vmodf-encodeurl.lo am_libsieve_ext_enotify_la_OBJECTS = ext-enotify.lo \ ext-enotify-common.lo $(am__objects_1) $(am__objects_2) \ $(am__objects_3) libsieve_ext_enotify_la_OBJECTS = \ $(am_libsieve_ext_enotify_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-notify.Plo \ ./$(DEPDIR)/ext-enotify-common.Plo ./$(DEPDIR)/ext-enotify.Plo \ ./$(DEPDIR)/tst-notify-method-capability.Plo \ ./$(DEPDIR)/tst-valid-notify-method.Plo \ ./$(DEPDIR)/vmodf-encodeurl.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_enotify_la_SOURCES) DIST_SOURCES = $(libsieve_ext_enotify_la_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(noinst_HEADERS) $(pkginc_lib_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 distdir-am 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)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp 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_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = mailto noinst_LTLIBRARIES = libsieve_ext_enotify.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-notify.c tests = \ tst-valid-notify-method.c \ tst-notify-method-capability.c var_modifiers = \ vmodf-encodeurl.c notify_methods = \ ./mailto/libsieve_ext_enotify_mailto.la libsieve_ext_enotify_la_DEPENDENCIES = \ $(notify_methods) libsieve_ext_enotify_la_LIBADD = \ $(notify_methods) libsieve_ext_enotify_la_SOURCES = \ ext-enotify.c \ ext-enotify-common.c \ $(commands) \ $(tests) \ $(var_modifiers) public_headers = \ sieve-ext-enotify.h headers = \ ext-enotify-limits.h \ ext-enotify-common.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/enotify/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/enotify/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_enotify.la: $(libsieve_ext_enotify_la_OBJECTS) $(libsieve_ext_enotify_la_DEPENDENCIES) $(EXTRA_libsieve_ext_enotify_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_enotify_la_OBJECTS) $(libsieve_ext_enotify_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-notify.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-enotify-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-enotify.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-notify-method-capability.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-valid-notify-method.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmodf-encodeurl.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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 clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/cmd-notify.Plo -rm -f ./$(DEPDIR)/ext-enotify-common.Plo -rm -f ./$(DEPDIR)/ext-enotify.Plo -rm -f ./$(DEPDIR)/tst-notify-method-capability.Plo -rm -f ./$(DEPDIR)/tst-valid-notify-method.Plo -rm -f ./$(DEPDIR)/vmodf-encodeurl.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: 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 ./$(DEPDIR)/cmd-notify.Plo -rm -f ./$(DEPDIR)/ext-enotify-common.Plo -rm -f ./$(DEPDIR)/ext-enotify.Plo -rm -f ./$(DEPDIR)/tst-notify-method-capability.Plo -rm -f ./$(DEPDIR)/tst-valid-notify-method.Plo -rm -f ./$(DEPDIR)/vmodf-encodeurl.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am 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-pkginc_libHEADERS \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/ext-enotify.c0000644000175100001700000000507415100335616027230 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension enotify * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5435 * Implementation: full * Status: testing * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "sieve-ext-variables.h" #include "ext-enotify-common.h" /* * Operations */ const struct sieve_operation_def *ext_enotify_operations[] = { ¬ify_operation, &valid_notify_method_operation, ¬ify_method_capability_operation, }; /* * Extension */ static int ext_enotify_load(const struct sieve_extension *ext, void **context_r); static void ext_enotify_unload(const struct sieve_extension *ext); static bool ext_enotify_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def enotify_extension = { .name = "enotify", .load = ext_enotify_load, .unload = ext_enotify_unload, .validator_load = ext_enotify_validator_load, SIEVE_EXT_DEFINE_OPERATIONS(ext_enotify_operations), SIEVE_EXT_DEFINE_OPERAND(encodeurl_operand), }; static int ext_enotify_load(const struct sieve_extension *ext, void **context_r) { const struct sieve_extension *var_ext; struct ext_enotify_context *extctx; if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0) return -1; extctx = i_new(struct ext_enotify_context, 1); extctx->var_ext = var_ext; if (ext_enotify_methods_init(extctx, ext) < 0) { i_free(extctx); return -1; } sieve_extension_capabilities_register(ext, ¬ify_capabilities); *context_r = extctx; return 0; } static void ext_enotify_unload(const struct sieve_extension *ext) { struct ext_enotify_context *extctx = ext->context; if (extctx == NULL) return; ext_enotify_methods_deinit(extctx); i_free(extctx); } static bool ext_enotify_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct ext_enotify_context *extctx = ext->context; /* Register new commands */ sieve_validator_register_command(valdtr, ext, ¬ify_command); sieve_validator_register_command(valdtr, ext, &valid_notify_method_test); sieve_validator_register_command(valdtr, ext, ¬ify_method_capability_test); /* Register new set modifier for variables extension */ sieve_variables_modifier_register(extctx->var_ext, valdtr, ext, &encodeurl_modifier); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/ext-enotify-common.h0000644000175100001700000000522715100335616030523 0ustar00buildbotbuildbot00000000000000#ifndef EXT_ENOTIFY_COMMON_H #define EXT_ENOTIFY_COMMON_H #include "lib.h" #include "array.h" #include "sieve-common.h" #include "sieve-ext-variables.h" #include "sieve-ext-enotify.h" /* * Extension */ extern const struct sieve_extension_def enotify_extension; extern const struct sieve_extension_capabilities notify_capabilities; struct ext_enotify_context { const struct sieve_extension *var_ext; ARRAY(struct sieve_enotify_method) notify_methods; }; /* * Commands */ extern const struct sieve_command_def notify_command; /* Codes for optional arguments */ enum cmd_notify_optional { CMD_NOTIFY_OPT_END, CMD_NOTIFY_OPT_FROM, CMD_NOTIFY_OPT_OPTIONS, CMD_NOTIFY_OPT_MESSAGE, CMD_NOTIFY_OPT_IMPORTANCE }; /* * Tests */ extern const struct sieve_command_def valid_notify_method_test; extern const struct sieve_command_def notify_method_capability_test; /* * Operations */ extern const struct sieve_operation_def notify_operation; extern const struct sieve_operation_def valid_notify_method_operation; extern const struct sieve_operation_def notify_method_capability_operation; enum ext_variables_opcode { EXT_ENOTIFY_OPERATION_NOTIFY, EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD, EXT_ENOTIFY_OPERATION_NOTIFY_METHOD_CAPABILITY }; /* * Operands */ extern const struct sieve_operand_def encodeurl_operand; /* * Modifiers */ extern const struct sieve_variables_modifier_def encodeurl_modifier; /* * Notify methods */ int ext_enotify_methods_init(struct ext_enotify_context *extctx, const struct sieve_extension *ntfy_ext); void ext_enotify_methods_deinit(struct ext_enotify_context *extctx); const struct sieve_enotify_method * ext_enotify_method_find(const struct sieve_extension *ntfy_ext, const char *identifier); /* * Validation */ bool ext_enotify_compile_check_arguments( struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg, struct sieve_ast_argument *options_arg); /* * Runtime */ bool ext_enotify_runtime_method_validate(const struct sieve_runtime_env *renv, string_t *method_uri); const char * ext_enotify_runtime_get_method_capability(const struct sieve_runtime_env *renv, string_t *method_uri, const char *capability); int ext_enotify_runtime_check_operands( const struct sieve_runtime_env *renv, string_t *method_uri, string_t *message, string_t *from, struct sieve_stringlist *options, const struct sieve_enotify_method **method_r, void **method_context); /* * Method printing */ struct sieve_enotify_print_env { const struct sieve_result_print_env *result_penv; }; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c0000644000175100001700000001350515100335616032470 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-enotify-common.h" /* * String test * * Syntax: * notify_method_capability [COMPARATOR] [MATCH-TYPE] * * * */ static bool tst_notifymc_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_notifymc_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_notifymc_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def notify_method_capability_test = { .identifier = "notify_method_capability", .type = SCT_TEST, .positional_args = 3, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_notifymc_registered, .validate = tst_notifymc_validate, .generate = tst_notifymc_generate }; /* * String operation */ static bool tst_notifymc_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_notifymc_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def notify_method_capability_operation = { .mnemonic = "NOTIFY_METHOD_CAPABILITY", .ext_def = &enotify_extension, .code = EXT_ENOTIFY_OPERATION_NOTIFY_METHOD_CAPABILITY, .dump = tst_notifymc_operation_dump, .execute = tst_notifymc_operation_execute }; /* * Optional arguments */ enum tst_notifymc_optional { OPT_END, OPT_COMPARATOR, OPT_MATCH_TYPE }; /* * Test registration */ static bool tst_notifymc_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, OPT_MATCH_TYPE); return TRUE; } /* * Test validation */ static bool tst_notifymc_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "notification-uri", 1, SAAT_STRING) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "notification-capability", 2, SAAT_STRING) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "key-list", 3, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate (valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Test generation */ static bool tst_notifymc_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit (cgenv->sblock, cmd->ext, ¬ify_method_capability_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool tst_notifymc_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "NOTIFY_METHOD_CAPABILITY"); sieve_code_descend(denv); /* Handle any optional arguments */ if ( sieve_match_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return sieve_opr_string_dump(denv, address, "notify uri") && sieve_opr_string_dump(denv, address, "notify capability") && sieve_opr_stringlist_dump(denv, address, "key list"); } /* * Code execution */ static int tst_notifymc_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); string_t *notify_uri, *notify_capability; struct sieve_stringlist *value_list, *key_list; const char *cap_value; int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ if ( sieve_match_opr_optional_read (renv, address, NULL, &ret, &cmp, &mcht) < 0 ) return ret; /* Read notify uri */ if ( (ret=sieve_opr_string_read(renv, address, "notify-uri", ¬ify_uri)) <= 0 ) return ret; /* Read notify capability */ if ( (ret=sieve_opr_string_read (renv, address, "notify-capability", ¬ify_capability)) <= 0 ) return ret; /* Read key-list */ if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) <= 0) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "notify_method_capability test"); cap_value = ext_enotify_runtime_get_method_capability (renv, notify_uri, str_c(notify_capability)); if ( cap_value != NULL ) { value_list = sieve_single_stringlist_create_cstr(renv, cap_value, TRUE); /* Perform match */ if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) return ret; } else { match = 0; } /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/ext-enotify-common.c0000644000175100001700000004741215100335616030520 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "array.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "ext-enotify-limits.h" #include "ext-enotify-common.h" #include /* FIXME: (from draft RFC) Header/envelope tests [Sieve] together with Sieve variables can be used to extract the list of users to receive notifications from the incoming email message or its envelope. This is potentially quite dangerous, as this can be used for Deny Of Service attacks on recipients controlled by the message sender. For this reason implementations SHOULD NOT allow use of variables containing values extracted from the email message in the method parameter to the notify action. Note that violation of this SHOULD NOT may result in* the creation of an open relay, i.e. any sender would be able to create specially crafted email messages that would result in notifications delivered to recipients under the control of the sender. In worst case this might result in financial loss by user controlling the Sieve script and/or by recipients of notifications (e.g. if a notification is an SMS message). --> This is currently not possible to check. */ /* * Notify capability */ static const char * ext_notify_get_methods_string(const struct sieve_extension *ntfy_ext); const struct sieve_extension_capabilities notify_capabilities = { "notify", ext_notify_get_methods_string, }; /* * Core notification methods */ extern const struct sieve_enotify_method_def mailto_notify; /* * Enotify extension */ int sieve_ext_enotify_get_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_register(svinst, &enotify_extension, FALSE, ext_r); } int sieve_ext_enotify_require_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_require(svinst, &enotify_extension, TRUE, ext_r); } /* * Notify method registry */ static int ext_enotify_method_register(struct ext_enotify_context *extctx, const struct sieve_extension *ntfy_ext, const struct sieve_enotify_method_def *nmth_def, const struct sieve_enotify_method **nmth_r) { struct sieve_enotify_method *nmth; int nmth_id = (int)array_count(&extctx->notify_methods); nmth = array_append_space(&extctx->notify_methods); nmth->def = nmth_def; nmth->id = nmth_id; nmth->svinst = ntfy_ext->svinst; nmth->ext = ntfy_ext; if (nmth_def->load != NULL && nmth_def->load(nmth, &nmth->context) < 0) { array_pop_back(&extctx->notify_methods); return -1; } *nmth_r = nmth; return 0; } int ext_enotify_methods_init(struct ext_enotify_context *extctx, const struct sieve_extension *ntfy_ext) { const struct sieve_enotify_method *nmth; p_array_init(&extctx->notify_methods, default_pool, 4); if (ext_enotify_method_register(extctx, ntfy_ext, &mailto_notify, &nmth) < 0) return -1; return 0; } void ext_enotify_methods_deinit(struct ext_enotify_context *extctx) { const struct sieve_enotify_method *methods; unsigned int meth_count, i; methods = array_get(&extctx->notify_methods, &meth_count); for (i = 0; i < meth_count; i++) { if (methods[i].def != NULL && methods[i].def->unload != NULL) methods[i].def->unload(&methods[i]); } array_free(&extctx->notify_methods); } int sieve_enotify_method_register( const struct sieve_extension *ntfy_ext, const struct sieve_enotify_method_def *nmth_def, const struct sieve_enotify_method **nmth_r) { i_assert(ntfy_ext != NULL); i_assert(ntfy_ext->def == &enotify_extension); struct ext_enotify_context *extctx = ntfy_ext->context; return ext_enotify_method_register(extctx, ntfy_ext, nmth_def, nmth_r); } void sieve_enotify_method_unregister(const struct sieve_enotify_method *nmth) { const struct sieve_extension *ntfy_ext = nmth->ext; i_assert(ntfy_ext != NULL); i_assert(ntfy_ext->def == &enotify_extension); struct ext_enotify_context *extctx = ntfy_ext->context; int nmth_id = nmth->id; if (nmth_id >= 0 && nmth_id < (int)array_count(&extctx->notify_methods)) { struct sieve_enotify_method *nmth_mod = array_idx_modifiable(&extctx->notify_methods, nmth_id); nmth_mod->def = NULL; } } const struct sieve_enotify_method * ext_enotify_method_find(const struct sieve_extension *ntfy_ext, const char *identifier) { struct ext_enotify_context *extctx = ntfy_ext->context; unsigned int meth_count, i; const struct sieve_enotify_method *methods; methods = array_get(&extctx->notify_methods, &meth_count); for (i = 0; i < meth_count; i++) { if (methods[i].def == NULL) continue; if (strcasecmp(methods[i].def->identifier, identifier) == 0) return &methods[i]; } return NULL; } static const char * ext_notify_get_methods_string(const struct sieve_extension *ntfy_ext) { struct ext_enotify_context *extctx = ntfy_ext->context; unsigned int meth_count, i; const struct sieve_enotify_method *methods; string_t *result = t_str_new(128); methods = array_get(&extctx->notify_methods, &meth_count); if (meth_count > 0) { for (i = 0; i < meth_count; i++) { if (str_len(result) > 0) str_append_c(result, ' '); if (methods[i].def != NULL) str_append(result, methods[i].def->identifier); } return str_c(result); } return NULL; } /* * Compile-time argument validation */ static const char *ext_enotify_uri_scheme_parse(const char **uri_p) { string_t *scheme = t_str_new(EXT_ENOTIFY_MAX_SCHEME_LEN); const char *p = *uri_p; unsigned int len = 0; /* RFC 3968: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) FIXME: we do not allow '%' in schemes. Is this correct? */ if (!i_isalpha(*p)) return NULL; str_append_c(scheme, *p); p++; while (*p != '\0' && len < EXT_ENOTIFY_MAX_SCHEME_LEN) { if (!i_isalnum(*p) && *p != '+' && *p != '-' && *p != '.') break; str_append_c(scheme, *p); p++; len++; } if (*p != ':') return NULL; p++; *uri_p = p; return str_c(scheme); } static bool ext_enotify_option_parse(struct sieve_enotify_env *nenv, const char *option, bool name_only, const char **opt_name_r, const char **opt_value_r) { const char *p = option; /* "=". l-d = ALPHA / DIGIT l-d-p = l-d / "." / "-" / "_" optionname = l-d *l-d-p value = *(%x01-09 / %x0B-0C / %x0E-FF) */ /* * Parse option name */ /* optionname = l-d *l-d-p */ /* Explicitly report empty option as such */ if (*p == '\0') { sieve_enotify_error(nenv, "empty option specified"); return FALSE; } /* l-d = ALPHA / DIGIT */ if (i_isalnum(*p)) { p++; /* l-d-p = l-d / "." / "-" / "_" */ while (i_isalnum(*p) || *p == '.' || *p == '-' || *p == '_') p++; } /* Parsing must end at '=' and we must parse at least one character */ if (*p != '=' || p == option) { sieve_enotify_error( nenv, "invalid option name specified in option '%s'", str_sanitize(option, 80)); return FALSE; } /* Assign option name */ if (opt_name_r != NULL) *opt_name_r = t_strdup_until(option, p); /* Skip '=' */ p++; /* Exit now if only the option name is of interest */ if (name_only) return TRUE; /* * Parse option value */ /* value = *(%x01-09 / %x0B-0C / %x0E-FF) */ while (*p != '\0' && *p != 0x0A && *p != 0x0D) p++; /* Parse must end at end of string */ if (*p != '\0') { sieve_enotify_error( nenv, "notify command: " "invalid option value specified in option '%s'", str_sanitize(option, 80)); return FALSE; } /* Assign option value */ if (opt_value_r != NULL) *opt_value_r = p; return TRUE; } struct _ext_enotify_option_check_context { struct sieve_instance *svinst; struct sieve_validator *valdtr; const struct sieve_enotify_method *method; }; static int _ext_enotify_option_check(void *context, struct sieve_ast_argument *arg) { struct _ext_enotify_option_check_context *optn_context = (struct _ext_enotify_option_check_context *) context; struct sieve_validator *valdtr = optn_context->valdtr; const struct sieve_enotify_method *method = optn_context->method; struct sieve_enotify_env nenv; const char *option = sieve_ast_argument_strc(arg); const char *opt_name = NULL, *opt_value = NULL; bool check = TRUE; int result = 1; /* Compose log structure */ i_zero(&nenv); nenv.svinst = optn_context->svinst; nenv.method = method; nenv.ehandler = sieve_validator_error_handler(valdtr); nenv.location = sieve_error_script_location( sieve_validator_script(valdtr), arg->source_line); nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify command: "); /* Parse option */ if (!sieve_argument_is_string_literal(arg)) { /* Variable string: partial option parse If the string item is not a string literal, it cannot be validated fully at compile time. We can however check whether the '=' is in the string specification and whether the part before the '=' is a valid option name. In that case, the method option check function is called with the value parameter equal to NULL, meaning that it should only check the validity of the option itself and not the assigned value. */ if (!ext_enotify_option_parse(NULL, option, TRUE, &opt_name, &opt_value)) check = FALSE; } else { /* Literal string: full option parse */ if (!ext_enotify_option_parse(&nenv, option, FALSE, &opt_name, &opt_value)) result = -1; } /* Call method's option check function */ if (result > 0 && check && method->def != NULL && method->def->compile_check_option != NULL) { result = (method->def->compile_check_option(&nenv, opt_name, opt_value) ? 1 : -1); } event_unref(&nenv.event); return result; } bool ext_enotify_compile_check_arguments(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg, struct sieve_ast_argument *options_arg) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_instance *svinst = this_ext->svinst; const char *uri = sieve_ast_argument_strc(uri_arg); const char *scheme; const struct sieve_enotify_method *method; struct sieve_enotify_env nenv; bool result = TRUE; /* If the uri string is not a constant literal, we cannot determine which method is used, so we bail out successfully and defer checking to runtime. */ if (!sieve_argument_is_string_literal(uri_arg)) return TRUE; /* Parse scheme part of URI */ if ((scheme = ext_enotify_uri_scheme_parse(&uri)) == NULL) { sieve_argument_validate_error( valdtr, uri_arg, "notify command: " "invalid scheme part for method URI '%s'", str_sanitize(sieve_ast_argument_strc(uri_arg), 80)); return FALSE; } /* Find used method with the parsed scheme identifier */ if ((method = ext_enotify_method_find(this_ext, scheme)) == NULL) { sieve_argument_validate_error( valdtr, uri_arg, "notify command: " "invalid method '%s'", scheme); return FALSE; } if (method->def == NULL) return TRUE; /* Compose log structure */ i_zero(&nenv); nenv.svinst = svinst; nenv.method = method; /* Check URI itself */ if (result && method->def->compile_check_uri != NULL) { /* Set log location to location of URI argument */ nenv.ehandler = sieve_validator_error_handler(valdtr); nenv.location = sieve_error_script_location( sieve_validator_script(valdtr), uri_arg->source_line); nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify command: "); /* Execute method check function */ result = method->def->compile_check_uri( &nenv, sieve_ast_argument_strc(uri_arg), uri); } /* Check :message argument */ if (result && msg_arg != NULL && sieve_argument_is_string_literal(msg_arg) && method->def->compile_check_message != NULL) { /* Set log location to location of :message argument */ event_unref(&nenv.event); nenv.ehandler = sieve_validator_error_handler(valdtr); nenv.location = sieve_error_script_location( sieve_validator_script(valdtr), msg_arg->source_line); nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify command: "); /* Execute method check function */ result = method->def->compile_check_message( &nenv, sieve_ast_argument_str(msg_arg)); } /* Check :from argument */ if (result && from_arg != NULL && sieve_argument_is_string_literal(from_arg) && method->def->compile_check_from != NULL) { /* Set log location to location of :from argument */ event_unref(&nenv.event); nenv.ehandler = sieve_validator_error_handler(valdtr); nenv.location = sieve_error_script_location( sieve_validator_script(valdtr), from_arg->source_line); nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify command: "); /* Execute method check function */ result = method->def->compile_check_from( &nenv, sieve_ast_argument_str(from_arg)); } event_unref(&nenv.event); /* Check :options argument */ if (result && options_arg != NULL) { struct sieve_ast_argument *option = options_arg; struct _ext_enotify_option_check_context optn_context = { svinst, valdtr, method }; /* Parse and check options */ result = (sieve_ast_stringlist_map( &option, &optn_context, _ext_enotify_option_check) > 0); /* Discard argument if options are not accepted by method */ if (result && method->def->compile_check_option == NULL) { sieve_argument_validate_warning( valdtr, options_arg, "notify command: " "method '%s' accepts no options", scheme); (void)sieve_ast_arguments_detach(options_arg, 1); } } return result; } /* * Runtime operand checking */ bool ext_enotify_runtime_method_validate(const struct sieve_runtime_env *renv, string_t *method_uri) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_extension *this_ext = renv->oprtn->ext; const struct sieve_enotify_method *method; const char *uri = str_c(method_uri); const char *scheme; bool result = TRUE; /* Get the method */ if ((scheme = ext_enotify_uri_scheme_parse(&uri)) == NULL) return FALSE; if ((method = ext_enotify_method_find(this_ext, scheme)) == NULL) return FALSE; /* Validate the provided URI */ if (method->def != NULL && method->def->runtime_check_uri != NULL) { struct sieve_enotify_env nenv; i_zero(&nenv); nenv.svinst = eenv->svinst; nenv.method = method; nenv.ehandler = renv->ehandler; nenv.location = sieve_runtime_get_full_command_location(renv), nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "valid_notify_method test: "); /* Use the method check function to validate the URI */ result = method->def->runtime_check_uri( &nenv, str_c(method_uri), uri); event_unref(&nenv.event); } return result; } static const struct sieve_enotify_method *ext_enotify_get_method( const struct sieve_runtime_env *renv, string_t *method_uri, const char **uri_body_r) { const struct sieve_extension *this_ext = renv->oprtn->ext; const struct sieve_enotify_method *method; const char *uri = str_c(method_uri); const char *scheme; /* Parse part before ':' of the uri (the scheme) and use it to identify notify method. */ if ((scheme = ext_enotify_uri_scheme_parse(&uri)) == NULL) { sieve_runtime_error( renv, NULL, "invalid scheme part for method URI '%s'", str_sanitize(str_c(method_uri), 80)); return NULL; } /* Find the notify method */ if ((method = ext_enotify_method_find(this_ext, scheme)) == NULL) { sieve_runtime_error(renv, NULL, "invalid notify method '%s'", scheme); return NULL; } /* Return the parse pointer and the found method */ *uri_body_r = uri; return method; } const char * ext_enotify_runtime_get_method_capability(const struct sieve_runtime_env *renv, string_t *method_uri, const char *capability) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_enotify_method *method; const char *uri_body; const char *result = NULL; /* Get method */ method = ext_enotify_get_method(renv, method_uri, &uri_body); if (method == NULL) return NULL; /* Get requested capability */ if (method->def != NULL && method->def->runtime_get_method_capability != NULL) { struct sieve_enotify_env nenv; i_zero(&nenv); nenv.svinst = eenv->svinst; nenv.method = method; nenv.ehandler = renv->ehandler; nenv.location = sieve_runtime_get_full_command_location(renv), nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify_method_capability test: "); /* Execute method function to acquire capability value */ result = method->def->runtime_get_method_capability( &nenv, str_c(method_uri), uri_body, capability); event_unref(&nenv.event); } return result; } int ext_enotify_runtime_check_operands( const struct sieve_runtime_env *renv, string_t *method_uri, string_t *message, string_t *from, struct sieve_stringlist *options, const struct sieve_enotify_method **method_r, void **method_context) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_enotify_method *method; const char *uri_body; /* Get method */ method = ext_enotify_get_method(renv, method_uri, &uri_body); if (method == NULL) return SIEVE_EXEC_FAILURE; /* Check provided operands */ if (method->def != NULL && method->def->runtime_check_operands != NULL) { struct sieve_enotify_env nenv; int result = SIEVE_EXEC_OK; i_zero(&nenv); nenv.svinst = eenv->svinst; nenv.method = method; nenv.ehandler = renv->ehandler; nenv.location = sieve_runtime_get_full_command_location(renv), nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify_action: "); /* Execute check function */ if (method->def->runtime_check_operands( &nenv, str_c(method_uri), uri_body, message, from, sieve_result_pool(renv->result), method_context)) { /* Check any provided options */ if (options != NULL) { string_t *option = NULL; int ret; /* Iterate through all provided options */ while ((ret = sieve_stringlist_next_item( options, &option)) > 0) { const char *opt_name = NULL; const char *opt_value = NULL; /* Parse option into and */ if (ext_enotify_option_parse( &nenv, str_c(option), FALSE, &opt_name, &opt_value)) { /* Set option */ if (method->def->runtime_set_option != NULL) { (void)method->def->runtime_set_option( &nenv, *method_context, opt_name, opt_value); } } } /* Check for binary corruptions encountered during string list iteration */ if (ret >= 0) { *method_r = method; } else { /* Binary corrupt */ sieve_runtime_trace_error( renv, "invalid item in options string list"); result = SIEVE_EXEC_BIN_CORRUPT; } } else { /* No options */ *method_r = method; } } else { /* Operand check failed */ result = SIEVE_EXEC_FAILURE; } event_unref(&nenv.event); return result; } /* No check function defined: a most unlikely situation */ *method_context = NULL; *method_r = method; return SIEVE_EXEC_OK; } /* * Notify method printing */ void sieve_enotify_method_printf(const struct sieve_enotify_print_env *penv, const char *fmt, ...) { va_list args; va_start(args, fmt); sieve_result_vprintf(penv->result_penv, fmt, args); va_end(args); } /* * Action execution */ struct event_passthrough * sieve_enotify_create_finish_event(const struct sieve_enotify_exec_env *nenv) { struct event_passthrough *e = event_create_passthrough(nenv->event)-> set_name("sieve_action_finished"); return e; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/cmd-notify.c0000644000175100001700000003541515100335616027030 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-result.h" #include "ext-enotify-common.h" /* * Forward declarations */ static const struct sieve_argument_def notify_importance_tag; static const struct sieve_argument_def notify_from_tag; static const struct sieve_argument_def notify_options_tag; static const struct sieve_argument_def notify_message_tag; /* * Notify command * * Syntax: * notify [":from" string] * [":importance" <"1" / "2" / "3">] * [":options" string-list] * [":message" string] * */ static bool cmd_notify_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_notify_pre_validate(struct sieve_validator *validator, struct sieve_command *cmd); static bool cmd_notify_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_notify_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def notify_command = { .identifier = "notify", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_notify_registered, .pre_validate = cmd_notify_pre_validate, .validate = cmd_notify_validate, .generate = cmd_notify_generate, }; /* * Notify command tags */ /* Forward declarations */ static bool cmd_notify_validate_string_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool cmd_notify_validate_stringlist_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool cmd_notify_validate_importance_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def notify_from_tag = { .identifier = "from", .validate = cmd_notify_validate_string_tag, }; static const struct sieve_argument_def notify_options_tag = { .identifier = "options", .validate = cmd_notify_validate_stringlist_tag, }; static const struct sieve_argument_def notify_message_tag = { .identifier = "message", .validate = cmd_notify_validate_string_tag, }; static const struct sieve_argument_def notify_importance_tag = { .identifier = "importance", .validate = cmd_notify_validate_importance_tag, }; /* * Notify operation */ static bool cmd_notify_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_notify_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def notify_operation = { .mnemonic = "NOTIFY", .ext_def = &enotify_extension, .code = EXT_ENOTIFY_OPERATION_NOTIFY, .dump = cmd_notify_operation_dump, .execute = cmd_notify_operation_execute, }; /* * Notify action */ /* Forward declarations */ static int act_notify_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_notify_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_notify_commit(const struct sieve_action_exec_env *aenv, void *tr_context); /* Action object */ const struct sieve_action_def act_notify = { .name = "notify", .check_duplicate =act_notify_check_duplicate, .print = act_notify_print, .commit = act_notify_commit, }; /* * Command validation context */ struct cmd_notify_context_data { struct sieve_ast_argument *from; struct sieve_ast_argument *message; struct sieve_ast_argument *options; }; /* * Tag validation */ static bool cmd_notify_validate_string_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_notify_context_data *ctx_data = (struct cmd_notify_context_data *)cmd->data; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: :from :message */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE)) return FALSE; if (sieve_argument_is(tag, notify_from_tag)) { ctx_data->from = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); } else if (sieve_argument_is(tag, notify_message_tag)) { ctx_data->message = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); } return TRUE; } static bool cmd_notify_validate_stringlist_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_notify_context_data *ctx_data = (struct cmd_notify_context_data *)cmd->data; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: :options string-list */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING_LIST, FALSE)) return FALSE; /* Assign context */ ctx_data->options = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool cmd_notify_validate_importance_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd ATTR_UNUSED) { const struct sieve_ast_argument *tag = *arg; const char *impstr; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: :importance <"1" / "2" / "3"> */ if (sieve_ast_argument_type(*arg) != SAAT_STRING) { /* Not a string */ sieve_argument_validate_error( valdtr, *arg, "the :importance tag for the notify command requires a string parameter, " "but %s was found", sieve_ast_argument_name(*arg)); return FALSE; } impstr = sieve_ast_argument_strc(*arg); if (impstr[0] < '1' || impstr[0] > '3' || impstr[1] != '\0') { /* Invalid importance */ sieve_argument_validate_error( valdtr, *arg, "invalid :importance value for notify command: %s", impstr); return FALSE; } sieve_ast_argument_number_substitute(*arg, impstr[0] - '0'); (*arg)->argument = sieve_argument_create((*arg)->ast, &number_argument, tag->argument->ext, tag->argument->id_code); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Command registration */ static bool cmd_notify_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, ¬ify_importance_tag, CMD_NOTIFY_OPT_IMPORTANCE); sieve_validator_register_tag(valdtr, cmd_reg, ext, ¬ify_from_tag, CMD_NOTIFY_OPT_FROM); sieve_validator_register_tag(valdtr, cmd_reg, ext, ¬ify_options_tag, CMD_NOTIFY_OPT_OPTIONS); sieve_validator_register_tag(valdtr, cmd_reg, ext, ¬ify_message_tag, CMD_NOTIFY_OPT_MESSAGE); return TRUE; } /* * Command validation */ static bool cmd_notify_pre_validate(struct sieve_validator *validator ATTR_UNUSED, struct sieve_command *cmd) { struct cmd_notify_context_data *ctx_data; /* Assign context */ ctx_data = p_new(sieve_command_pool(cmd), struct cmd_notify_context_data, 1); cmd->data = ctx_data; return TRUE; } static bool cmd_notify_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_notify_context_data *ctx_data = (struct cmd_notify_context_data *)cmd->data; if (!sieve_validate_positional_argument(valdtr, cmd, arg, "method", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; return ext_enotify_compile_check_arguments( valdtr, cmd, arg, ctx_data->message, ctx_data->from, ctx_data->options); } /* * Code generation */ static bool cmd_notify_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, ¬ify_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_notify_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "NOTIFY"); sieve_code_descend(denv); /* Dump optional operands */ for (;;) { int opt; bool opok = TRUE; if ((opt = sieve_opr_optional_dump(denv, address, &opt_code)) < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case CMD_NOTIFY_OPT_IMPORTANCE: opok = sieve_opr_number_dump(denv, address, "importance"); break; case CMD_NOTIFY_OPT_FROM: opok = sieve_opr_string_dump(denv, address, "from"); break; case CMD_NOTIFY_OPT_OPTIONS: opok = sieve_opr_stringlist_dump(denv, address, "options"); break; case CMD_NOTIFY_OPT_MESSAGE: opok = sieve_opr_string_dump(denv, address, "message"); break; default: return FALSE; } if (!opok) return FALSE; } /* Dump method operand */ return sieve_opr_string_dump(denv, address, "method"); } /* * Code execution */ static int cmd_notify_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct sieve_side_effects_list *slist = NULL; struct sieve_enotify_action *act; void *method_context; pool_t pool; int opt_code = 0; sieve_number_t importance = 2; struct sieve_stringlist *options = NULL; const struct sieve_enotify_method *method; string_t *method_uri, *message = NULL, *from = NULL; int ret; /* * Read operands */ /* Optional operands */ for (;;) { int opt; if ((opt = sieve_opr_optional_read(renv, address, &opt_code)) < 0) return SIEVE_EXEC_BIN_CORRUPT; if (opt == 0) break; switch (opt_code) { case CMD_NOTIFY_OPT_IMPORTANCE: ret = sieve_opr_number_read(renv, address, "importance", &importance); break; case CMD_NOTIFY_OPT_FROM: ret = sieve_opr_string_read(renv, address, "from", &from); break; case CMD_NOTIFY_OPT_MESSAGE: ret = sieve_opr_string_read(renv, address, "message", &message); break; case CMD_NOTIFY_OPT_OPTIONS: ret = sieve_opr_stringlist_read(renv, address, "options", &options); break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } if (ret <= 0) return ret; } /* Method operand */ if ((ret = sieve_opr_string_read(renv, address, "method", &method_uri)) <= 0) return ret; /* * Perform operation */ /* Enforce 0 < importance < 4 (just to be sure) */ if (importance < 1) importance = 1; else if (importance > 3) importance = 3; /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS)) { sieve_runtime_trace(renv, 0, "notify action"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, "notify with uri '%s'", str_sanitize(str_c(method_uri), 80)); } /* Check operands */ if ((ret = ext_enotify_runtime_check_operands(renv, method_uri, message, from, options, &method, &method_context)) > 0) { /* Add notify action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct sieve_enotify_action, 1); act->method = method; act->method_context = method_context; act->importance = importance; if (message != NULL) act->message = p_strdup(pool, str_c(message)); if (from != NULL) act->from = p_strdup(pool, str_c(from)); if (sieve_result_add_action(renv, this_ext, "notify", &act_notify, slist, act, 0, FALSE) < 0) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } return ret; } /* * Action */ /* Runtime verification */ static int act_notify_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_enotify_action *nact, *nact_other; const struct sieve_enotify_method_def *nmth_def; struct sieve_enotify_env nenv; int result; if (act->context == NULL || act_other->context == NULL) return 0; nact = (const struct sieve_enotify_action *)act->context; nact_other = (const struct sieve_enotify_action *)act_other->context; if (nact->method == NULL || nact->method->def == NULL) return 0; nmth_def = nact->method->def; if (nmth_def->action_check_duplicates == NULL) return 0; i_zero(&nenv); nenv.svinst = eenv->svinst; nenv.method = nact->method; nenv.ehandler = renv->ehandler; nenv.location = act->location; nenv.event = event_create(nenv.svinst->event); event_set_append_log_prefix(nenv.event, "notify: "); result = nmth_def->action_check_duplicates(&nenv, nact, nact_other); event_unref(&nenv.event); return result; } /* Result printing */ static void act_notify_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { const struct sieve_enotify_action *act = (const struct sieve_enotify_action *)action->context; const struct sieve_enotify_method *method; method = act->method; if (method->def != NULL) { sieve_result_action_printf( rpenv, "send notification with method '%s:':", method->def->identifier); if (method->def->action_print != NULL) { struct sieve_enotify_print_env penv; i_zero(&penv); penv.result_penv = rpenv; method->def->action_print(&penv, act); } } } /* Result execution */ static int act_notify_commit(const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED) { const struct sieve_execute_env *eenv = aenv->exec_env; const struct sieve_enotify_action *act = (const struct sieve_enotify_action *)aenv->action->context; const struct sieve_enotify_method *method = act->method; struct sieve_enotify_exec_env nenv; int ret = 0; if (method->def != NULL && method->def->action_execute != NULL) { /* Compose log structure */ i_zero(&nenv); nenv.svinst = eenv->svinst; nenv.flags = eenv->flags; nenv.method = method; nenv.scriptenv = eenv->scriptenv; nenv.msgdata = eenv->msgdata; nenv.msgctx = aenv->msgctx; nenv.ehandler = aenv->ehandler; nenv.event = aenv->event; ret = method->def->action_execute(&nenv, act); if (ret >= 0) eenv->exec_status->significant_action_executed = TRUE; } return (ret >= 0 ? SIEVE_EXEC_OK : SIEVE_EXEC_TEMP_FAILURE); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h0000644000175100001700000001275515100335616030352 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXT_ENOTIFY_H #define SIEVE_EXT_ENOTIFY_H #include "lib.h" #include "compat.h" #include #include "sieve-common.h" #include "sieve-error.h" /* * Forward declarations */ struct sieve_enotify_method; struct sieve_enotify_env; struct sieve_enotify_action; struct sieve_enotify_print_env; struct sieve_enotify_exec_env; /* * Enotify extension */ int sieve_ext_enotify_get_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r); int sieve_ext_enotify_require_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r); /* * Notify method definition */ struct sieve_enotify_method_def { const char *identifier; /* Registration */ int (*load)(const struct sieve_enotify_method *nmth, void **context); void (*unload)(const struct sieve_enotify_method *nmth); /* Validation */ bool (*compile_check_uri)(const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body); bool (*compile_check_message)(const struct sieve_enotify_env *nenv, string_t *message); bool (*compile_check_from)(const struct sieve_enotify_env *nenv, string_t *from); bool (*compile_check_option)(const struct sieve_enotify_env *nenv, const char *option, const char *value); /* Runtime */ bool (*runtime_check_uri)(const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body); const char *(*runtime_get_method_capability)( const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body, const char *capability); bool (*runtime_check_operands)( const struct sieve_enotify_env *nenv, const char *uri, const char *uri_body, string_t *message, string_t *from, pool_t context_pool, void **method_context); bool (*runtime_set_option)( const struct sieve_enotify_env *nenv, void *method_context, const char *option, const char *value); /* Action duplicates */ int (*action_check_duplicates)( const struct sieve_enotify_env *nenv, const struct sieve_enotify_action *nact, const struct sieve_enotify_action *nact_other); /* Action print */ void (*action_print)( const struct sieve_enotify_print_env *penv, const struct sieve_enotify_action *nact); /* Action execution (returns 0 if all is ok and -1 for temporary error) */ int (*action_execute)(const struct sieve_enotify_exec_env *nenv, const struct sieve_enotify_action *nact); }; /* * Notify method instance */ struct sieve_enotify_method { const struct sieve_enotify_method_def *def; int id; struct sieve_instance *svinst; const struct sieve_extension *ext; void *context; }; int sieve_enotify_method_register( const struct sieve_extension *ntfy_ext, const struct sieve_enotify_method_def *nmth_def, const struct sieve_enotify_method **nmth_r); void sieve_enotify_method_unregister(const struct sieve_enotify_method *nmth); /* * Notify method environment */ struct sieve_enotify_env { struct sieve_instance *svinst; const struct sieve_enotify_method *method; struct sieve_error_handler *ehandler; const char *location; struct event *event; }; /* * Notify method printing */ void sieve_enotify_method_printf(const struct sieve_enotify_print_env *penv, const char *fmt, ...) ATTR_FORMAT(2, 3); /* * Notify execution environment */ struct sieve_enotify_exec_env { struct sieve_instance *svinst; enum sieve_execute_flags flags; const struct sieve_enotify_method *method; const struct sieve_script_env *scriptenv; const struct sieve_message_data *msgdata; struct sieve_message_context *msgctx; struct sieve_error_handler *ehandler; const char *location; struct event *event; }; struct event_passthrough * sieve_enotify_create_finish_event(const struct sieve_enotify_exec_env *nenv); /* * Notify action */ struct sieve_enotify_action { const struct sieve_enotify_method *method; void *method_context; sieve_number_t importance; const char *message; const char *from; }; /* * Error handling */ #define sieve_enotify_error(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_ERROR, (ENV)->location, 0, __VA_ARGS__ ) #define sieve_enotify_warning(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_WARNING, \ (ENV)->location, 0, __VA_ARGS__ ) #define sieve_enotify_info(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_INFO, \ (ENV)->location, 0, __VA_ARGS__ ) #define sieve_enotify_critical(ENV, ...) \ sieve_critical((ENV)->svinst, (ENV)->ehandler, NULL, __VA_ARGS__ ) #define sieve_enotify_global_error(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_ERROR, (ENV)->location, \ SIEVE_ERROR_FLAG_GLOBAL, __VA_ARGS__ ) #define sieve_enotify_global_warning(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_WARNING, (ENV)->location, \ SIEVE_ERROR_FLAG_GLOBAL, __VA_ARGS__ ) #define sieve_enotify_global_info(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_INFO, (ENV)->location, \ SIEVE_ERROR_FLAG_GLOBAL, __VA_ARGS__ ) #define sieve_enotify_event_log(ENV, EVENT, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (EVENT), \ LOG_TYPE_INFO, (ENV)->location, \ SIEVE_ERROR_FLAG_GLOBAL, __VA_ARGS__ ) #define sieve_enotify_global_log_error(ENV, ...) \ sieve_event_log((ENV)->svinst, (ENV)->ehandler, (ENV)->event, \ LOG_TYPE_ERROR, (ENV)->location, \ (SIEVE_ERROR_FLAG_GLOBAL | \ SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO), __VA_ARGS__ ) #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/0000755000175100001700000000000015100335670024706 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/ext-metadata.c0000644000175100001700000000404515100335616027433 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "sieve-interpreter.h" #include "ext-metadata-common.h" /* * Extension mboxmetadata * ----------------------------- * * Authors: Stephan Bosch * Specification: RFC 5490; Section 3 * Implementation: skeleton * Status: development * */ const struct sieve_operation_def *mboxmetadata_operations[] = { &metadata_operation, &metadataexists_operation, }; static bool ext_mboxmetadata_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def mboxmetadata_extension = { .name = "mboxmetadata", .validator_load = ext_mboxmetadata_validator_load, SIEVE_EXT_DEFINE_OPERATIONS(mboxmetadata_operations) }; static bool ext_mboxmetadata_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { sieve_validator_register_command(valdtr, ext, &metadata_test); sieve_validator_register_command(valdtr, ext, &metadataexists_test); return TRUE; } /* * Extension servermetadata * ----------------------------- * * Authors: Stephan Bosch * Specification: RFC 5490; Section 4 * Implementation: skeleton * Status: development * */ const struct sieve_operation_def *servermetadata_operations[] = { &servermetadata_operation, &servermetadataexists_operation, }; static bool ext_servermetadata_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def servermetadata_extension = { .name = "servermetadata", .validator_load = ext_servermetadata_validator_load, SIEVE_EXT_DEFINE_OPERATIONS(servermetadata_operations) }; static bool ext_servermetadata_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { sieve_validator_register_command(valdtr, ext, &servermetadata_test); sieve_validator_register_command(valdtr, ext, &servermetadataexists_test); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/Makefile.am0000644000175100001700000000064315100335616026745 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_metadata.la libsieve_ext_metadata_la_LDFLAGS = -module -avoid-version AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_STORAGE_INCLUDE) tests = \ tst-metadata.c \ tst-metadataexists.c extensions = \ ext-metadata.c libsieve_ext_metadata_la_SOURCES = \ $(tests) \ $(extensions) noinst_HEADERS = \ ext-metadata-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/tst-metadataexists.c0000644000175100001700000002511415100335616030705 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "mail-storage.h" #include "mail-namespace.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-metadata-common.h" /* * Command definitions */ /* Forward declarations */ static bool tst_metadataexists_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_metadataexists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); /* Metadataexists command * * Syntax: * metadataexists */ static bool tst_metadataexists_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_metadataexists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def metadataexists_test = { .identifier = "metadataexists", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_metadataexists_validate, .generate = tst_metadataexists_generate, }; /* Servermetadataexists command * * Syntax: * servermetadataexists */ const struct sieve_command_def servermetadataexists_test = { .identifier = "servermetadataexists", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = tst_metadataexists_validate, .generate = tst_metadataexists_generate, }; /* * Opcode definitions */ static bool tst_metadataexists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_metadataexists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); /* Metadata operation */ const struct sieve_operation_def metadataexists_operation = { .mnemonic = "METADATAEXISTS", .ext_def = &mboxmetadata_extension, .code = EXT_METADATA_OPERATION_METADATAEXISTS, .dump = tst_metadataexists_operation_dump, .execute = tst_metadataexists_operation_execute, }; /* Mailboxexists operation */ const struct sieve_operation_def servermetadataexists_operation = { .mnemonic = "SERVERMETADATAEXISTS", .ext_def = &servermetadata_extension, .code = EXT_METADATA_OPERATION_METADATAEXISTS, .dump = tst_metadataexists_operation_dump, .execute = tst_metadataexists_operation_execute, }; /* * Test validation */ struct _validate_context { struct sieve_validator *valdtr; struct sieve_command *tst; }; static int tst_metadataexists_annotation_validate(void *context, struct sieve_ast_argument *arg) { struct _validate_context *valctx = (struct _validate_context *)context; if (sieve_argument_is_string_literal(arg)) { const char *aname = sieve_ast_strlist_strc(arg); const char *error; if (!imap_metadata_verify_entry_name(aname, &error)) { sieve_argument_validate_warning( valctx->valdtr, arg, "%s test: " "specified annotation name '%s' is invalid: %s", sieve_command_identifier(valctx->tst), str_sanitize(aname, 256), sieve_error_from_external(error)); } } return 1; /* Can't check at compile time */ } static bool tst_metadataexists_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *aarg; struct _validate_context valctx; unsigned int arg_index = 1; if (sieve_command_is(tst, metadataexists_test)) { if (!sieve_validate_positional_argument(valdtr, tst, arg, "mailbox", arg_index++, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Check name validity when mailbox argument is not a variable */ if (sieve_argument_is_string_literal(arg)) { const char *mailbox = sieve_ast_argument_strc(arg); const char *error; if (!sieve_mailbox_check_name(mailbox, &error)) { sieve_argument_validate_warning( valdtr, arg, "%s test: " "invalid mailbox name '%s' specified: %s", sieve_command_identifier(tst), str_sanitize(mailbox, 256), error); } } arg = sieve_ast_argument_next(arg); } if (!sieve_validate_positional_argument(valdtr, tst, arg, "annotation-names", arg_index++, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; aarg = arg; i_zero(&valctx); valctx.valdtr = valdtr; valctx.tst = tst; return (sieve_ast_stringlist_map( &aarg, &valctx, tst_metadataexists_annotation_validate) >= 0); } /* * Test generation */ static bool tst_metadataexists_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { if (sieve_command_is(tst, metadataexists_test)) { sieve_operation_emit(cgenv->sblock, tst->ext, &metadataexists_operation); } else if (sieve_command_is(tst, servermetadataexists_test)) { sieve_operation_emit(cgenv->sblock, tst->ext, &servermetadataexists_operation); } else { i_unreached(); } /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_metadataexists_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { bool metadata = sieve_operation_is(denv->oprtn, metadataexists_operation); if (metadata) sieve_code_dumpf(denv, "METADATAEXISTS"); else sieve_code_dumpf(denv, "SERVERMETADATAEXISTS"); sieve_code_descend(denv); if (metadata && !sieve_opr_string_dump(denv, address, "mailbox")) return FALSE; return sieve_opr_stringlist_dump(denv, address, "annotation-names"); } /* * Code execution */ static int tst_metadataexists_check_annotation(const struct sieve_runtime_env *renv, struct imap_metadata_transaction *imtrans, const char *mailbox, const char *aname, bool *all_exist_r) { struct mail_attribute_value avalue; const char *error; int ret; if (!imap_metadata_verify_entry_name(aname, &error)) { sieve_runtime_warning( renv, NULL, "%s test: " "specified annotation name '%s' is invalid: %s", (mailbox != NULL ? "metadataexists" : "servermetadataexists"), str_sanitize(aname, 256), sieve_error_from_external(error)); *all_exist_r = FALSE; return SIEVE_EXEC_OK; } ret = imap_metadata_get(imtrans, aname, &avalue); if (ret < 0) { enum mail_error error_code; const char *error; error = imap_metadata_transaction_get_last_error( imtrans, &error_code); sieve_runtime_error( renv, NULL, "%s test: " "failed to retrieve annotation '%s': %s%s", (mailbox != NULL ? "metadataexists" : "servermetadataexists"), str_sanitize(aname, 256), sieve_error_from_external(error), (error_code == MAIL_ERROR_TEMP ? " (temporary failure)" : "")); *all_exist_r = FALSE; return (error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } if (avalue.value == NULL && avalue.value_stream == NULL) { sieve_runtime_trace(renv, 0, "annotation '%s': not found", aname); *all_exist_r = FALSE; } sieve_runtime_trace(renv, 0, "annotation '%s': found", aname); return SIEVE_EXEC_OK; } static int tst_metadataexists_check_annotations(const struct sieve_runtime_env *renv, const char *mailbox, struct sieve_stringlist *anames, bool *all_exist_r) { const struct sieve_execute_env *eenv = renv->exec_env; struct mail_user *user = eenv->scriptenv->user; struct mailbox *box = NULL; struct imap_metadata_transaction *imtrans; string_t *aname; bool all_exist = TRUE; int ret, sret, status; *all_exist_r = FALSE; if (user == NULL) return SIEVE_EXEC_OK; if (mailbox != NULL) { struct mail_namespace *ns; ns = mail_namespace_find(user->namespaces, mailbox); box = mailbox_alloc(ns->list, mailbox, 0); imtrans = imap_metadata_transaction_begin(box); } else { imtrans = imap_metadata_transaction_begin_server(user); } if (mailbox != NULL) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "checking annotations of mailbox '%s':", str_sanitize(mailbox, 80)); } else { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "checking server annotations"); } aname = NULL; status = SIEVE_EXEC_OK; while (all_exist && (sret = sieve_stringlist_next_item(anames, &aname)) > 0) { ret = tst_metadataexists_check_annotation( renv, imtrans, mailbox, str_c(aname), &all_exist); if (ret <= 0) { status = ret; break; } } if (sret < 0) { sieve_runtime_trace_error( renv, "invalid annotation name stringlist item"); status = SIEVE_EXEC_BIN_CORRUPT; } (void)imap_metadata_transaction_commit(&imtrans, NULL, NULL); if (box != NULL) mailbox_free(&box); *all_exist_r = all_exist; return status; } static int tst_metadataexists_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool metadata = sieve_operation_is(renv->oprtn, metadataexists_operation); struct sieve_stringlist *anames; string_t *mailbox; bool trace = FALSE, all_exist = TRUE; const char *error; int ret; /* * Read operands */ /* Read mailbox */ if (metadata) { ret = sieve_opr_string_read(renv, address, "mailbox", &mailbox); if (ret <= 0) return ret; } /* Read annotation names */ ret = sieve_opr_stringlist_read(renv, address, "annotation-names", &anames); if (ret <= 0) return ret; /* * Perform operation */ if (metadata && !sieve_mailbox_check_name(str_c(mailbox), &error)) { sieve_runtime_warning( renv, NULL, "metadataexists test: " "invalid mailbox name '%s' specified: %s", str_sanitize(str_c(mailbox), 256), error); sieve_interpreter_set_test_result(renv->interp, FALSE); return SIEVE_EXEC_OK; } if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS)) { if (metadata) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "metadataexists test"); } else { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "servermetadataexists test"); } sieve_runtime_trace_descend(renv); trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); } ret = tst_metadataexists_check_annotations( renv, (metadata ? str_c(mailbox) : NULL), anames, &all_exist); if (ret <= 0) return ret; if (trace) { if (all_exist) { sieve_runtime_trace(renv, 0, "all annotations exist"); } else { sieve_runtime_trace(renv, 0, "some annotations do not exist"); } } sieve_interpreter_set_test_result(renv->interp, all_exist); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/Makefile.in0000644000175100001700000005530315100335630026755 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/metadata ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_metadata_la_LIBADD = am__objects_1 = tst-metadata.lo tst-metadataexists.lo am__objects_2 = ext-metadata.lo am_libsieve_ext_metadata_la_OBJECTS = $(am__objects_1) \ $(am__objects_2) libsieve_ext_metadata_la_OBJECTS = \ $(am_libsieve_ext_metadata_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libsieve_ext_metadata_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsieve_ext_metadata_la_LDFLAGS) \ $(LDFLAGS) -o $@ 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-metadata.Plo \ ./$(DEPDIR)/tst-metadata.Plo \ ./$(DEPDIR)/tst-metadataexists.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_metadata_la_SOURCES) DIST_SOURCES = $(libsieve_ext_metadata_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_metadata.la libsieve_ext_metadata_la_LDFLAGS = -module -avoid-version AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_STORAGE_INCLUDE) tests = \ tst-metadata.c \ tst-metadataexists.c extensions = \ ext-metadata.c libsieve_ext_metadata_la_SOURCES = \ $(tests) \ $(extensions) noinst_HEADERS = \ ext-metadata-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/metadata/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/metadata/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_metadata.la: $(libsieve_ext_metadata_la_OBJECTS) $(libsieve_ext_metadata_la_DEPENDENCIES) $(EXTRA_libsieve_ext_metadata_la_DEPENDENCIES) $(AM_V_CCLD)$(libsieve_ext_metadata_la_LINK) $(libsieve_ext_metadata_la_OBJECTS) $(libsieve_ext_metadata_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-metadata.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-metadata.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-metadataexists.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-metadata.Plo -rm -f ./$(DEPDIR)/tst-metadata.Plo -rm -f ./$(DEPDIR)/tst-metadataexists.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-metadata.Plo -rm -f ./$(DEPDIR)/tst-metadata.Plo -rm -f ./$(DEPDIR)/tst-metadataexists.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/ext-metadata-common.h0000644000175100001700000000170615100335616030727 0ustar00buildbotbuildbot00000000000000#ifndef EXT_METADATA_COMMON_H #define EXT_METADATA_COMMON_H #include "lib.h" #include "mail-storage.h" #include "imap-metadata.h" #include "sieve-common.h" /* * Extension */ extern const struct sieve_extension_def mboxmetadata_extension; extern const struct sieve_extension_def servermetadata_extension; /* * Commands */ extern const struct sieve_command_def metadata_test; extern const struct sieve_command_def servermetadata_test; extern const struct sieve_command_def metadataexists_test; extern const struct sieve_command_def servermetadataexists_test; /* * Operations */ enum ext_metadata_opcode { EXT_METADATA_OPERATION_METADATA, EXT_METADATA_OPERATION_METADATAEXISTS }; extern const struct sieve_operation_def metadata_operation; extern const struct sieve_operation_def servermetadata_operation; extern const struct sieve_operation_def metadataexists_operation; extern const struct sieve_operation_def servermetadataexists_operation; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/metadata/tst-metadata.c0000644000175100001700000002567415100335616027460 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "istream.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-metadata-common.h" #define TST_METADATA_MAX_MATCH_SIZE SIEVE_MAX_STRING_LEN /* * Test definitions */ /* Forward declarations */ static bool tst_metadata_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_metadata_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_metadata_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); /* Metadata test * * Syntax: * metadata [MATCH-TYPE] [COMPARATOR] * * */ const struct sieve_command_def metadata_test = { .identifier = "metadata", .type = SCT_TEST, .positional_args = 3, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_metadata_registered, .validate = tst_metadata_validate, .generate = tst_metadata_generate, }; /* Servermetadata test * * Syntax: * servermetadata [MATCH-TYPE] [COMPARATOR] * */ const struct sieve_command_def servermetadata_test = { .identifier = "servermetadata", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_metadata_registered, .validate = tst_metadata_validate, .generate = tst_metadata_generate, }; /* * Opcode definitions */ static bool tst_metadata_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_metadata_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); /* Metadata operation */ const struct sieve_operation_def metadata_operation = { .mnemonic = "METADATA", .ext_def = &mboxmetadata_extension, .code = EXT_METADATA_OPERATION_METADATA, .dump = tst_metadata_operation_dump, .execute = tst_metadata_operation_execute, }; /* Servermetadata operation */ const struct sieve_operation_def servermetadata_operation = { .mnemonic = "SERVERMETADATA", .ext_def = &servermetadata_extension, .code = EXT_METADATA_OPERATION_METADATA, .dump = tst_metadata_operation_dump, .execute = tst_metadata_operation_execute, }; /* * Test registration */ static bool tst_metadata_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); return TRUE; } /* * Test validation */ static bool tst_metadata_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); unsigned int arg_index = 1; const char *error; /* mailbox */ if (sieve_command_is(tst, metadata_test)) { if (!sieve_validate_positional_argument( valdtr, tst, arg, "mailbox", arg_index++, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Check name validity when mailbox argument is not a variable */ if (sieve_argument_is_string_literal(arg)) { const char *mailbox = sieve_ast_argument_strc(arg); const char *error; if (!sieve_mailbox_check_name(mailbox, &error)) { sieve_argument_validate_warning( valdtr, arg, "%s test: " "invalid mailbox name '%s' specified: %s", sieve_command_identifier(tst), str_sanitize(mailbox, 256), error); } } arg = sieve_ast_argument_next(arg); } /* annotation-name */ if (!sieve_validate_positional_argument(valdtr, tst, arg, "annotation-name", arg_index++, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; if (sieve_argument_is_string_literal(arg)) { string_t *aname = sieve_ast_argument_str(arg); if (!imap_metadata_verify_entry_name(str_c(aname), &error)) { sieve_argument_validate_warning( valdtr, arg, "%s test: " "specified annotation name '%s' is invalid: %s", sieve_command_identifier(tst), str_sanitize(str_c(aname), 256), sieve_error_from_external(error)); } } arg = sieve_ast_argument_next(arg); /* key-list */ if (!sieve_validate_positional_argument(valdtr, tst, arg, "key-list", arg_index++, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Test generation */ static bool tst_metadata_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { if (sieve_command_is(tst, metadata_test)) { sieve_operation_emit(cgenv->sblock, tst->ext, &metadata_operation); } else if (sieve_command_is(tst, servermetadata_test)) { sieve_operation_emit(cgenv->sblock, tst->ext, &servermetadata_operation); } else { i_unreached(); } /* Generate arguments */ if (!sieve_generate_arguments(cgenv, tst, NULL)) return FALSE; return TRUE; } /* * Code dump */ static bool tst_metadata_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { bool metadata = sieve_operation_is(denv->oprtn, metadata_operation); if (metadata) sieve_code_dumpf(denv, "METADATA"); else sieve_code_dumpf(denv, "SERVERMETADATA"); sieve_code_descend(denv); /* Handle any optional arguments */ if (sieve_match_opr_optional_dump(denv, address, NULL) != 0) return FALSE; if (metadata && !sieve_opr_string_dump(denv, address, "mailbox")) return FALSE; return (sieve_opr_string_dump(denv, address, "annotation-name") && sieve_opr_stringlist_dump(denv, address, "key list")); } /* * Code execution */ static int tst_metadata_get_annotation(const struct sieve_runtime_env *renv, const char *mailbox, const char *aname, const char **annotation_r) { const struct sieve_execute_env *eenv = renv->exec_env; struct mail_user *user = eenv->scriptenv->user; struct mailbox *box; struct imap_metadata_transaction *imtrans; struct mail_attribute_value avalue; int status, ret; *annotation_r = NULL; if (user == NULL) return SIEVE_EXEC_OK; if (mailbox != NULL) { struct mail_namespace *ns; ns = mail_namespace_find(user->namespaces, mailbox); box = mailbox_alloc(ns->list, mailbox, 0); imtrans = imap_metadata_transaction_begin(box); } else { box = NULL; imtrans = imap_metadata_transaction_begin_server(user); } status = SIEVE_EXEC_OK; ret = imap_metadata_get(imtrans, aname, &avalue); if (ret < 0) { enum mail_error error_code; const char *error; error = imap_metadata_transaction_get_last_error( imtrans, &error_code); sieve_runtime_error( renv, NULL, "%s test: " "failed to retrieve annotation '%s': %s%s", (mailbox != NULL ? "metadata" : "servermetadata"), str_sanitize(aname, 256), sieve_error_from_external(error), (error_code == MAIL_ERROR_TEMP ? " (temporary failure)" : "")); status = (error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE); } else if (avalue.value != NULL) { *annotation_r = avalue.value; } (void)imap_metadata_transaction_commit(&imtrans, NULL, NULL); if (box != NULL) mailbox_free(&box); return status; } static int tst_metadata_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool metadata = sieve_operation_is(renv->oprtn, metadata_operation); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); string_t *mailbox, *aname; struct sieve_stringlist *value_list, *key_list; const char *annotation = NULL, *error; int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ if (sieve_match_opr_optional_read(renv, address, NULL, &ret, &cmp, &mcht) < 0) return ret; /* Read mailbox */ if (metadata) { ret = sieve_opr_string_read(renv, address, "mailbox", &mailbox); if (ret <= 0) return ret; } /* Read annotation-name */ ret = sieve_opr_string_read(renv, address, "annotation-name", &aname); if (ret <= 0) return ret; /* Read key-list */ ret = sieve_opr_stringlist_read(renv, address, "key-list", &key_list); if (ret <= 0) return ret; /* * Perform operation */ if (metadata) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "metadata test"); } else { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "servermetadata test"); } sieve_runtime_trace_descend(renv); if (!imap_metadata_verify_entry_name(str_c(aname), &error)) { sieve_runtime_warning( renv, NULL, "%s test: " "specified annotation name '%s' is invalid: %s", (metadata ? "metadata" : "servermetadata"), str_sanitize(str_c(aname), 256), sieve_error_from_external(error)); sieve_interpreter_set_test_result(renv->interp, FALSE); return SIEVE_EXEC_OK; } if (metadata) { if (!sieve_mailbox_check_name(str_c(mailbox), &error)) { sieve_runtime_warning( renv, NULL, "metadata test: " "invalid mailbox name '%s' specified: %s", str_sanitize(str_c(mailbox), 256), error); sieve_interpreter_set_test_result(renv->interp, FALSE); return SIEVE_EXEC_OK; } sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "retrieving annotation '%s' from mailbox '%s'", str_sanitize(str_c(aname), 256), str_sanitize(str_c(mailbox), 80)); } else { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "retrieving server annotation '%s'", str_sanitize(str_c(aname), 256)); } /* Get annotation */ ret = tst_metadata_get_annotation(renv, (metadata ? str_c(mailbox) : NULL), str_c(aname), &annotation); if (ret == SIEVE_EXEC_OK) { /* Perform match */ if (annotation != NULL) { /* Create value stringlist */ value_list = sieve_single_stringlist_create_cstr( renv, annotation, FALSE); /* Perform match */ match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret); if (ret < 0) return ret; } else { match = 0; } } /* Set test result for subsequent conditional jump */ if (ret == SIEVE_EXEC_OK) sieve_interpreter_set_test_result(renv->interp, match > 0); return ret; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/0000755000175100001700000000000015100335670025472 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/tst-environment.c0000644000175100001700000001264715100335616031024 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-environment-common.h" /* * Environment test * * Syntax: * environment [COMPARATOR] [MATCH-TYPE] * */ static bool tst_environment_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_environment_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_environment_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def tst_environment = { .identifier = "environment", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_environment_registered, .validate = tst_environment_validate, .generate = tst_environment_generate, }; /* * Environment operation */ static bool tst_environment_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_environment_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_environment_operation = { .mnemonic = "ENVIRONMENT", .ext_def = &environment_extension, .dump = tst_environment_operation_dump, .execute = tst_environment_operation_execute, }; /* * Test registration */ static bool tst_environment_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); return TRUE; } /* * Test validation */ static bool tst_environment_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if (!sieve_validate_positional_argument(valdtr, tst, arg, "name", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; arg = sieve_ast_argument_next(arg); if (!sieve_validate_positional_argument(valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Test generation */ static bool tst_environment_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &tst_environment_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool tst_environment_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "ENVIRONMENT"); sieve_code_descend(denv); /* Optional operands */ if (sieve_match_opr_optional_dump(denv, address, NULL) != 0) return FALSE; return (sieve_opr_string_dump(denv, address, "name") && sieve_opr_stringlist_dump(denv, address, "key list")); } /* * Code execution */ static int tst_environment_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); string_t *name; struct sieve_stringlist *value_list, *key_list; const char *env_item; int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ if (sieve_match_opr_optional_read(renv, address, NULL, &ret, &cmp, &mcht) < 0) return ret; /* Read source */ ret = sieve_opr_string_read(renv, address, "name", &name); if (ret <= 0) return ret; /* Read key-list */ ret = sieve_opr_stringlist_read(renv, address, "key-list", &key_list); if (ret <= 0) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "environment test"); env_item = ext_environment_item_get_value(this_ext, renv, str_c(name)); if (env_item != NULL) { /* Construct value list */ value_list = sieve_single_stringlist_create_cstr( renv, env_item, FALSE); /* Perform match */ match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret); if (ret < 0) return ret; } else { match = 0; sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "environment item '%s' not found", str_sanitize(str_c(name), 128)); } /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/Makefile.am0000644000175100001700000000066615100335616027536 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_environment.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-environment.c libsieve_ext_environment_la_SOURCES = \ $(tests) \ ext-environment-common.c \ ext-environment.c public_headers = \ sieve-ext-environment.h headers = \ ext-environment-common.h pkginc_libdir=$(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/sieve-ext-environment.h0000644000175100001700000000307515100335616032123 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_EXT_ENVIRONMENT_H #define SIEVE_EXT_ENVIRONMENT_H #include "sieve-common.h" /* * Environment extension */ /* FIXME: this is not suitable for future plugin support */ extern const struct sieve_extension_def environment_extension; static inline int sieve_ext_environment_get_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_register(svinst, &environment_extension, FALSE, ext_r); } static inline int sieve_ext_environment_require_extension(struct sieve_instance *svinst, const struct sieve_extension **ext_r) { return sieve_extension_require(svinst, &environment_extension, TRUE, ext_r); } bool sieve_ext_environment_is_active(const struct sieve_extension *env_ext, struct sieve_interpreter *interp); /* * Environment item */ struct sieve_environment_item; struct sieve_environment_item_def { const char *name; bool prefix; const char *value; const char *(*get_value)(const struct sieve_runtime_env *renv, const struct sieve_environment_item *item, const char *name); }; struct sieve_environment_item { const struct sieve_environment_item_def *def; const struct sieve_extension *ext; }; void sieve_environment_item_register( const struct sieve_extension *env_ext, struct sieve_interpreter *interp, const struct sieve_extension *ext, const struct sieve_environment_item_def *item_def); const char * ext_environment_item_get_value(const struct sieve_extension *env_ext, const struct sieve_runtime_env *renv, const char *name); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/Makefile.in0000644000175100001700000006152515100335630027544 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/environment ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(pkginc_lib_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_environment_la_LIBADD = am__objects_1 = tst-environment.lo am_libsieve_ext_environment_la_OBJECTS = $(am__objects_1) \ ext-environment-common.lo ext-environment.lo libsieve_ext_environment_la_OBJECTS = \ $(am_libsieve_ext_environment_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-environment-common.Plo \ ./$(DEPDIR)/ext-environment.Plo \ ./$(DEPDIR)/tst-environment.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_environment_la_SOURCES) DIST_SOURCES = $(libsieve_ext_environment_la_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; }; \ } am__installdirs = "$(DESTDIR)$(pkginc_libdir)" HEADERS = $(noinst_HEADERS) $(pkginc_lib_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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_environment.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-environment.c libsieve_ext_environment_la_SOURCES = \ $(tests) \ ext-environment-common.c \ ext-environment.c public_headers = \ sieve-ext-environment.h headers = \ ext-environment-common.h pkginc_libdir = $(dovecot_pkgincludedir)/sieve pkginc_lib_HEADERS = $(public_headers) noinst_HEADERS = $(headers) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/environment/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/environment/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_environment.la: $(libsieve_ext_environment_la_OBJECTS) $(libsieve_ext_environment_la_DEPENDENCIES) $(EXTRA_libsieve_ext_environment_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_environment_la_OBJECTS) $(libsieve_ext_environment_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-environment-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-environment.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-environment.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || 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_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ done uninstall-pkginc_libHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginc_libdir)'; $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-environment-common.Plo -rm -f ./$(DEPDIR)/ext-environment.Plo -rm -f ./$(DEPDIR)/tst-environment.Plo -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-pkginc_libHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-environment-common.Plo -rm -f ./$(DEPDIR)/ext-environment.Plo -rm -f ./$(DEPDIR)/tst-environment.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkginc_libHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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-pkginc_libHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkginc_libHEADERS .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/ext-environment.c0000644000175100001700000000262215100335616031002 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension variables * ------------------- * * Authors: Stephan Bosch * Specification: RFC 5183 * Implementation: full * Status: testing * */ #include "lib.h" #include "str.h" #include "unichar.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-validator.h" #include "ext-environment-common.h" /* * Extension */ static bool ext_environment_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_environment_interpreter_load (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_extension_def environment_extension = { .name = "environment", .validator_load = ext_environment_validator_load, .interpreter_load = ext_environment_interpreter_load, SIEVE_EXT_DEFINE_OPERATION(tst_environment_operation) }; static bool ext_environment_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { sieve_validator_register_command(valdtr, ext, &tst_environment); return TRUE; } static bool ext_environment_interpreter_load (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { ext_environment_interpreter_init(ext, renv->interp); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/ext-environment-common.c0000644000175100001700000002223015100335616032265 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "hash.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-interpreter.h" #include "ext-environment-common.h" struct ext_environment_interpreter_context; /* * Core environment items */ static const struct sieve_environment_item_def *core_env_items[] = { &domain_env_item, &host_env_item, &location_env_item, &phase_env_item, &name_env_item, &version_env_item, }; static unsigned int core_env_items_count = N_ELEMENTS(core_env_items); static void sieve_environment_item_insert( struct ext_environment_interpreter_context *ctx, struct sieve_interpreter *interp, const struct sieve_extension *ext, const struct sieve_environment_item_def *item_def); /* * Validator context */ struct ext_environment_interpreter_context { HASH_TABLE(const char *, const struct sieve_environment_item *) name_items; ARRAY(const struct sieve_environment_item *) prefix_items; bool active:1; }; static void ext_environment_interpreter_extension_free(const struct sieve_extension *ext, struct sieve_interpreter *interp, void *context); struct sieve_interpreter_extension environment_interpreter_extension = { .ext_def = &environment_extension, .free = ext_environment_interpreter_extension_free, }; static struct ext_environment_interpreter_context * ext_environment_interpreter_context_create( const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { pool_t pool = sieve_interpreter_pool(interp); struct ext_environment_interpreter_context *ctx; ctx = p_new(pool, struct ext_environment_interpreter_context, 1); hash_table_create(&ctx->name_items, default_pool, 0, str_hash, strcmp); i_array_init(&ctx->prefix_items, 16); sieve_interpreter_extension_register(interp, this_ext, &environment_interpreter_extension, ctx); return ctx; } static void ext_environment_interpreter_extension_free( const struct sieve_extension *ext ATTR_UNUSED, struct sieve_interpreter *interp ATTR_UNUSED, void *context) { struct ext_environment_interpreter_context *ctx = (struct ext_environment_interpreter_context *)context; hash_table_destroy(&ctx->name_items); array_free(&ctx->prefix_items); } static struct ext_environment_interpreter_context * ext_environment_interpreter_context_get(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_environment_interpreter_context *ctx = (struct ext_environment_interpreter_context *) sieve_interpreter_extension_get_context(interp, this_ext); if (ctx == NULL) { ctx = ext_environment_interpreter_context_create( this_ext, interp); } return ctx; } void ext_environment_interpreter_init(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_environment_interpreter_context *ctx; unsigned int i; /* Create our context */ ctx = ext_environment_interpreter_context_get(this_ext, interp); for (i = 0; i < core_env_items_count; i++) { sieve_environment_item_insert(ctx, interp, this_ext, core_env_items[i]); } ctx->active = TRUE; } bool sieve_ext_environment_is_active(const struct sieve_extension *env_ext, struct sieve_interpreter *interp) { struct ext_environment_interpreter_context *ctx = ext_environment_interpreter_context_get(env_ext, interp); return (ctx != NULL && ctx->active); } /* * Registration */ static void sieve_environment_item_insert( struct ext_environment_interpreter_context *ctx, struct sieve_interpreter *interp, const struct sieve_extension *ext, const struct sieve_environment_item_def *item_def) { pool_t pool = sieve_interpreter_pool(interp); struct sieve_environment_item *item_mod; item_mod = p_new(pool, struct sieve_environment_item, 1); item_mod->def = item_def; item_mod->ext = ext; const struct sieve_environment_item *item = item_mod; if (!item_def->prefix) hash_table_insert(ctx->name_items, item_def->name, item); else array_append(&ctx->prefix_items, &item, 1); } void sieve_environment_item_register( const struct sieve_extension *env_ext, struct sieve_interpreter *interp, const struct sieve_extension *ext, const struct sieve_environment_item_def *item_def) { struct ext_environment_interpreter_context *ctx; i_assert(sieve_extension_is(env_ext, environment_extension)); ctx = ext_environment_interpreter_context_get(env_ext, interp); sieve_environment_item_insert(ctx, interp, ext, item_def); } /* * Retrieval */ static const struct sieve_environment_item * ext_environment_item_lookup(struct ext_environment_interpreter_context *ctx, const char **_name) { const struct sieve_environment_item *item; const char *suffix, *name = *_name; item = hash_table_lookup(ctx->name_items, name); if (item != NULL) return item; array_foreach_elem(&ctx->prefix_items, item) { i_assert(item->def->prefix); if (str_begins(name, item->def->name, &suffix)) { if (*suffix == '.') ++suffix; *_name = suffix; return item; } } return NULL; } const char * ext_environment_item_get_value(const struct sieve_extension *env_ext, const struct sieve_runtime_env *renv, const char *name) { struct ext_environment_interpreter_context *ctx; const struct sieve_environment_item *item; i_assert(sieve_extension_is(env_ext, environment_extension)); ctx = ext_environment_interpreter_context_get(env_ext, renv->interp); item = ext_environment_item_lookup(ctx, &name); if (item == NULL) return NULL; i_assert(item->def != NULL); if (item->def->value != NULL) return item->def->value; if (item->def->get_value != NULL) return item->def->get_value(renv, item, name); return NULL; } /* * Default environment items */ /* "domain": The primary DNS domain associated with the Sieve execution context, usually but not always a proper suffix of the host name. */ static const char * envit_domain_get_value(const struct sieve_runtime_env *renv, const struct sieve_environment_item *item ATTR_UNUSED, const char *name ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; return eenv->svinst->domainname; } const struct sieve_environment_item_def domain_env_item = { .name = "domain", .get_value = envit_domain_get_value, }; /* "host": The fully-qualified domain name of the host where the Sieve script is executing. */ static const char * envit_host_get_value(const struct sieve_runtime_env *renv, const struct sieve_environment_item *item ATTR_UNUSED, const char *name ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; return eenv->svinst->hostname; } const struct sieve_environment_item_def host_env_item = { .name = "host", .get_value = envit_host_get_value, }; /* "location": Sieve evaluation can be performed at various different points as messages are processed. This item provides additional information about the type of service that is evaluating the script. Possible values are: "MTA" - the Sieve script is being evaluated by a Message Transfer Agent "MDA" - evaluation is being performed by a Mail Delivery Agent "MUA" - evaluation is being performed by a Mail User Agent (right...) "MS" - evaluation is being performed by a Message Store */ static const char * envit_location_get_value(const struct sieve_runtime_env *renv, const struct sieve_environment_item *item ATTR_UNUSED, const char *name ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; switch (eenv->svinst->env_location ) { case SIEVE_ENV_LOCATION_MDA: return "MDA"; case SIEVE_ENV_LOCATION_MTA: return "MTA"; case SIEVE_ENV_LOCATION_MS: return "MS"; default: break; } return NULL; } const struct sieve_environment_item_def location_env_item = { .name = "location", .get_value = envit_location_get_value }; /* "phase": The point relative to final delivery where the Sieve script is being evaluated. Possible values are "pre", "during", and "post", referring respectively to processing before, during, and after final delivery has taken place. */ static const char * envit_phase_get_value(const struct sieve_runtime_env *renv, const struct sieve_environment_item *item ATTR_UNUSED, const char *name ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; switch (eenv->svinst->delivery_phase) { case SIEVE_DELIVERY_PHASE_PRE: return "pre"; case SIEVE_DELIVERY_PHASE_DURING: return "during"; case SIEVE_DELIVERY_PHASE_POST: return "post"; default: break; } return NULL; } const struct sieve_environment_item_def phase_env_item = { .name = "phase", .get_value = envit_phase_get_value }; /* "name": The product name associated with the Sieve interpreter. */ const struct sieve_environment_item_def name_env_item = { .name = "name", .value = PIGEONHOLE_NAME" Sieve" }; /* "version": The product version associated with the Sieve interpreter. The meaning of the product version string is product-specific and should always be considered in the context of the product name given by the "name" item. */ const struct sieve_environment_item_def version_env_item = { .name = "version", .value = PIGEONHOLE_VERSION, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/environment/ext-environment-common.h0000644000175100001700000000216415100335616032276 0ustar00buildbotbuildbot00000000000000#ifndef EXT_ENVIRONMENT_COMMON_H #define EXT_ENVIRONMENT_COMMON_H #include "lib.h" #include "sieve-common.h" #include "sieve-ext-environment.h" /* * Extension */ extern const struct sieve_extension_def environment_extension; /* * Commands */ extern const struct sieve_command_def tst_environment; /* * Operations */ extern const struct sieve_operation_def tst_environment_operation; /* * Environment items */ extern const struct sieve_environment_item_def domain_env_item; extern const struct sieve_environment_item_def host_env_item; extern const struct sieve_environment_item_def location_env_item; extern const struct sieve_environment_item_def phase_env_item; extern const struct sieve_environment_item_def name_env_item; extern const struct sieve_environment_item_def version_env_item; /* * Initialization */ bool ext_environment_init(const struct sieve_extension *ext, void **context); void ext_environment_deinit(const struct sieve_extension *ext); /* * Validator context */ void ext_environment_interpreter_init(const struct sieve_extension *this_ext, struct sieve_interpreter *interp); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/0000755000175100001700000000000015100335670025357 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/debug/0000755000175100001700000000000015100335670026445 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/debug/ext-debug.c0000644000175100001700000000317315100335616030501 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension debug * --------------- * * Authors: Stephan Bosch * Specification: vendor-defined; spec-bosch-sieve-debug * Implementation: full * Status: experimental * */ #include "lib.h" #include "array.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-debug-common.h" /* * Extension */ static bool ext_debug_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); static bool ext_debug_interpreter_load (const struct sieve_extension *ext ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED); const struct sieve_extension_def vnd_debug_extension = { .name = "vnd.dovecot.debug", .validator_load = ext_debug_validator_load, .interpreter_load = ext_debug_interpreter_load, SIEVE_EXT_DEFINE_OPERATION(debug_log_operation), }; static bool ext_debug_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator) { /* Register new test */ sieve_validator_register_command(validator, ext, &debug_log_command); return TRUE; } static bool ext_debug_interpreter_load (const struct sieve_extension *ext ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { if ( renv->ehandler != NULL ) { sieve_error_handler_accept_infolog(renv->ehandler, TRUE); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/debug/Makefile.am0000644000175100001700000000036115100335616030501 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_debug.la AM_CPPFLAGS = \ -I$(srcdir)/../../.. \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-debug-log.c libsieve_ext_debug_la_SOURCES = \ $(commands) \ ext-debug.c noinst_HEADERS = \ ext-debug-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/debug/Makefile.in0000644000175100001700000005377215100335630030524 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/vnd.dovecot/debug ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_debug_la_LIBADD = am__objects_1 = cmd-debug-log.lo am_libsieve_ext_debug_la_OBJECTS = $(am__objects_1) ext-debug.lo libsieve_ext_debug_la_OBJECTS = $(am_libsieve_ext_debug_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-debug-log.Plo \ ./$(DEPDIR)/ext-debug.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_debug_la_SOURCES) DIST_SOURCES = $(libsieve_ext_debug_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_debug.la AM_CPPFLAGS = \ -I$(srcdir)/../../.. \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-debug-log.c libsieve_ext_debug_la_SOURCES = \ $(commands) \ ext-debug.c noinst_HEADERS = \ ext-debug-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/vnd.dovecot/debug/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/vnd.dovecot/debug/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_debug.la: $(libsieve_ext_debug_la_OBJECTS) $(libsieve_ext_debug_la_DEPENDENCIES) $(EXTRA_libsieve_ext_debug_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_debug_la_OBJECTS) $(libsieve_ext_debug_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-debug-log.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-debug.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-debug-log.Plo -rm -f ./$(DEPDIR)/ext-debug.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-debug-log.Plo -rm -f ./$(DEPDIR)/ext-debug.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/debug/ext-debug-common.h0000644000175100001700000000046415100335616031774 0ustar00buildbotbuildbot00000000000000#ifndef EXT_DEBUG_COMMON_H #define EXT_DEBUG_COMMON_H /* * Extensions */ extern const struct sieve_extension_def vnd_debug_extension; /* * Commands */ extern const struct sieve_command_def debug_log_command; /* * Operations */ extern const struct sieve_operation_def debug_log_operation; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/debug/cmd-debug-log.c0000644000175100001700000000536715100335616031232 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-debug-common.h" /* * Debug_log command * * Syntax * debug_log */ static bool cmd_debug_log_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool cmd_debug_log_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def debug_log_command = { .identifier = "debug_log", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_debug_log_validate, .generate = cmd_debug_log_generate }; /* * Body operation */ static bool cmd_debug_log_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_debug_log_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def debug_log_operation = { .mnemonic = "DEBUG_LOG", .ext_def = &vnd_debug_extension, .dump = cmd_debug_log_operation_dump, .execute = cmd_debug_log_operation_execute }; /* * Validation */ static bool cmd_debug_log_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if ( !sieve_validate_positional_argument (valdtr, tst, arg, "message", 1, SAAT_STRING) ) { return FALSE; } return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* * Code generation */ static bool cmd_debug_log_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &debug_log_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_debug_log_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "DEBUG_LOG"); sieve_code_descend(denv); return sieve_opr_string_dump(denv, address, "key list"); } /* * Interpretation */ static int cmd_debug_log_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *message; int ret; /* * Read operands */ /* Read message */ if ( (ret=sieve_opr_string_read(renv, address, "message", &message)) <= 0 ) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "debug_log \"%s\"", str_sanitize(str_c(message), 80)); sieve_runtime_log(renv, NULL, "DEBUG: %s", str_c(message)); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/Makefile.am0000644000175100001700000000004415100335616027411 0ustar00buildbotbuildbot00000000000000SUBDIRS = debug environment report dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/Makefile.in0000644000175100001700000005404215100335630027425 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/vnd.dovecot ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = 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 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 distdir-am 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)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in 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_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = debug environment report all: all-recursive .SUFFIXES: $(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) --foreign src/lib-sieve/plugins/vnd.dovecot/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/vnd.dovecot/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 installdirs: installdirs-recursive installdirs-am: 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 clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am 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 mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/0000755000175100001700000000000015100335670027723 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/Makefile.am0000644000175100001700000000066215100335616031763 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_vnd_environment.la AM_CPPFLAGS = \ -I$(srcdir)/../../.. \ -I$(srcdir)/../../environment \ -I$(srcdir)/../../variables \ $(LIBDOVECOT_INCLUDE) libsieve_ext_vnd_environment_la_SOURCES = \ ext-vnd-environment-settings.c \ ext-vnd-environment-items.c \ ext-vnd-environment-variables.c \ ext-vnd-environment.c noinst_HEADERS = \ ext-vnd-environment-settings.h \ ext-vnd-environment-common.h ext-vnd-environment-settings.h0000644000175100001700000000040115100335616035575 0ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment#ifndef EXT_VND_ENVIRONMENT_SETTINGS_H #define EXT_VND_ENVIRONMENT_SETTINGS_H struct ext_vnd_environment_settings { pool_t pool; ARRAY_TYPE(const_string) envs; }; extern const struct setting_parser_info ext_vnd_environment_setting_parser_info; #endif ext-vnd-environment-variables.c0000644000175100001700000001411015100335616035702 0ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/* Copyright (c) 2015-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-vnd-environment-common.h" static bool vnspc_vnd_environment_validate(struct sieve_validator *valdtr, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, bool assignment); static bool vnspc_vnd_environment_generate(const struct sieve_codegen_env *cgenv, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd, void *var_data); static bool vnspc_vnd_environment_dump_variable( const struct sieve_dumptime_env *denv, const struct sieve_variables_namespace *nspc, const struct sieve_operand *oprnd, sieve_size_t *address); static int vnspc_vnd_environment_read_variable( const struct sieve_runtime_env *renv, const struct sieve_variables_namespace *nspc, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); static const struct sieve_variables_namespace_def environment_namespace = { SIEVE_OBJECT("env", &environment_namespace_operand, 0), .validate = vnspc_vnd_environment_validate, .generate = vnspc_vnd_environment_generate, .dump_variable = vnspc_vnd_environment_dump_variable, .read_variable = vnspc_vnd_environment_read_variable, }; static bool vnspc_vnd_environment_validate( struct sieve_validator *valdtr, const struct sieve_variables_namespace *nspc ATTR_UNUSED, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED, ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, bool assignment) { struct sieve_ast *ast = arg->ast; const struct sieve_variable_name *name_elements; unsigned int i, count; const char *variable; string_t *name; /* Compose environment name from parsed variable name */ name = t_str_new(64); name_elements = array_get(var_name, &count); i_assert(count > 1); for (i = 1; i < count; i++) { if (name_elements[i].num_variable >= 0) { sieve_argument_validate_error( valdtr, arg, "vnd.dovecot.environment: " "invalid variable name within env namespace 'env.%d': " "encountered numeric variable name", name_elements[i].num_variable); return FALSE; } if (str_len(name) > 0) str_append_c(name, '.'); str_append_str(name, name_elements[i].identifier); } variable = str_c(name); if (assignment) { sieve_argument_validate_error( valdtr, arg, "vnd.dovecot.environment: " "cannot assign to environment variable 'env.%s'", variable); return FALSE; } *var_data = p_strdup(sieve_ast_pool(ast), variable); return TRUE; } static bool vnspc_vnd_environment_generate(const struct sieve_codegen_env *cgenv, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg ATTR_UNUSED, struct sieve_command *cmd ATTR_UNUSED, void *var_data) { const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); const char *variable = (const char *) var_data; struct ext_vnd_environment_context *extctx; if (this_ext == NULL) return FALSE; extctx = (struct ext_vnd_environment_context *)this_ext->context; sieve_variables_opr_namespace_variable_emit( cgenv->sblock, extctx->var_ext, this_ext, &environment_namespace); sieve_binary_emit_cstring(cgenv->sblock, variable); return TRUE; } static bool vnspc_vnd_environment_dump_variable( const struct sieve_dumptime_env *denv, const struct sieve_variables_namespace *nspc ATTR_UNUSED, const struct sieve_operand *oprnd, sieve_size_t *address) { string_t *var_name; if (!sieve_binary_read_string(denv->sblock, address, &var_name)) return FALSE; if (oprnd->field_name != NULL) { sieve_code_dumpf(denv, "%s: VAR ${env.%s}", oprnd->field_name, str_c(var_name)); } else { sieve_code_dumpf(denv, "VAR ${env.%s}", str_c(var_name)); } return TRUE; } static int vnspc_vnd_environment_read_variable( const struct sieve_runtime_env *renv, const struct sieve_variables_namespace *nspc, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r) { const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); struct ext_vnd_environment_context *extctx = this_ext->context; string_t *var_name; const char *ext_value; if (!sieve_binary_read_string(renv->sblock, address, &var_name)) { sieve_runtime_trace_operand_error( renv, oprnd, "environment variable operand corrupt: " "invalid name"); return SIEVE_EXEC_BIN_CORRUPT; } if (str_r != NULL) { const char *vname = str_c(var_name); ext_value = ext_environment_item_get_value(extctx->env_ext, renv, vname); if (ext_value == NULL && strchr(vname, '_') != NULL) { char *p, *aname; /* Try again with '_' replaced with '-' */ aname = t_strdup_noconst(vname); for (p = aname; *p != '\0'; p++) { if (*p == '_') *p = '-'; } ext_value = ext_environment_item_get_value( extctx->env_ext, renv, aname); } if (ext_value == NULL) { *str_r = t_str_new_const("", 0); return SIEVE_EXEC_OK; } *str_r = t_str_new_const(ext_value, strlen(ext_value)); } return SIEVE_EXEC_OK; } /* * Namespace registration */ static const struct sieve_extension_objects environment_namespaces = SIEVE_VARIABLES_DEFINE_NAMESPACE(environment_namespace); const struct sieve_operand_def environment_namespace_operand = { .name = "env-namespace", .ext_def = &vnd_environment_extension, .class = &sieve_variables_namespace_operand_class, .interface = &environment_namespaces, }; void ext_environment_variables_init(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_vnd_environment_context *extctx = this_ext->context; sieve_variables_namespace_register(extctx->var_ext, valdtr, this_ext, &environment_namespace); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c0000644000175100001700000000635615100335616034030 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension vnd.dovecot.environment * --------------------------------- * * Authors: Stephan Bosch * Specification: vendor-defined; * spec-bosch-sieve-dovecot-environment * Implementation: preliminary * Status: experimental * */ #include "lib.h" #include "array.h" #include "settings.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-vnd-environment-common.h" /* * Extension */ static int ext_vnd_environment_load(const struct sieve_extension *ext, void **context_r); static void ext_vnd_environment_unload(const struct sieve_extension *ext); static bool ext_vnd_environment_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_vnd_environment_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_extension_def vnd_environment_extension = { .name = "vnd.dovecot.environment", .load = ext_vnd_environment_load, .unload = ext_vnd_environment_unload, .validator_load = ext_vnd_environment_validator_load, .interpreter_load = ext_vnd_environment_interpreter_load, SIEVE_EXT_DEFINE_OPERAND(environment_namespace_operand), }; static int ext_vnd_environment_load(const struct sieve_extension *ext, void **context_r) { const struct sieve_extension *ext_env; const struct sieve_extension *ext_var; struct sieve_instance *svinst = ext->svinst; struct ext_vnd_environment_context *extctx; const struct ext_vnd_environment_settings *set; const char *error; if (sieve_ext_environment_require_extension(ext->svinst, &ext_env) < 0) return -1; if (sieve_ext_variables_get_extension(ext->svinst, &ext_var) < 0) return -1; if (settings_get(svinst->event, &ext_vnd_environment_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_vnd_environment_context, 1); extctx->set = set; extctx->env_ext = ext_env; extctx->var_ext = ext_var; *context_r = extctx; return 0; } static void ext_vnd_environment_unload(const struct sieve_extension *ext) { struct ext_vnd_environment_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); i_free(extctx); } /* * Validator */ static bool ext_vnd_environment_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { const struct sieve_extension *env_ext; /* Load environment extension implicitly */ env_ext = sieve_validator_extension_load_implicit( valdtr, environment_extension.name); if (env_ext == NULL) return FALSE; ext_environment_variables_init(ext, valdtr); return TRUE; } /* * Interpreter */ static bool ext_vnd_environment_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { ext_vnd_environment_items_register(ext, renv); return TRUE; } ext-vnd-environment-settings.c0000644000175100001700000000161015100335616035573 0ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-vnd-environment-settings.h" static const struct setting_define ext_vnd_environment_setting_defines[] = { { .type = SET_STRLIST, .key = "sieve_environment", .offset = offsetof(struct ext_vnd_environment_settings, envs) }, SETTING_DEFINE_LIST_END, }; static const struct ext_vnd_environment_settings ext_vnd_environment_default_settings = { .envs = ARRAY_INIT, }; const struct setting_parser_info ext_vnd_environment_setting_parser_info = { .name = "sieve_vnd_environment", .defines = ext_vnd_environment_setting_defines, .defaults = &ext_vnd_environment_default_settings, .struct_size = sizeof(struct ext_vnd_environment_settings), .pool_offset1 = 1 + offsetof(struct ext_vnd_environment_settings, pool), }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/Makefile.in0000644000175100001700000005577115100335630032003 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/vnd.dovecot/environment ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_vnd_environment_la_LIBADD = am_libsieve_ext_vnd_environment_la_OBJECTS = \ ext-vnd-environment-settings.lo ext-vnd-environment-items.lo \ ext-vnd-environment-variables.lo ext-vnd-environment.lo libsieve_ext_vnd_environment_la_OBJECTS = \ $(am_libsieve_ext_vnd_environment_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-vnd-environment-items.Plo \ ./$(DEPDIR)/ext-vnd-environment-settings.Plo \ ./$(DEPDIR)/ext-vnd-environment-variables.Plo \ ./$(DEPDIR)/ext-vnd-environment.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_vnd_environment_la_SOURCES) DIST_SOURCES = $(libsieve_ext_vnd_environment_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_vnd_environment.la AM_CPPFLAGS = \ -I$(srcdir)/../../.. \ -I$(srcdir)/../../environment \ -I$(srcdir)/../../variables \ $(LIBDOVECOT_INCLUDE) libsieve_ext_vnd_environment_la_SOURCES = \ ext-vnd-environment-settings.c \ ext-vnd-environment-items.c \ ext-vnd-environment-variables.c \ ext-vnd-environment.c noinst_HEADERS = \ ext-vnd-environment-settings.h \ ext-vnd-environment-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/vnd.dovecot/environment/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/vnd.dovecot/environment/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_vnd_environment.la: $(libsieve_ext_vnd_environment_la_OBJECTS) $(libsieve_ext_vnd_environment_la_DEPENDENCIES) $(EXTRA_libsieve_ext_vnd_environment_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_vnd_environment_la_OBJECTS) $(libsieve_ext_vnd_environment_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-environment-items.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-environment-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-environment-variables.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-environment.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-vnd-environment-items.Plo -rm -f ./$(DEPDIR)/ext-vnd-environment-settings.Plo -rm -f ./$(DEPDIR)/ext-vnd-environment-variables.Plo -rm -f ./$(DEPDIR)/ext-vnd-environment.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-vnd-environment-items.Plo -rm -f ./$(DEPDIR)/ext-vnd-environment-settings.Plo -rm -f ./$(DEPDIR)/ext-vnd-environment-variables.Plo -rm -f ./$(DEPDIR)/ext-vnd-environment.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment-items.c0000644000175100001700000000525615100335616035145 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-vnd-environment-common.h" /* * Environment items */ /* default_mailbox */ static const char * envit_default_mailbox_get_value( const struct sieve_runtime_env *renv, const struct sieve_environment_item *item ATTR_UNUSED, const char *name ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; i_assert(eenv->scriptenv->default_mailbox != NULL); return eenv->scriptenv->default_mailbox; } const struct sieve_environment_item_def default_mailbox_env_item = { .name = "vnd.dovecot.default-mailbox", .get_value = envit_default_mailbox_get_value, }; /* username */ static const char * envit_username_get_value(const struct sieve_runtime_env *renv, const struct sieve_environment_item *item ATTR_UNUSED, const char *name ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; return eenv->svinst->username; } const struct sieve_environment_item_def username_env_item = { .name = "vnd.dovecot.username", .get_value = envit_username_get_value, }; /* config.* */ static const char * envit_config_get_value(const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_environment_item *item, const char *name) { const struct sieve_extension *this_ext = item->ext; struct ext_vnd_environment_context *extctx = this_ext->context; if (*name == '\0') return NULL; if (!array_is_created(&extctx->set->envs)) return NULL; const char *const *envs; unsigned int envs_count, i; envs = array_get(&extctx->set->envs, &envs_count); i_assert(envs_count % 2 == 0); for (i = 0; i < envs_count; i += 2) { if (strcasecmp(name, envs[i]) == 0) return envs[i + 1]; } return NULL; } const struct sieve_environment_item_def config_env_item = { .name = "vnd.dovecot.config", .prefix = TRUE, .get_value = envit_config_get_value, }; /* * Register */ void ext_vnd_environment_items_register(const struct sieve_extension *ext, const struct sieve_runtime_env *renv) { struct ext_vnd_environment_context *extctx = ext->context; sieve_environment_item_register(extctx->env_ext, renv->interp, ext, &default_mailbox_env_item); sieve_environment_item_register(extctx->env_ext, renv->interp, ext, &username_env_item); sieve_environment_item_register(extctx->env_ext, renv->interp, ext, &config_env_item); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment-common.h0000644000175100001700000000143515100335616035314 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VND_ENVIRONMENT_COMMON_H #define EXT_VND_ENVIRONMENT_COMMON_H #include "sieve-ext-environment.h" #include "ext-vnd-environment-settings.h" /* * Extension */ struct ext_vnd_environment_context { const struct ext_vnd_environment_settings *set; const struct sieve_extension *env_ext; const struct sieve_extension *var_ext; }; extern const struct sieve_extension_def vnd_environment_extension; /* * Operands */ extern const struct sieve_operand_def environment_namespace_operand; /* * Environment items */ void ext_vnd_environment_items_register(const struct sieve_extension *ext, const struct sieve_runtime_env *renv); /* * Variables */ void ext_environment_variables_init(const struct sieve_extension *this_ext, struct sieve_validator *valdtr); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/0000755000175100001700000000000015100335670026672 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.h0000644000175100001700000000126115100335616033227 0ustar00buildbotbuildbot00000000000000#ifndef EXT_REPORT_COMMON_H #define EXT_REPORT_COMMON_H #include "ext-vnd-report-settings.h" /* * Extension configuration */ struct ext_report_context { const struct ext_report_settings *set; }; /* * Extension */ extern const struct sieve_extension_def vnd_report_extension; int ext_report_load(const struct sieve_extension *ext, void **context_r); void ext_report_unload(const struct sieve_extension *ext); /* * Commands */ extern const struct sieve_command_def cmd_report; /* * Operations */ extern const struct sieve_operation_def report_operation; /* * RFC 5965 feedback-type */ const char *ext_vnd_report_parse_feedback_type(const char *feedback_type); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/Makefile.am0000644000175100001700000000056415100335616030733 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_vnd_report.la AM_CPPFLAGS = \ -I$(srcdir)/../../.. \ -I$(srcdir)/../../../util \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-report.c libsieve_ext_vnd_report_la_SOURCES = \ ext-vnd-report.c \ ext-vnd-report-settings.c \ ext-vnd-report-common.c \ $(commands) noinst_HEADERS = \ ext-vnd-report-settings.h \ ext-vnd-report-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.h0000644000175100001700000000045515100335616033603 0ustar00buildbotbuildbot00000000000000#ifndef EXT_REPORT_SETTINGS_H #define EXT_REPORT_SETTINGS_H #include "sieve-address-source.h" struct ext_report_settings { pool_t pool; const char *from; struct { struct sieve_address_source from; } parsed; }; extern const struct setting_parser_info ext_report_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report.c0000644000175100001700000000230315100335616031732 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2016-2018 Pigeonhole authors, see the included COPYING file */ /* Extension report * ---------------- * * Authors: Stephan Bosch * Specification: draft-ietf-sieve-report-00.txt * Implementation: full, but deprecated; provided for backwards compatibility * Status: testing * */ #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" #include "ext-vnd-report-common.h" /* * Extension */ static bool ext_report_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def vnd_report_extension = { .name = "vnd.dovecot.report", .load = ext_report_load, .unload = ext_report_unload, .validator_load = ext_report_validator_load, SIEVE_EXT_DEFINE_OPERATION(report_operation), }; /* * Extension validation */ static bool ext_report_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new commands */ sieve_validator_register_command(valdtr, ext, &cmd_report); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/Makefile.in0000644000175100001700000005535415100335630030747 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/vnd.dovecot/report ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_vnd_report_la_LIBADD = am__objects_1 = cmd-report.lo am_libsieve_ext_vnd_report_la_OBJECTS = ext-vnd-report.lo \ ext-vnd-report-settings.lo ext-vnd-report-common.lo \ $(am__objects_1) libsieve_ext_vnd_report_la_OBJECTS = \ $(am_libsieve_ext_vnd_report_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-report.Plo \ ./$(DEPDIR)/ext-vnd-report-common.Plo \ ./$(DEPDIR)/ext-vnd-report-settings.Plo \ ./$(DEPDIR)/ext-vnd-report.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_vnd_report_la_SOURCES) DIST_SOURCES = $(libsieve_ext_vnd_report_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_vnd_report.la AM_CPPFLAGS = \ -I$(srcdir)/../../.. \ -I$(srcdir)/../../../util \ $(LIBDOVECOT_INCLUDE) commands = \ cmd-report.c libsieve_ext_vnd_report_la_SOURCES = \ ext-vnd-report.c \ ext-vnd-report-settings.c \ ext-vnd-report-common.c \ $(commands) noinst_HEADERS = \ ext-vnd-report-settings.h \ ext-vnd-report-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/vnd.dovecot/report/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/vnd.dovecot/report/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_vnd_report.la: $(libsieve_ext_vnd_report_la_OBJECTS) $(libsieve_ext_vnd_report_la_DEPENDENCIES) $(EXTRA_libsieve_ext_vnd_report_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_vnd_report_la_OBJECTS) $(libsieve_ext_vnd_report_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-report.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-report-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-report-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vnd-report.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-report.Plo -rm -f ./$(DEPDIR)/ext-vnd-report-common.Plo -rm -f ./$(DEPDIR)/ext-vnd-report-settings.Plo -rm -f ./$(DEPDIR)/ext-vnd-report.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-report.Plo -rm -f ./$(DEPDIR)/ext-vnd-report-common.Plo -rm -f ./$(DEPDIR)/ext-vnd-report-settings.Plo -rm -f ./$(DEPDIR)/ext-vnd-report.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.c0000644000175100001700000000277515100335616033235 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2016-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "settings.h" #include "rfc822-parser.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "ext-vnd-report-common.h" int ext_report_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; struct ext_report_context *extctx; const struct ext_report_settings *set; const char *error; if (settings_get(svinst->event, &ext_report_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_report_context, 1); extctx->set = set; *context_r = extctx; return 0; } void ext_report_unload(const struct sieve_extension *ext) { struct ext_report_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); i_free(extctx); } const char *ext_vnd_report_parse_feedback_type(const char *feedback_type) { struct rfc822_parser_context parser; string_t *token; /* Initialize parsing */ rfc822_parser_init(&parser, (const unsigned char *)feedback_type, strlen(feedback_type), NULL); (void)rfc822_skip_lwsp(&parser); /* Parse MIME token */ token = t_str_new(64); if (rfc822_parse_mime_token(&parser, token) < 0) return NULL; /* Content-type value must end here, otherwise it is invalid after all. */ (void)rfc822_skip_lwsp(&parser); if (parser.data != parser.end) return NULL; /* Success */ return str_c(token); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c0000644000175100001700000004330615100335616031120 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2016-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str.h" #include "ioloop.h" #include "hostpid.h" #include "str-sanitize.h" #include "istream.h" #include "ostream.h" #include "message-date.h" #include "message-size.h" #include "mail-storage.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-address.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-message.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-result.h" #include "sieve-address.h" #include "sieve-message.h" #include "sieve-smtp.h" #include "ext-vnd-report-common.h" #include /* Report command * * Syntax: * report [:headers_only] * * */ static bool cmd_report_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_report_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_report_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def cmd_report = { .identifier = "report", .type = SCT_COMMAND, .positional_args = 3, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_report_registered, .validate = cmd_report_validate, .generate = cmd_report_generate, }; /* * Tagged arguments */ static const struct sieve_argument_def report_headers_only_tag = { .identifier = "headers_only", }; /* * Report operation */ static bool cmd_report_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_report_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def report_operation = { .mnemonic = "REPORT", .ext_def = &vnd_report_extension, .code = 0, .dump = cmd_report_operation_dump, .execute = cmd_report_operation_execute, }; /* Codes for optional operands */ enum cmd_report_optional { OPT_END, OPT_HEADERS_ONLY, }; /* * Report action */ /* Forward declarations */ static int act_report_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_report_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_report_commit(const struct sieve_action_exec_env *aenv, void *tr_context); /* Action object */ const struct sieve_action_def act_report = { .name = "report", .check_duplicate = act_report_check_duplicate, .print = act_report_print, .commit = act_report_commit, }; /* Action data */ struct act_report_data { const char *feedback_type; const char *message; struct smtp_address *to_address; bool headers_only:1; }; /* * Command registration */ static bool cmd_report_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, &report_headers_only_tag, OPT_HEADERS_ONLY); return TRUE; } /* * Command validation */ static bool cmd_report_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; /* type */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "feedback-type", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; if (sieve_argument_is_string_literal(arg)) { string_t *fbtype = sieve_ast_argument_str(arg); const char *feedback_type; T_BEGIN { /* Check feedback type */ feedback_type = ext_vnd_report_parse_feedback_type(str_c(fbtype)); if (feedback_type == NULL) { sieve_argument_validate_error( valdtr, arg, "specified feedback type '%s' is invalid", str_sanitize(str_c(fbtype),128)); } } T_END; if (feedback_type == NULL) return FALSE; } arg = sieve_ast_argument_next(arg); /* message */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "message", 2, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; arg = sieve_ast_argument_next(arg); /* address */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "address", 3, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; /* We can only assess the validity of the outgoing address when it is a string literal. For runtime-generated strings this needs to be done at runtime. */ if (sieve_argument_is_string_literal(arg)) { string_t *raw_address = sieve_ast_argument_str(arg); const char *error; bool result; T_BEGIN { /* Parse the address */ result = sieve_address_validate_str(raw_address, &error); if (!result) { sieve_argument_validate_error( valdtr, arg, "specified report address '%s' is invalid: %s", str_sanitize(str_c(raw_address),128), error); } } T_END; return result; } return TRUE; } /* * Code generation */ static bool cmd_report_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &report_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_report_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "REPORT"); sieve_code_descend(denv); /* Dump optional operands */ for (;;) { int opt; opt = sieve_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_HEADERS_ONLY: sieve_code_dumpf(denv, "headers_only"); break; default: return FALSE; } } return (sieve_opr_string_dump(denv, address, "feedback-type") && sieve_opr_string_dump(denv, address, "message") && sieve_opr_string_dump(denv, address, "address")); } /* * Code execution */ static int cmd_report_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct act_report_data *act; string_t *fbtype, *message, *to_address; const char *feedback_type, *error; const struct smtp_address *parsed_address; int opt_code = 0, ret = 0; bool headers_only = FALSE; pool_t pool; /* * Read operands */ /* Optional operands */ for (;;) { int opt; opt = sieve_opr_optional_read(renv, address, &opt_code); if (opt < 0) return SIEVE_EXEC_BIN_CORRUPT; if (opt == 0) break; switch (opt_code) { case OPT_HEADERS_ONLY: headers_only = TRUE; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } /* Fixed operands */ ret = sieve_opr_string_read(renv, address, "feedback-type", &fbtype); if (ret <= 0) return ret; ret = sieve_opr_string_read(renv, address, "message", &message); if (ret <= 0) return ret; ret = sieve_opr_string_read(renv, address, "address", &to_address); if (ret <= 0) return ret; /* * Perform operation */ /* Verify and trim feedback type */ feedback_type = ext_vnd_report_parse_feedback_type(str_c(fbtype)); if (feedback_type == NULL) { sieve_runtime_error( renv, NULL, "specified report feedback type '%s' is invalid", str_sanitize(str_c(fbtype), 256)); return SIEVE_EXEC_FAILURE; } /* Verify and normalize the address to 'local_part@domain' */ parsed_address = sieve_address_parse_str(to_address, &error); if (parsed_address == NULL) { sieve_runtime_error( renv, NULL, "specified report address '%s' is invalid: %s", str_sanitize(str_c(to_address),128), error); return SIEVE_EXEC_FAILURE; } /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS)) { sieve_runtime_trace(renv, 0, "report action"); sieve_runtime_trace_descend(renv); sieve_runtime_trace( renv, 0, "report incoming message as '%s' to address %s", str_sanitize(str_c(fbtype), 32), smtp_address_encode_path(parsed_address)); } /* Add report action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_report_data, 1); act->headers_only = headers_only; act->feedback_type = p_strdup(pool, feedback_type); act->message = p_strdup(pool, str_c(message)); act->to_address = smtp_address_clone(pool, parsed_address); if (sieve_result_add_action(renv, this_ext, "report", &act_report, NULL, act, 0, TRUE) < 0) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } /* * Action */ /* Runtime verification */ static bool act_report_equals(const struct sieve_script_env *senv ATTR_UNUSED, const struct sieve_action *act1, const struct sieve_action *act2) { struct act_report_data *rdd1 = (struct act_report_data *)act1->context; struct act_report_data *rdd2 = (struct act_report_data *)act2->context; /* Address is already normalized */ return (smtp_address_equals(rdd1->to_address, rdd2->to_address)); } static int act_report_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other) { const struct sieve_execute_env *eenv = renv->exec_env; return (act_report_equals(eenv->scriptenv, act, act_other) ? 1 : 0); } /* Result printing */ static void act_report_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { const struct act_report_data *rdd = (struct act_report_data *)action->context; sieve_result_action_printf(rpenv, "report incoming message as '%s' to: %s", str_sanitize(rdd->feedback_type, 32), smtp_address_encode_path(rdd->to_address)); } /* Result execution */ static bool _contains_8bit(const char *msg) { const unsigned char *s = (const unsigned char *)msg; for (; *s != '\0'; s++) { if ((*s & 0x80) != 0) return TRUE; } return FALSE; } static int act_report_send(const struct sieve_action_exec_env *aenv, const struct ext_report_context *extctx, const struct act_report_data *act) { const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_instance *svinst = eenv->svinst; struct sieve_message_context *msgctx = aenv->msgctx; const struct sieve_script_env *senv = eenv->scriptenv; const struct sieve_message_data *msgdata = eenv->msgdata; struct sieve_address_source report_from = extctx->set->parsed.from; const struct smtp_address *sender, *user; struct sieve_smtp_context *sctx; struct istream *input; struct ostream *output; string_t *msg; const char *const *headers; const char *outmsgid, *boundary, *error, *subject, *from; int ret; /* Just to be sure */ if (!sieve_smtp_available(senv)) { sieve_result_global_warning( aenv, "report action has no means to send mail"); return SIEVE_EXEC_OK; } /* Make sure we have a subject for our report */ ret = mail_get_headers_utf8(msgdata->mail, "subject", &headers); if (ret < 0) { return sieve_result_mail_error( aenv, msgdata->mail, "failed to read header field 'subject'"); } if (ret > 0 && headers[0] != NULL) subject = t_strconcat("Report: ", headers[0], NULL); else subject = "Report: (message without subject)"; /* Determine from address */ if (report_from.type == SIEVE_ADDRESS_SOURCE_POSTMASTER) { report_from.type = SIEVE_ADDRESS_SOURCE_DEFAULT; report_from.address = NULL; } if (sieve_address_source_get_address( &report_from, svinst, senv, msgctx, eenv->flags, &sender) > 0 && sender != NULL) from = smtp_address_encode_path(sender); else from = sieve_get_postmaster_address(senv); /* Start message */ sctx = sieve_smtp_start_single(senv, act->to_address, NULL, &output); outmsgid = sieve_message_get_new_id(svinst); boundary = t_strdup_printf("%s/%s", my_pid, svinst->hostname); /* Compose main report headers */ msg = t_str_new(512); rfc2822_header_write(msg, "X-Sieve", SIEVE_IMPLEMENTATION); rfc2822_header_write(msg, "Message-ID", outmsgid); rfc2822_header_write(msg, "Date", message_date_create(ioloop_time)); rfc2822_header_write(msg, "From", from); rfc2822_header_write(msg, "To", smtp_address_encode_path(act->to_address)); if (_contains_8bit(subject)) rfc2822_header_utf8_printf(msg, "Subject", "%s", subject); else rfc2822_header_printf(msg, "Subject", "%s", subject); rfc2822_header_write(msg, "Auto-Submitted", "auto-generated (report)"); rfc2822_header_write(msg, "MIME-Version", "1.0"); rfc2822_header_printf(msg, "Content-Type", "multipart/report; report-type=feedback-report;\n" "boundary=\"%s\"", boundary); str_append(msg, "\r\nThis is a MIME-encapsulated message\r\n\r\n"); /* Human-readable report */ str_printfa(msg, "--%s\r\n", boundary); if (_contains_8bit(act->message)) { rfc2822_header_write(msg, "Content-Type", "text/plain; charset=utf-8"); rfc2822_header_write(msg, "Content-Transfer-Encoding", "8bit"); } else { rfc2822_header_write(msg, "Content-Type", "text/plain; charset=us-ascii"); rfc2822_header_write(msg, "Content-Transfer-Encoding", "7bit"); } rfc2822_header_write(msg, "Content-Disposition", "inline"); str_printfa(msg, "\r\n%s\r\n\r\n", act->message); o_stream_nsend(output, str_data(msg), str_len(msg)); /* Machine-readable report */ str_truncate(msg, 0); str_printfa(msg, "--%s\r\n", boundary); rfc2822_header_write(msg, "Content-Type", "message/feedback-report"); str_append(msg, "\r\n"); rfc2822_header_write(msg, "Version", "1"); rfc2822_header_write(msg, "Feedback-Type", act->feedback_type); rfc2822_header_write(msg, "User-Agent", PACKAGE_NAME "/" PACKAGE_VERSION " " PIGEONHOLE_NAME "/" PIGEONHOLE_VERSION); if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) { const struct smtp_address *sender, *orig_recipient; sender = sieve_message_get_sender(msgctx); orig_recipient = sieve_message_get_orig_recipient(msgctx); rfc2822_header_write(msg, "Original-Mail-From", smtp_address_encode_path(sender)); if (orig_recipient != NULL) { rfc2822_header_write( msg, "Original-Rcpt-To", smtp_address_encode_path(orig_recipient)); } } if (svinst->set->parsed.user_email != NULL) user = svinst->set->parsed.user_email; else if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0 || (user = sieve_message_get_orig_recipient(msgctx)) == NULL) user = sieve_get_user_email(svinst); if (user != NULL) { rfc2822_header_write(msg, "Dovecot-Reporting-User", smtp_address_encode_path(user)); } str_append(msg, "\r\n"); o_stream_nsend(output, str_data(msg), str_len(msg)); /* Original message */ str_truncate(msg, 0); str_printfa(msg, "--%s\r\n", boundary); if (act->headers_only) { rfc2822_header_write(msg, "Content-Type", "text/rfc822-headers"); } else { rfc2822_header_write(msg, "Content-Type", "message/rfc822"); } rfc2822_header_write(msg, "Content-Disposition", "attachment"); str_append(msg, "\r\n"); o_stream_nsend(output, str_data(msg), str_len(msg)); if (act->headers_only) { struct message_size hdr_size; ret = mail_get_hdr_stream(msgdata->mail, &hdr_size, &input); if (ret >= 0) { input = i_stream_create_limit( input, hdr_size.physical_size); } } else { ret = mail_get_stream(msgdata->mail, NULL, NULL, &input); if (ret >= 0) i_stream_ref(input); } if (ret < 0) { sieve_smtp_abort(sctx); return sieve_result_mail_error(aenv, msgdata->mail, "failed to read input message"); } o_stream_nsend_istream(output, input); if (input->stream_errno != 0) { /* Error; clean up */ sieve_result_critical(aenv, "failed to read input message", "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); i_stream_unref(&input); sieve_smtp_abort(sctx); return SIEVE_EXEC_OK; } i_stream_unref(&input); str_truncate(msg, 0); if (!act->headers_only) str_printfa(msg, "\r\n"); str_printfa(msg, "\r\n--%s--\r\n", boundary); o_stream_nsend(output, str_data(msg), str_len(msg)); /* Finish sending message */ ret = sieve_smtp_finish(sctx, &error); if (ret <= 0) { if (ret < 0) { sieve_result_global_error( aenv, "failed to send '%s' report to <%s>: %s " "(temporary failure)", str_sanitize(act->feedback_type, 32), smtp_address_encode(act->to_address), str_sanitize(error, 512)); } else { sieve_result_global_log_error( aenv, "failed to send '%s' report to <%s>: %s " "(permanent failure)", str_sanitize(act->feedback_type, 32), smtp_address_encode(act->to_address), str_sanitize(error, 512)); } } else { eenv->exec_status->significant_action_executed = TRUE; struct event_passthrough *e = sieve_action_create_finish_event(aenv)-> add_str("report_target", smtp_address_encode(act->to_address))-> add_str("report_type", str_sanitize(act->feedback_type, 32)); sieve_result_event_log(aenv, e->event(), "sent '%s' report to <%s>", str_sanitize(act->feedback_type, 32), smtp_address_encode(act->to_address)); } return SIEVE_EXEC_OK; } static int act_report_commit(const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED) { const struct sieve_action *action = aenv->action; const struct sieve_extension *ext = action->ext; const struct ext_report_context *extctx = ext->context; const struct act_report_data *act = (const struct act_report_data *)action->context; int ret; T_BEGIN { ret = act_report_send(aenv, extctx, act); } T_END; if (ret == SIEVE_EXEC_TEMP_FAILURE) return SIEVE_EXEC_TEMP_FAILURE; /* Ignore all other errors */ return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.c0000644000175100001700000000253115100335616033573 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-vnd-report-settings.h" static bool ext_report_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_report_"#name, name, \ struct ext_report_settings) static const struct setting_define ext_report_setting_defines[] = { DEF(STR, from), SETTING_DEFINE_LIST_END, }; static const struct ext_report_settings ext_report_default_settings = { .from = "", }; const struct setting_parser_info ext_report_setting_parser_info = { .name = "sieve_report", .defines = ext_report_setting_defines, .defaults = &ext_report_default_settings, .struct_size = sizeof(struct ext_report_settings), .check_func = ext_report_settings_check, .pool_offset1 = 1 + offsetof(struct ext_report_settings, pool), }; /* */ static bool ext_report_settings_check(void *_set, pool_t pool, const char **error_r) { struct ext_report_settings *set = _set; if (!sieve_address_source_parse(pool, set->from, &set->parsed.from)) { *error_r = t_strdup_printf("sieve_report_from: " "Invalid address source '%s'", set->from); return FALSE; } return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/0000755000175100001700000000000015100335670024043 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/tst-date.c0000644000175100001700000003104415100335616025736 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-message.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-date-common.h" #include /* * Tests */ static bool tst_date_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_date_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); /* Date test * * Syntax: * date [<":zone" > / ":originalzone"] * [COMPARATOR] [MATCH-TYPE] * */ static bool tst_date_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); const struct sieve_command_def date_test = { .identifier = "date", .type = SCT_TEST, .positional_args = 3, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_date_registered, .validate = tst_date_validate, .generate = tst_date_generate, }; /* Currentdate test * * Syntax: * currentdate [":zone" ] * [COMPARATOR] [MATCH-TYPE] * */ static bool tst_currentdate_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); const struct sieve_command_def currentdate_test = { .identifier = "currentdate", .type = SCT_TEST, .positional_args = 2, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_currentdate_registered, .validate = tst_date_validate, .generate = tst_date_generate, }; /* * Tagged arguments */ /* Forward declarations */ static bool tag_zone_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_zone_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def date_zone_tag = { .identifier = "zone", .validate = tag_zone_validate, .generate = tag_zone_generate, }; static const struct sieve_argument_def date_originalzone_tag = { .identifier = "originalzone", .validate = tag_zone_validate, .generate = tag_zone_generate, }; /* * Date operation */ static bool tst_date_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_date_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def date_operation = { .mnemonic = "DATE", .ext_def = &date_extension, .code = EXT_DATE_OPERATION_DATE, .dump = tst_date_operation_dump, .execute = tst_date_operation_execute, }; const struct sieve_operation_def currentdate_operation = { .mnemonic = "CURRENTDATE", .ext_def = &date_extension, .code = EXT_DATE_OPERATION_CURRENTDATE, .dump = tst_date_operation_dump, .execute = tst_date_operation_execute, }; /* * Optional operands */ enum tst_date_optional { OPT_DATE_ZONE = SIEVE_AM_OPT_LAST, OPT_DATE_LAST, }; /* * Tag implementation */ static bool tag_zone_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; if ((bool)cmd->data) { if (sieve_command_is(cmd, date_test)) { sieve_argument_validate_error( valdtr, *arg, "multiple :zone or :originalzone arguments specified for " "the currentdate test"); } else { sieve_argument_validate_error( valdtr, *arg, "multiple :zone arguments specified for the currentdate test"); } return FALSE; } /* Skip tag */ *arg = sieve_ast_argument_next(*arg); /* :content tag has a string-list argument */ if (sieve_argument_is(tag, date_zone_tag)) { /* Check syntax: * :zone */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE)) return FALSE; /* Check it */ if (sieve_argument_is_string_literal(*arg)) { const char *zone = sieve_ast_argument_strc(*arg); if (!ext_date_parse_timezone(zone, NULL)) { sieve_argument_validate_warning( valdtr, *arg, "specified :zone argument '%s' is not a valid timezone", str_sanitize(zone, 40)); } } /* Assign tag parameters */ tag->parameters = *arg; *arg = sieve_ast_arguments_detach(*arg,1); } cmd->data = (void *)TRUE; return TRUE; } /* * Test registration */ static bool tst_date_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag(valdtr, cmd_reg, ext, &date_zone_tag, OPT_DATE_ZONE); sieve_validator_register_tag(valdtr, cmd_reg, ext, &date_originalzone_tag, OPT_DATE_ZONE); return TRUE; } static bool tst_currentdate_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag(valdtr, cmd_reg, ext, &date_zone_tag, OPT_DATE_ZONE); return TRUE; } /* * Validation */ static bool tst_date_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; unsigned int arg_offset = 0 ; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); /* Check header name */ if (sieve_command_is(tst, date_test)) { arg_offset = 1; if (!sieve_validate_positional_argument( valdtr, tst, arg, "header name", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; if (!sieve_command_verify_headers_argument(valdtr, arg)) return FALSE; arg = sieve_ast_argument_next(arg); } /* Check date part */ if (!sieve_validate_positional_argument( valdtr, tst, arg, "date part", arg_offset + 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; if (sieve_argument_is_string_literal(arg)) { const char * part = sieve_ast_argument_strc(arg); if (ext_date_part_find(part) == NULL) { sieve_argument_validate_warning( valdtr, arg, "specified date part '%s' is not known", str_sanitize(part, 80)); } } arg = sieve_ast_argument_next(arg); /* Check key list */ if (!sieve_validate_positional_argument( valdtr, tst, arg, "key list", arg_offset + 2, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_date_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { if (sieve_command_is(tst, date_test)) { sieve_operation_emit(cgenv->sblock, tst->ext, &date_operation); } else if (sieve_command_is(tst, currentdate_test)) { sieve_operation_emit(cgenv->sblock, tst->ext, ¤tdate_operation); } else { i_unreached(); } /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } static bool tag_zone_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { if (arg->parameters == NULL) { sieve_opr_omitted_emit(cgenv->sblock); return TRUE; } return sieve_generate_argument_parameters(cgenv, cmd, arg); } /* * Code dump */ static bool tst_date_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; const struct sieve_operation *op = denv->oprtn; sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); /* Handle any optional arguments */ for (;;) { int opt; opt = sieve_message_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_DATE_ZONE: if (!sieve_opr_string_dump_ex(denv, address, "zone", "ORIGINAL")) return FALSE; break; default: return FALSE; } } if (sieve_operation_is(op, date_operation) && !sieve_opr_string_dump(denv, address, "header name")) return FALSE; return (sieve_opr_string_dump(denv, address, "date part") && sieve_opr_stringlist_dump(denv, address, "key list")); } /* * Code execution */ static int tst_date_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *op = renv->oprtn; int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); ARRAY_TYPE(sieve_message_override) svmos; string_t *date_part = NULL, *zone = NULL; struct sieve_stringlist *hdr_list = NULL, *hdr_value_list; struct sieve_stringlist *value_list, *key_list; bool zone_specified = FALSE, zone_literal = TRUE; const struct ext_date_part *dpart; int time_zone; int match, ret; /* Read optional operands */ for (;;) { int opt; /* Optional operands */ i_zero(&svmos); opt = sieve_message_opr_optional_read( renv, address, &opt_code, &ret, NULL, &mcht, &cmp, &svmos); if (opt < 0) return ret; if (opt == 0) break; switch (opt_code) { case OPT_DATE_ZONE: ret = sieve_opr_string_read_ex( renv, address, "zone", TRUE, &zone, &zone_literal); if (ret <= 0) return ret; zone_specified = TRUE; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } if (sieve_operation_is(op, date_operation)) { /* Read header name as stringlist */ ret = sieve_opr_stringlist_read(renv, address, "header-name", &hdr_list); if (ret <= 0) return ret; } /* Read date part */ ret = sieve_opr_string_read(renv, address, "date-part", &date_part); if (ret <= 0) return ret; /* Read key-list */ ret = sieve_opr_stringlist_read(renv, address, "key-list", &key_list); if (ret <= 0) return ret; /* Determine what time zone to use in the result */ if (!zone_specified) { time_zone = EXT_DATE_TIMEZONE_LOCAL; } else if (zone == NULL) { time_zone = EXT_DATE_TIMEZONE_ORIGINAL; } else if (!ext_date_parse_timezone(str_c(zone), &time_zone)) { if (!zone_literal) { sieve_runtime_warning( renv, NULL, "specified :zone argument '%s' is not a valid timezone " "(using local zone)", str_sanitize(str_c(zone), 40)); } time_zone = EXT_DATE_TIMEZONE_LOCAL; } dpart = ext_date_part_find(str_c(date_part)); if (dpart == NULL) { sieve_runtime_warning( renv, NULL, "specified date part argument '%s' is not known", str_sanitize(str_c(date_part), 40)); sieve_interpreter_set_test_result(renv->interp, FALSE); return SIEVE_EXEC_OK; } /* * Perform test */ if (sieve_operation_is(op, date_operation)) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "date test"); /* Get header */ sieve_runtime_trace_descend(renv); ret = sieve_message_get_header_fields(renv, hdr_list, &svmos, FALSE, &hdr_value_list); if (ret <= 0) return ret; sieve_runtime_trace_ascend(renv); /* Create value stringlist */ value_list = ext_date_stringlist_create(renv, hdr_value_list, time_zone, dpart); } else if (sieve_operation_is(op, currentdate_operation)) { /* Use time stamp recorded at the time the script first started. */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "currentdatedate test"); /* Create value stringlist */ value_list = ext_date_stringlist_create( renv, NULL, time_zone, dpart); } else { i_unreached(); } /* Perform match */ match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret); if (match < 0) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/ext-date.c0000644000175100001700000000250115100335616025720 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension date * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5260 * Implementation: full * Status: testing * */ #include "lib.h" #include "array.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-date-common.h" /* * Extension */ static bool ext_date_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_operation_def *ext_date_operations[] = { &date_operation, ¤tdate_operation }; const struct sieve_extension_def date_extension = { .name = "date", .validator_load = ext_date_validator_load, .interpreter_load = ext_date_interpreter_load, SIEVE_EXT_DEFINE_OPERATIONS(ext_date_operations) }; static bool ext_date_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ sieve_validator_register_command(valdtr, ext, &date_test); sieve_validator_register_command(valdtr, ext, ¤tdate_test); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/Makefile.am0000644000175100001700000000036415100335616026102 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_date.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-date.c libsieve_ext_date_la_SOURCES = \ $(tests) \ ext-date-common.c \ ext-date.c noinst_HEADERS = \ ext-date-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/ext-date-common.c0000644000175100001700000003422515100335616027216 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "utc-offset.h" #include "str.h" #include "iso8601-date.h" #include "message-date.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-interpreter.h" #include "sieve-message.h" #include "ext-date-common.h" #include #include struct ext_date_context { time_t current_date; int zone_offset; }; /* * Runtime initialization */ static int ext_date_runtime_init(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, void *context ATTR_UNUSED, bool deferred ATTR_UNUSED) { struct ext_date_context *dctx; pool_t pool; struct timeval msg_time; time_t current_date; struct tm *tm; int zone_offset; /* Get current time at instance main script is started */ sieve_message_context_time(renv->msgctx, &msg_time); current_date = msg_time.tv_sec; tm = localtime(¤t_date); zone_offset = utc_offset(tm, current_date); /* Create context */ pool = sieve_message_context_pool(renv->msgctx); dctx = p_new(pool, struct ext_date_context, 1); dctx->current_date = current_date; dctx->zone_offset = zone_offset; sieve_message_context_extension_set(renv->msgctx, ext, dctx); return SIEVE_EXEC_OK; } static struct sieve_interpreter_extension date_interpreter_extension = { .ext_def = &date_extension, .run = ext_date_runtime_init }; bool ext_date_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { /* Register runtime hook to obtain stript start timestamp */ if (renv->msgctx == NULL || sieve_message_context_extension_get(renv->msgctx, ext) == NULL) { sieve_interpreter_extension_register( renv->interp, ext, &date_interpreter_extension, NULL); } return TRUE; } /* * Zone string */ bool ext_date_parse_timezone(const char *zone, int *zone_offset_r) { const unsigned char *str = (const unsigned char *)zone; size_t len = strlen(zone); if (len == 5 && (*str == '+' || *str == '-')) { int offset; if (!i_isdigit(str[1]) || !i_isdigit(str[2]) || !i_isdigit(str[3]) || !i_isdigit(str[4])) return FALSE; offset = ((str[1]-'0') * 10 + (str[2]-'0')) * 60 + (str[3]-'0') * 10 + (str[4]-'0'); if (zone_offset_r != NULL) *zone_offset_r = *str == '+' ? offset : -offset; return TRUE; } return FALSE; } /* * Current date */ time_t ext_date_get_current_date(const struct sieve_runtime_env *renv, int *zone_offset_r) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_date_context *dctx = (struct ext_date_context *) sieve_message_context_extension_get(renv->msgctx, this_ext); if (dctx == NULL) { ext_date_runtime_init(this_ext, renv, NULL, FALSE); dctx = (struct ext_date_context *) sieve_message_context_extension_get( renv->msgctx, this_ext); i_assert(dctx != NULL); } /* Read script start timestamp from message context */ if (zone_offset_r != NULL) *zone_offset_r = dctx->zone_offset; return dctx->current_date; } /* * Date parts */ /* "year" => the year, "0000" .. "9999". */ static const char *ext_date_year_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part year_date_part = { "year", ext_date_year_part_get, }; /* "month" => the month, "01" .. "12". */ static const char *ext_date_month_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part month_date_part = { "month", ext_date_month_part_get, }; /* "day" => the day, "01" .. "31". */ static const char *ext_date_day_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part day_date_part = { "day", ext_date_day_part_get, }; /* "date" => the date in "yyyy-mm-dd" format. */ static const char *ext_date_date_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part date_date_part = { "date", ext_date_date_part_get, }; /* "julian" => the Modified Julian Day, that is, the date expressed as an integer number of days since 00:00 UTC on November 17, 1858 (using the Gregorian calendar). This corresponds to the regular Julian Day minus 2400000.5. */ static const char *ext_date_julian_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part julian_date_part = { "julian", ext_date_julian_part_get, }; /* "hour" => the hour, "00" .. "23". */ static const char *ext_date_hour_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part hour_date_part = { "hour", ext_date_hour_part_get, }; /* "minute" => the minute, "00" .. "59". */ static const char *ext_date_minute_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part minute_date_part = { "minute", ext_date_minute_part_get, }; /* "second" => the second, "00" .. "60". */ static const char *ext_date_second_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part second_date_part = { "second", ext_date_second_part_get, }; /* "time" => the time in "hh:mm:ss" format. */ static const char *ext_date_time_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part time_date_part = { "time", ext_date_time_part_get, }; /* "iso8601" => the date and time in restricted ISO 8601 format. */ static const char *ext_date_iso8601_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part iso8601_date_part = { "iso8601", ext_date_iso8601_part_get, }; /* "std11" => the date and time in a format appropriate for use in a Date: header field [RFC2822]. */ static const char *ext_date_std11_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part std11_date_part = { "std11", ext_date_std11_part_get, }; /* "zone" => the time zone in use. If the user specified a time zone with ":zone", "zone" will contain that value. If :originalzone is specified this value will be the original zone specified in the date-time value. If neither argument is specified the value will be the server's default time zone in offset format "+hhmm" or "-hhmm". An offset of 0 (Zulu) always has a positive sign. */ static const char *ext_date_zone_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part zone_date_part = { "zone", ext_date_zone_part_get, }; /* "weekday" => the day of the week expressed as an integer between "0" and "6". "0" is Sunday, "1" is Monday, etc. */ static const char *ext_date_weekday_part_get(struct tm *tm, int zone_offset); static const struct ext_date_part weekday_date_part = { "weekday", ext_date_weekday_part_get, }; /* * Date part extraction */ static const struct ext_date_part *date_parts[] = { &year_date_part, &month_date_part, &day_date_part, &date_date_part, &julian_date_part, &hour_date_part, &minute_date_part, &second_date_part, &time_date_part, &iso8601_date_part, &std11_date_part, &zone_date_part, &weekday_date_part, }; unsigned int date_parts_count = N_ELEMENTS(date_parts); const struct ext_date_part *ext_date_part_find(const char *part) { unsigned int i; for (i = 0; i < date_parts_count; i++) { if (strcasecmp(date_parts[i]->identifier, part) == 0) return date_parts[i]; } return NULL; } const char *ext_date_part_extract(const struct ext_date_part *dpart, struct tm *tm, int zone_offset) { if (dpart == NULL || dpart->get_string == NULL) return NULL; return dpart->get_string(tm, zone_offset); } /* * Date part implementations */ static const char *month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const char *weekday_names[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char * ext_date_year_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%04d", tm->tm_year + 1900); } static const char * ext_date_month_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%02d", tm->tm_mon + 1); } static const char * ext_date_day_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%02d", tm->tm_mday); } static const char * ext_date_date_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%04d-%02d-%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); } static const char * ext_date_julian_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { int year = tm->tm_year+1900; int month = tm->tm_mon+1; int day = tm->tm_mday; int c, ya, jd; /* Modified from RFC 5260 Appendix A (refer to Errata) */ if (month > 2) month -= 3; else { month += 9; year--; } c = year / 100; ya = year - c * 100; jd = c * 146097 / 4 + ya * 1461 / 4 + (month * 153 + 2) / 5 + day + 1721119; return t_strdup_printf("%d", jd - 2400001); } static const char * ext_date_hour_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%02d", tm->tm_hour); } static const char * ext_date_minute_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%02d", tm->tm_min); } static const char * ext_date_second_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%02d", tm->tm_sec); } static const char * ext_date_time_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); } static const char * ext_date_iso8601_part_get(struct tm *tm, int zone_offset) { /* From RFC: The restricted ISO 8601 format is specified by the date-time ABNF production given in [RFC3339], Section 5.6, with the added restrictions that the letters "T" and "Z" MUST be in upper case, and a time zone offset of zero MUST be represented by "Z" and not "+00:00". */ if (zone_offset == 0) zone_offset = INT_MAX; return iso8601_date_create_tm(tm, zone_offset); } static const char * ext_date_std11_part_get(struct tm *tm, int zone_offset) { return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %s", weekday_names[tm->tm_wday], tm->tm_mday, month_names[tm->tm_mon], tm->tm_year+1900, tm->tm_hour, tm->tm_min, tm->tm_sec, ext_date_zone_part_get(tm, zone_offset)); } static const char * ext_date_zone_part_get(struct tm *tm ATTR_UNUSED, int zone_offset) { bool negative; int offset = zone_offset; if (zone_offset >= 0) negative = FALSE; else { negative = TRUE; offset = -offset; } return t_strdup_printf("%c%02d%02d", (negative ? '-' : '+'), offset / 60, offset % 60); } static const char * ext_date_weekday_part_get(struct tm *tm, int zone_offset ATTR_UNUSED) { return t_strdup_printf("%d", tm->tm_wday); } /* * Date stringlist */ /* Forward declarations */ static int ext_date_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void ext_date_stringlist_reset(struct sieve_stringlist *_strlist); /* Stringlist object */ struct ext_date_stringlist { struct sieve_stringlist strlist; struct sieve_stringlist *field_values; int time_zone; const struct ext_date_part *date_part; time_t local_time; int local_zone; bool read:1; }; struct sieve_stringlist * ext_date_stringlist_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_values, int time_zone, const struct ext_date_part *dpart) { struct ext_date_stringlist *strlist; strlist = t_new(struct ext_date_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = ext_date_stringlist_next_item; strlist->strlist.reset = ext_date_stringlist_reset; strlist->field_values = field_values; strlist->time_zone = time_zone; strlist->date_part = dpart; strlist->local_time = ext_date_get_current_date(renv, &strlist->local_zone); return &strlist->strlist; } /* Stringlist implementation */ static int ext_date_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct ext_date_stringlist *strlist = (struct ext_date_stringlist *)_strlist; bool got_date = FALSE; time_t date_value; const char *part_value = NULL; int original_zone; /* Check whether the item was already read */ if (strlist->read) return 0; if (strlist->field_values != NULL) { string_t *hdr_item; const char *header_value, *date_string; int ret; /* Use header field value */ /* Read first */ ret = sieve_stringlist_next_item(strlist->field_values, &hdr_item); if (ret <= 0) return ret; /* Extract the date string value */ header_value = str_c(hdr_item); date_string = strrchr(header_value, ';'); if (date_string == NULL) { /* Direct header value */ date_string = header_value; } else { /* Delimited by ';', e.g. a Received: header */ date_string++; } /* Parse the date value */ if (message_date_parse((const unsigned char *)date_string, strlen(date_string), &date_value, &original_zone)) got_date = TRUE; } else { /* Use time stamp recorded at the time the script first started. */ date_value = strlist->local_time; original_zone = strlist->local_zone; got_date = TRUE; } if (got_date) { int wanted_zone; struct tm *date_tm; /* Apply wanted timezone */ switch (strlist->time_zone) { case EXT_DATE_TIMEZONE_LOCAL: wanted_zone = strlist->local_zone; break; case EXT_DATE_TIMEZONE_ORIGINAL: wanted_zone = original_zone; break; default: wanted_zone = strlist->time_zone; } date_value += wanted_zone * 60; /* Convert timestamp to struct tm */ if ((date_tm = gmtime(&date_value)) != NULL) { /* Extract the date part */ part_value = ext_date_part_extract( strlist->date_part, date_tm, wanted_zone); } } strlist->read = TRUE; if (part_value == NULL) return 0; *str_r = t_str_new_const(part_value, strlen(part_value)); return 1; } static void ext_date_stringlist_reset(struct sieve_stringlist *_strlist) { struct ext_date_stringlist *strlist = (struct ext_date_stringlist *)_strlist; if (strlist->field_values != NULL) sieve_stringlist_reset(strlist->field_values); strlist->read = FALSE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/Makefile.in0000644000175100001700000005422715100335630026116 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/date ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_date_la_LIBADD = am__objects_1 = tst-date.lo am_libsieve_ext_date_la_OBJECTS = $(am__objects_1) ext-date-common.lo \ ext-date.lo libsieve_ext_date_la_OBJECTS = $(am_libsieve_ext_date_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-date-common.Plo \ ./$(DEPDIR)/ext-date.Plo ./$(DEPDIR)/tst-date.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_date_la_SOURCES) DIST_SOURCES = $(libsieve_ext_date_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_date.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-date.c libsieve_ext_date_la_SOURCES = \ $(tests) \ ext-date-common.c \ ext-date.c noinst_HEADERS = \ ext-date-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/date/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/date/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_date.la: $(libsieve_ext_date_la_OBJECTS) $(libsieve_ext_date_la_DEPENDENCIES) $(EXTRA_libsieve_ext_date_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_date_la_OBJECTS) $(libsieve_ext_date_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-date-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-date.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-date.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-date-common.Plo -rm -f ./$(DEPDIR)/ext-date.Plo -rm -f ./$(DEPDIR)/tst-date.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-date-common.Plo -rm -f ./$(DEPDIR)/ext-date.Plo -rm -f ./$(DEPDIR)/tst-date.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/date/ext-date-common.h0000644000175100001700000000301315100335616027212 0ustar00buildbotbuildbot00000000000000#ifndef EXT_DATE_COMMON_H #define EXT_DATE_COMMON_H #include "sieve-common.h" #include /* * Extension */ extern const struct sieve_extension_def date_extension; bool ext_date_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED); /* * Tests */ extern const struct sieve_command_def date_test; extern const struct sieve_command_def currentdate_test; /* * Operations */ enum ext_date_opcode { EXT_DATE_OPERATION_DATE, EXT_DATE_OPERATION_CURRENTDATE, }; extern const struct sieve_operation_def date_operation; extern const struct sieve_operation_def currentdate_operation; /* * Zone string */ bool ext_date_parse_timezone(const char *zone, int *zone_offset_r); /* * Current date */ time_t ext_date_get_current_date(const struct sieve_runtime_env *renv, int *zone_offset_r); /* * Date part */ struct ext_date_part { const char *identifier; const char *(*get_string)(struct tm *tm, int zone_offset); }; const struct ext_date_part *ext_date_part_find(const char *part); const char *ext_date_part_extract(const struct ext_date_part *dpart, struct tm *tm, int zone_offset); /* * Date stringlist */ enum ext_date_timezone_special { EXT_DATE_TIMEZONE_LOCAL = 100, EXT_DATE_TIMEZONE_ORIGINAL = 101 }; struct sieve_stringlist * ext_date_stringlist_create(const struct sieve_runtime_env *renv, struct sieve_stringlist *field_values, int time_zone, const struct ext_date_part *dpart); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/0000755000175100001700000000000015100335670024063 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/tst-body.c0000644000175100001700000002312515100335616025777 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-body-common.h" /* * Body test * * Syntax * body [COMPARATOR] [MATCH-TYPE] [BODY-TRANSFORM] * */ static bool tst_body_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_body_validate(struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_body_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def body_test = { .identifier = "body", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_body_registered, .validate = tst_body_validate, .generate = tst_body_generate }; /* * Body operation */ static bool ext_body_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_body_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def body_operation = { .mnemonic = "body", .ext_def = &body_extension, .dump = ext_body_operation_dump, .execute = ext_body_operation_execute }; /* * Optional operands */ enum tst_body_optional { OPT_BODY_TRANSFORM = SIEVE_MATCH_OPT_LAST }; /* * Tagged arguments */ /* Forward declarations */ static bool tag_body_transform_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tag_body_transform_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def body_raw_tag = { .identifier = "raw", .validate = tag_body_transform_validate, .generate = tag_body_transform_generate }; static const struct sieve_argument_def body_content_tag = { .identifier = "content", .validate = tag_body_transform_validate, .generate = tag_body_transform_generate }; static const struct sieve_argument_def body_text_tag = { .identifier = "text", .validate = tag_body_transform_validate, .generate = tag_body_transform_generate }; /* Argument implementation */ static bool tag_body_transform_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { enum tst_body_transform transform; struct sieve_ast_argument *tag = *arg; /* BODY-TRANSFORM: :raw / :content / :text */ if ((bool)cmd->data) { sieve_argument_validate_error( valdtr, *arg, "the :raw, :content and :text arguments for the body test are mutually " "exclusive, but more than one was specified"); return FALSE; } /* Skip tag */ *arg = sieve_ast_argument_next(*arg); /* :content tag has a string-list argument */ if (sieve_argument_is(tag, body_raw_tag)) transform = TST_BODY_TRANSFORM_RAW; else if (sieve_argument_is(tag, body_text_tag)) transform = TST_BODY_TRANSFORM_TEXT; else if (sieve_argument_is(tag, body_content_tag)) { /* Check syntax: * :content */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING_LIST, FALSE)) return FALSE; /* Assign tag parameters */ tag->parameters = *arg; *arg = sieve_ast_arguments_detach(*arg,1); transform = TST_BODY_TRANSFORM_CONTENT; } else { return FALSE; } /* Signal the presence of this tag */ cmd->data = (void *)TRUE; /* Assign context data */ tag->argument->data = (void *)transform; return TRUE; } /* * Command Registration */ static bool tst_body_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag(valdtr, cmd_reg, ext, &body_raw_tag, OPT_BODY_TRANSFORM); sieve_validator_register_tag(valdtr, cmd_reg, ext, &body_content_tag, OPT_BODY_TRANSFORM); sieve_validator_register_tag(valdtr, cmd_reg, ext, &body_text_tag, OPT_BODY_TRANSFORM); return TRUE; } /* * Validation */ static bool tst_body_validate(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if (!sieve_validate_positional_argument(valdtr, tst, arg, "key list", 1, SAAT_STRING_LIST)) return FALSE; if (!sieve_validator_argument_activate(valdtr, tst, arg, FALSE)) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate(valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_body_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &body_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } static bool tag_body_transform_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { enum tst_body_transform transform = POINTER_CAST_TO(arg->argument->data, enum tst_body_transform); sieve_binary_emit_byte(cgenv->sblock, transform); sieve_generate_argument_parameters(cgenv, cmd, arg); return TRUE; } /* * Code dump */ static bool ext_body_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int transform; int opt_code = 0; sieve_code_dumpf(denv, "BODY"); sieve_code_descend(denv); /* Handle any optional arguments */ for (;;) { int opt; opt = sieve_match_opr_optional_dump(denv, address, &opt_code); if (opt < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_BODY_TRANSFORM: if (!sieve_binary_read_byte(denv->sblock, address, &transform)) return FALSE; switch (transform) { case TST_BODY_TRANSFORM_RAW: sieve_code_dumpf(denv, "BODY-TRANSFORM: RAW"); break; case TST_BODY_TRANSFORM_TEXT: sieve_code_dumpf(denv, "BODY-TRANSFORM: TEXT"); break; case TST_BODY_TRANSFORM_CONTENT: sieve_code_dumpf( denv, "BODY-TRANSFORM: CONTENT"); sieve_code_descend(denv); if (!sieve_opr_stringlist_dump(denv, address, "content types")) return FALSE; sieve_code_ascend(denv); break; default: return FALSE; } break; default: return FALSE; } }; return sieve_opr_stringlist_dump(denv, address, "key list"); } /* * Interpretation */ static int ext_body_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { int opt_code = 0; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); unsigned int transform = TST_BODY_TRANSFORM_TEXT; struct sieve_stringlist *ctype_list, *value_list, *key_list; bool mvalues_active; const char *const *content_types = NULL; int match, ret; /* * Read operands */ /* Optional operands */ ctype_list = NULL; for (;;) { int opt; opt = sieve_match_opr_optional_read(renv, address, &opt_code, &ret, &cmp, &mcht); if (ret < 0) return ret; if (opt == 0) break; switch (opt_code) { case OPT_BODY_TRANSFORM: if (!sieve_binary_read_byte(renv->sblock, address, &transform) || transform > TST_BODY_TRANSFORM_TEXT) { sieve_runtime_trace_error( renv, "invalid body transform type"); return SIEVE_EXEC_BIN_CORRUPT; } if (transform == TST_BODY_TRANSFORM_CONTENT && (ret = sieve_opr_stringlist_read( renv, address, "content-type-list", &ctype_list)) <= 0) return ret; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } /* Read key-list */ ret = sieve_opr_stringlist_read(renv, address, "key-list", &key_list); if (ret <= 0) return ret; if (ctype_list != NULL && sieve_stringlist_read_all(ctype_list, pool_datastack_create(), &content_types) < 0) { sieve_runtime_trace_error( renv, "failed to read content-type-list operand"); return ctype_list->exec_status; } /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "body test"); /* Extract requested parts */ ret = ext_body_get_part_list(renv, (enum tst_body_transform)transform, content_types, &value_list); if (ret <= 0) return ret; /* Disable match values processing as required by RFC */ mvalues_active = sieve_match_values_set_enabled(renv, FALSE); /* Perform match */ match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret); /* Restore match values processing */ (void)sieve_match_values_set_enabled(renv, mvalues_active); if (match < 0) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/ext-body-common.h0000644000175100001700000000120415100335616027252 0ustar00buildbotbuildbot00000000000000#ifndef EXT_BODY_COMMON_H #define EXT_BODY_COMMON_H /* * Types */ enum tst_body_transform { TST_BODY_TRANSFORM_RAW, TST_BODY_TRANSFORM_CONTENT, TST_BODY_TRANSFORM_TEXT }; /* * Extension */ extern const struct sieve_extension_def body_extension; /* * Commands */ extern const struct sieve_command_def body_test; /* * Operations */ extern const struct sieve_operation_def body_operation; /* * Message body part extraction */ int ext_body_get_part_list(const struct sieve_runtime_env *renv, enum tst_body_transform transform, const char *const *content_types, struct sieve_stringlist **strlist_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/Makefile.am0000644000175100001700000000036215100335616026120 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_body.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tsts = \ tst-body.c libsieve_ext_body_la_SOURCES = \ ext-body-common.c \ $(tsts) \ ext-body.c noinst_HEADERS = \ ext-body-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/ext-body.c0000644000175100001700000000217615100335616025770 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension body * ------------------ * * Authors: Stephan Bosch * Original CMUSieve implementation by Timo Sirainen * Specification: RFC 5173 * Implementation: full * Status: testing * */ #include "lib.h" #include "array.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-body-common.h" /* * Extension */ static bool ext_body_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def body_extension = { .name = "body", .validator_load = ext_body_validator_load, SIEVE_EXT_DEFINE_OPERATION(body_operation) }; static bool ext_body_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ sieve_validator_register_command(valdtr, ext, &body_test); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/Makefile.in0000644000175100001700000005422515100335630026134 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/body ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_body_la_LIBADD = am__objects_1 = tst-body.lo am_libsieve_ext_body_la_OBJECTS = ext-body-common.lo $(am__objects_1) \ ext-body.lo libsieve_ext_body_la_OBJECTS = $(am_libsieve_ext_body_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-body-common.Plo \ ./$(DEPDIR)/ext-body.Plo ./$(DEPDIR)/tst-body.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_body_la_SOURCES) DIST_SOURCES = $(libsieve_ext_body_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_body.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tsts = \ tst-body.c libsieve_ext_body_la_SOURCES = \ ext-body-common.c \ $(tsts) \ ext-body.c noinst_HEADERS = \ ext-body-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/body/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/body/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_body.la: $(libsieve_ext_body_la_OBJECTS) $(libsieve_ext_body_la_DEPENDENCIES) $(EXTRA_libsieve_ext_body_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_body_la_OBJECTS) $(libsieve_ext_body_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-body-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-body.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-body.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-body-common.Plo -rm -f ./$(DEPDIR)/ext-body.Plo -rm -f ./$(DEPDIR)/tst-body.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-body-common.Plo -rm -f ./$(DEPDIR)/ext-body.Plo -rm -f ./$(DEPDIR)/tst-body.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/body/ext-body-common.c0000644000175100001700000000505215100335616027252 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mempool.h" #include "buffer.h" #include "array.h" #include "str.h" #include "istream.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-message.h" #include "sieve-interpreter.h" #include "ext-body-common.h" /* * Body part stringlist */ static int ext_body_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void ext_body_stringlist_reset(struct sieve_stringlist *_strlist); struct ext_body_stringlist { struct sieve_stringlist strlist; struct sieve_message_part_data *body_parts; struct sieve_message_part_data *body_parts_iter; }; int ext_body_get_part_list(const struct sieve_runtime_env *renv, enum tst_body_transform transform, const char *const *content_types, struct sieve_stringlist **strlist_r) { static const char *const _no_content_types[] = { "", NULL }; struct ext_body_stringlist *strlist; struct sieve_message_part_data *body_parts = NULL; int ret; *strlist_r = NULL; if (content_types == NULL) content_types = _no_content_types; switch (transform) { case TST_BODY_TRANSFORM_RAW: if ((ret = sieve_message_body_get_raw(renv, &body_parts)) <= 0) return ret; break; case TST_BODY_TRANSFORM_CONTENT: if ((ret = sieve_message_body_get_content(renv, content_types, &body_parts)) <= 0) return ret; break; case TST_BODY_TRANSFORM_TEXT: if ((ret = sieve_message_body_get_text(renv, &body_parts)) <= 0) return ret; break; default: i_unreached(); } strlist = t_new(struct ext_body_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.next_item = ext_body_stringlist_next_item; strlist->strlist.reset = ext_body_stringlist_reset; strlist->body_parts = body_parts; strlist->body_parts_iter = body_parts; *strlist_r = &strlist->strlist; return SIEVE_EXEC_OK; } static int ext_body_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct ext_body_stringlist *strlist = (struct ext_body_stringlist *)_strlist; *str_r = NULL; if (strlist->body_parts_iter->content == NULL) return 0; *str_r = t_str_new_const(strlist->body_parts_iter->content, strlist->body_parts_iter->size); strlist->body_parts_iter++; return 1; } static void ext_body_stringlist_reset(struct sieve_stringlist *_strlist) { struct ext_body_stringlist *strlist = (struct ext_body_stringlist *)_strlist; strlist->body_parts_iter = strlist->body_parts; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/0000755000175100001700000000000015100335670024551 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-binary.c0000644000175100001700000003555615100335616030436 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-script.h" #include "sieve-binary.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-include-common.h" #include "ext-include-limits.h" #include "ext-include-variables.h" #include "ext-include-binary.h" /* * Forward declarations */ static bool ext_include_binary_pre_save(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_error *error_code_r); static bool ext_include_binary_open(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); static bool ext_include_binary_up_to_date(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_compile_flags cpflags); static void ext_include_binary_free(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); /* * Binary include extension */ const struct sieve_binary_extension include_binary_ext = { .extension = &include_extension, .binary_pre_save = ext_include_binary_pre_save, .binary_open = ext_include_binary_open, .binary_free = ext_include_binary_free, .binary_up_to_date = ext_include_binary_up_to_date, }; /* * Binary context management */ struct ext_include_binary_context { struct sieve_binary *binary; struct sieve_binary_block *dependency_block; HASH_TABLE(const struct ext_include_script_info *, struct ext_include_script_info *) included_scripts; ARRAY(struct ext_include_script_info *) include_index; struct sieve_variable_scope_binary *global_vars; bool outdated:1; }; static int ext_include_script_info_cmp(const struct ext_include_script_info *sinfo1, const struct ext_include_script_info *sinfo2) { if (sinfo1 == sinfo2) return 0; if (sinfo1 == NULL || sinfo2 == NULL) return (sinfo1 == NULL ? -1 : 1); if (sinfo1->script == NULL || sinfo2->script == NULL) { if (sinfo1->location != sinfo2->location) return (sinfo1->location > sinfo2->location ? 1 : -1); return strcmp(sinfo1->script_name, sinfo2->script_name); } return sieve_script_cmp(sinfo1->script, sinfo2->script); } static unsigned int ext_include_script_info_hash(const struct ext_include_script_info *sinfo) { if (sinfo == NULL) return 0; return ((unsigned int)sinfo->location + str_hash(sinfo->script_name)); } static struct ext_include_binary_context * ext_include_binary_create_context(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { pool_t pool = sieve_binary_pool(sbin); struct ext_include_binary_context *ctx = p_new(pool, struct ext_include_binary_context, 1); ctx->binary = sbin; hash_table_create(&ctx->included_scripts, pool, 0, ext_include_script_info_hash, ext_include_script_info_cmp); p_array_init(&ctx->include_index, pool, 128); sieve_binary_extension_set(sbin, this_ext, &include_binary_ext, ctx); return ctx; } struct ext_include_binary_context * ext_include_binary_get_context(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { struct ext_include_binary_context *ctx = (struct ext_include_binary_context *) sieve_binary_extension_get_context(sbin, this_ext); if (ctx == NULL) ctx = ext_include_binary_create_context(this_ext, sbin); return ctx; } struct ext_include_binary_context * ext_include_binary_init(const struct sieve_extension *this_ext, struct sieve_binary *sbin, struct sieve_ast *ast) { struct ext_include_ast_context *ast_ctx = ext_include_get_ast_context(this_ext, ast); struct ext_include_binary_context *ctx; /* Get/create our context from the binary we are working on */ ctx = ext_include_binary_get_context(this_ext, sbin); /* Create dependency block */ if (ctx->dependency_block == 0) ctx->dependency_block = sieve_binary_extension_create_block(sbin, this_ext); if (ctx->global_vars == NULL) { ctx->global_vars = sieve_variable_scope_binary_create( ast_ctx->global_vars); sieve_variable_scope_binary_ref(ctx->global_vars); } return ctx; } /* * Script inclusion */ struct ext_include_script_info * ext_include_binary_script_include(struct ext_include_binary_context *binctx, enum ext_include_script_location location, const char *script_name, enum ext_include_flags flags, struct sieve_script *script, struct sieve_binary_block *inc_block) { pool_t pool = sieve_binary_pool(binctx->binary); struct ext_include_script_info *incscript; const struct ext_include_script_info *key; incscript = p_new(pool, struct ext_include_script_info, 1); incscript->id = array_count(&binctx->include_index)+1; incscript->location = location; incscript->script_name = p_strdup(pool, script_name); incscript->flags = flags; incscript->script = script; incscript->block = inc_block; key = incscript; /* Unreferenced on binary_free */ if (script != NULL) sieve_script_ref(script); hash_table_insert(binctx->included_scripts, key, incscript); array_append(&binctx->include_index, &incscript, 1); return incscript; } struct ext_include_script_info * ext_include_binary_script_get_include_info( struct ext_include_binary_context *binctx, enum ext_include_script_location location, const char *script_name) { struct ext_include_script_info key_def; const struct ext_include_script_info *key; i_zero(&key_def); key_def.location = location; key_def.script_name = script_name; key = &key_def; return hash_table_lookup(binctx->included_scripts, key); } const struct ext_include_script_info * ext_include_binary_script_get_included( struct ext_include_binary_context *binctx, unsigned int include_id) { if (include_id > 0 && (include_id - 1) < array_count(&binctx->include_index) ) { struct ext_include_script_info *const *sinfo = array_idx(&binctx->include_index, include_id - 1); return *sinfo; } return NULL; } unsigned int ext_include_binary_script_get_count(struct ext_include_binary_context *binctx) { return array_count(&binctx->include_index); } /* * Variables */ struct sieve_variable_scope_binary * ext_include_binary_get_global_scope(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { struct ext_include_binary_context *binctx = ext_include_binary_get_context(this_ext, sbin); return binctx->global_vars; } /* * Binary extension */ static bool ext_include_binary_pre_save(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin ATTR_UNUSED, void *context, enum sieve_error *error_code_r) { struct ext_include_binary_context *binctx = (struct ext_include_binary_context *)context; struct ext_include_script_info *const *scripts; struct sieve_binary_block *sblock = binctx->dependency_block; unsigned int script_count, i; bool result = TRUE; sieve_binary_block_clear(sblock); scripts = array_get(&binctx->include_index, &script_count); sieve_binary_emit_unsigned(sblock, script_count); for (i = 0; i < script_count; i++) { struct ext_include_script_info *incscript = scripts[i]; if (incscript->block != NULL) { sieve_binary_emit_unsigned( sblock, sieve_binary_block_get_id(incscript->block)); } else { sieve_binary_emit_unsigned(sblock, 0); } sieve_binary_emit_byte(sblock, incscript->location); sieve_binary_emit_cstring(sblock, incscript->script_name); sieve_binary_emit_byte(sblock, incscript->flags); if (incscript->block != NULL) { sieve_script_binary_write_metadata(incscript->script, sblock); } } result = ext_include_variables_save(sblock, binctx->global_vars, error_code_r); return result; } static bool ext_include_binary_open(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context) { struct sieve_instance *svinst = ext->svinst; struct ext_include_context *extctx = ext->context; struct ext_include_binary_context *binctx = (struct ext_include_binary_context *)context; struct sieve_script *bin_script = sieve_binary_script(sbin); const char *cause = (bin_script == NULL ? SIEVE_SCRIPT_CAUSE_ANY : sieve_script_cause(bin_script)); struct sieve_binary_block *sblock; unsigned int depcount, i, block_id; sieve_size_t offset; sblock = sieve_binary_extension_get_block(sbin, ext); if (sblock == NULL) { e_error(svinst->event, "include: failed to load dependency block of binary %s", sieve_binary_path(sbin)); return FALSE; } block_id = sieve_binary_block_get_id(sblock); offset = 0; if (!sieve_binary_read_unsigned(sblock, &offset, &depcount)) { e_error(svinst->event, "include: failed to read include count " "for dependency block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } /* Check include limit */ if (depcount > extctx->set->max_includes) { e_error(svinst->event, "include: binary %s includes too many scripts " "(%u > %u)", sieve_binary_path(sbin), depcount, extctx->set->max_includes); return FALSE; } /* Read dependencies */ for (i = 0; i < depcount; i++) { unsigned int inc_block_id; struct sieve_binary_block *inc_block = NULL; unsigned int location, flags; string_t *script_name; struct sieve_script *script; enum sieve_error error_code; int ret; if (!sieve_binary_read_unsigned(sblock, &offset, &inc_block_id) || !sieve_binary_read_byte(sblock, &offset, &location) || !sieve_binary_read_string(sblock, &offset, &script_name) || !sieve_binary_read_byte(sblock, &offset, &flags)) { /* Binary is corrupt, recompile */ e_error(svinst->event, "include: failed to read included script " "from dependency block %d of binary %s", block_id, sieve_binary_path(sbin)); return FALSE; } if (inc_block_id != 0 && (inc_block=sieve_binary_block_get( sbin, inc_block_id)) == NULL) { e_error(svinst->event, "include: failed to find block %d for included script " "from dependency block %d of binary %s", inc_block_id, block_id, sieve_binary_path(sbin)); return FALSE; } if (location >= EXT_INCLUDE_LOCATION_INVALID) { /* Binary is corrupt, recompile */ e_error(svinst->event, "include: dependency block %d of binary %s " "uses invalid script location (id %d)", block_id, sieve_binary_path(sbin), location); return FALSE; } /* Can we open the script dependency ? */ if (ext_include_open_script(ext, location, cause, str_c(script_name), &script, &error_code) < 0) { if (error_code != SIEVE_ERROR_NOT_FOUND) { /* No, recompile */ return FALSE; } if ((flags & EXT_INCLUDE_FLAG_OPTIONAL) == 0) { /* Not supposed to be missing, recompile */ if (svinst->debug) { e_debug(svinst->event, "include: " "script '%s' included in binary %s is missing, " "so recompile", str_c(script_name), sieve_binary_path(sbin)); } return FALSE; } } else if (inc_block == NULL) { /* Script exists, but it is missing from the binary, recompile no matter what. */ if (svinst->debug) { e_debug(svinst->event, "include: " "script '%s' is missing in binary %s, " "but is now available, so recompile", str_c(script_name), sieve_binary_path(sbin)); } sieve_script_unref(&script); return FALSE; } /* Can we read script metadata ? */ ret = (inc_block == NULL ? 1 : sieve_script_binary_read_metadata(script, sblock, &offset)); if (ret < 0) { /* Binary is corrupt, recompile */ e_error(svinst->event, "include: " "dependency block %d of binary %s " "contains invalid script metadata for script '%s'", block_id, sieve_binary_path(sbin), sieve_script_label(script)); sieve_script_unref(&script); return FALSE; } if (ret == 0) binctx->outdated = TRUE; (void)ext_include_binary_script_include(binctx, location, str_c(script_name), flags, script, inc_block); sieve_script_unref(&script); } if (!ext_include_variables_load(ext, sblock, &offset, &binctx->global_vars)) return FALSE; return TRUE; } static bool ext_include_binary_up_to_date(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin ATTR_UNUSED, void *context, enum sieve_compile_flags cpflags ATTR_UNUSED) { struct ext_include_binary_context *binctx = (struct ext_include_binary_context *)context; return !binctx->outdated; } static void ext_include_binary_free(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin ATTR_UNUSED, void *context) { struct ext_include_binary_context *binctx = (struct ext_include_binary_context *)context; struct hash_iterate_context *hctx; const struct ext_include_script_info *key; struct ext_include_script_info *incscript; /* Release references to all included script objects */ hctx = hash_table_iterate_init(binctx->included_scripts); while (hash_table_iterate(hctx, binctx->included_scripts, &key, &incscript)) sieve_script_unref(&incscript->script); hash_table_iterate_deinit(&hctx); hash_table_destroy(&binctx->included_scripts); if (binctx->global_vars != NULL) sieve_variable_scope_binary_unref(&binctx->global_vars); } /* * Dumping the binary */ bool ext_include_binary_dump(const struct sieve_extension *ext, struct sieve_dumptime_env *denv) { struct sieve_binary *sbin = denv->sbin; struct ext_include_binary_context *binctx = ext_include_binary_get_context(ext, sbin); struct hash_iterate_context *hctx; const struct ext_include_script_info *key; struct ext_include_script_info *incscript; if (!ext_include_variables_dump(denv, binctx->global_vars)) return FALSE; hctx = hash_table_iterate_init(binctx->included_scripts); while (hash_table_iterate(hctx, binctx->included_scripts, &key, &incscript)) { if (incscript->block == NULL) { sieve_binary_dump_sectionf( denv, "Included %s script '%s' (MISSING)", ext_include_script_location_name( incscript->location), incscript->script_name); } else { unsigned int block_id = sieve_binary_block_get_id(incscript->block); sieve_binary_dump_sectionf( denv, "Included %s script '%s' (block: %d)", ext_include_script_location_name( incscript->location), incscript->script_name, block_id); denv->sblock = incscript->block; denv->cdumper = sieve_code_dumper_create(denv); if (denv->cdumper == NULL) return FALSE; sieve_code_dumper_run(denv->cdumper); sieve_code_dumper_free(&(denv->cdumper)); } } hash_table_iterate_deinit(&hctx); return TRUE; } bool ext_include_code_dump(const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED) { struct sieve_binary *sbin = denv->sbin; struct ext_include_binary_context *binctx = ext_include_binary_get_context(ext, sbin); struct ext_include_context *extctx = ext_include_get_context(ext); sieve_ext_variables_dump_set_scope( extctx->var_ext, denv, ext, sieve_variable_scope_binary_get(binctx->global_vars)); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/cmd-return.c0000644000175100001700000000251415100335616026777 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-include-common.h" /* * Return command * * Syntax * return */ static bool cmd_return_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def cmd_return = { .identifier = "return", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .generate = cmd_return_generate }; /* * Return operation */ static int opc_return_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def return_operation = { .mnemonic = "RETURN", .ext_def = &include_extension, .code = EXT_INCLUDE_OPERATION_RETURN, .execute = opc_return_execute }; /* * Code generation */ static bool cmd_return_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &return_operation); return TRUE; } /* * Execution */ static int opc_return_execute (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { ext_include_execute_return(renv); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-common.h0000644000175100001700000000760515100335616030441 0ustar00buildbotbuildbot00000000000000#ifndef EXT_INCLUDE_COMMON_H #define EXT_INCLUDE_COMMON_H #include "lib.h" #include "hash.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-storage.h" #include "ext-include-settings.h" /* * Forward declarations */ struct ext_include_script_info; struct ext_include_binary_context; /* * Types */ enum ext_include_flags { // stored in one byte EXT_INCLUDE_FLAG_ONCE = 0x01, EXT_INCLUDE_FLAG_OPTIONAL = 0x02, EXT_INCLUDE_FLAG_MISSING_AT_UPLOAD = 0x04 }; enum ext_include_script_location { EXT_INCLUDE_LOCATION_PERSONAL, EXT_INCLUDE_LOCATION_GLOBAL, EXT_INCLUDE_LOCATION_INVALID }; static inline const char * ext_include_script_location_name(enum ext_include_script_location location) { switch (location) { case EXT_INCLUDE_LOCATION_PERSONAL: return "personal"; case EXT_INCLUDE_LOCATION_GLOBAL: return "global"; default: break; } return "[INVALID LOCATION]"; } /* * Extension */ extern const struct sieve_extension_def include_extension; extern const struct sieve_binary_extension include_binary_ext; int ext_include_load(const struct sieve_extension *ext, void **context_r); void ext_include_unload(const struct sieve_extension *ext); /* * Commands */ extern const struct sieve_command_def cmd_include; extern const struct sieve_command_def cmd_return; extern const struct sieve_command_def cmd_global; /* * Operations */ enum ext_include_opcode { EXT_INCLUDE_OPERATION_INCLUDE, EXT_INCLUDE_OPERATION_RETURN, EXT_INCLUDE_OPERATION_GLOBAL }; extern const struct sieve_operation_def include_operation; extern const struct sieve_operation_def return_operation; extern const struct sieve_operation_def global_operation; /* * Script access */ int ext_include_open_script(const struct sieve_extension *ext, enum ext_include_script_location location, const char *cause, const char *script_name, struct sieve_script **script_r, enum sieve_error *error_code_r); /* * Context */ /* Extension context */ struct ext_include_context { /* Extension dependencies */ const struct sieve_extension *var_ext; struct sieve_storage *personal_storage; const struct ext_include_settings *set; }; static inline struct ext_include_context * ext_include_get_context(const struct sieve_extension *ext) { return ext->context; } /* AST Context */ struct ext_include_ast_context { struct sieve_variable_scope *global_vars; ARRAY(struct sieve_script *) included_scripts; }; struct ext_include_ast_context * ext_include_create_ast_context(const struct sieve_extension *this_ext, struct sieve_ast *ast, struct sieve_ast *parent); struct ext_include_ast_context * ext_include_get_ast_context(const struct sieve_extension *this_ext, struct sieve_ast *ast); void ext_include_ast_link_included_script( const struct sieve_extension *this_ext, struct sieve_ast *ast, struct sieve_script *script); bool ext_include_validator_have_variables( const struct sieve_extension *this_ext, struct sieve_validator *valdtr); /* Generator context */ void ext_include_register_generator_context( const struct sieve_extension *this_ext, const struct sieve_codegen_env *cgenv); int ext_include_generate_include( const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, enum ext_include_script_location location, const char *script_name, enum ext_include_flags flags, struct sieve_script *script, const struct ext_include_script_info **included_r); /* Interpreter context */ void ext_include_interpreter_context_init( const struct sieve_extension *this_ext, struct sieve_interpreter *interp); int ext_include_execute_include(const struct sieve_runtime_env *renv, unsigned int block_id, enum ext_include_flags flags); void ext_include_execute_return(const struct sieve_runtime_env *renv); struct sieve_variable_storage * ext_include_interpreter_get_global_variables( const struct sieve_extension *this_ext, struct sieve_interpreter *interp); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/Makefile.am0000644000175100001700000000076215100335616026612 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_include.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) cmds = \ cmd-include.c \ cmd-return.c \ cmd-global.c libsieve_ext_include_la_SOURCES = \ $(cmds) \ ext-include-settings.c \ ext-include-common.c \ ext-include-binary.c \ ext-include-variables.c \ ext-include.c noinst_HEADERS = \ ext-include-settings.h \ ext-include-common.h \ ext-include-limits.h \ ext-include-binary.h \ ext-include-variables.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/cmd-include.c0000644000175100001700000002434615100335616027112 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-script.h" #include "sieve-ast.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-binary.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-include-common.h" #include "ext-include-binary.h" /* * Include command * * Syntax: * include [LOCATION] [":once"] [":optional"] * * [LOCATION]: * ":personal" / ":global" */ static bool cmd_include_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_include_pre_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd); static bool cmd_include_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_include_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def cmd_include = { .identifier = "include", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_include_registered, .pre_validate = cmd_include_pre_validate, .validate = cmd_include_validate, .generate = cmd_include_generate, }; /* * Include operation */ static bool opc_include_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int opc_include_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def include_operation = { .mnemonic = "include", .ext_def = &include_extension, .code = EXT_INCLUDE_OPERATION_INCLUDE, .dump = opc_include_dump, .execute = opc_include_execute, }; /* * Context structures */ struct cmd_include_context_data { enum ext_include_script_location location; const char *script_name; struct sieve_script *script; enum ext_include_flags flags; bool location_assigned:1; }; /* * Tagged arguments */ static bool cmd_include_validate_location_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static const struct sieve_argument_def include_personal_tag = { .identifier = "personal", .validate = cmd_include_validate_location_tag, }; static const struct sieve_argument_def include_global_tag = { .identifier = "global", .validate = cmd_include_validate_location_tag, }; static bool cmd_include_validate_boolean_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static const struct sieve_argument_def include_once_tag = { .identifier = "once", .validate = cmd_include_validate_boolean_tag, }; static const struct sieve_argument_def include_optional_tag = { .identifier = "optional", .validate = cmd_include_validate_boolean_tag, }; /* * Tag validation */ static bool cmd_include_validate_location_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *)cmd->data; if (ctx_data->location_assigned) { sieve_argument_validate_error( valdtr, *arg, "include: cannot use location tags ':personal' and ':global' " "multiple times"); return FALSE; } if (sieve_argument_is(*arg, include_personal_tag)) ctx_data->location = EXT_INCLUDE_LOCATION_PERSONAL; else if (sieve_argument_is(*arg, include_global_tag)) ctx_data->location = EXT_INCLUDE_LOCATION_GLOBAL; else return FALSE; ctx_data->location_assigned = TRUE; /* Delete this tag (for now) */ *arg = sieve_ast_arguments_detach(*arg, 1); return TRUE; } static bool cmd_include_validate_boolean_tag(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *)cmd->data; if (sieve_argument_is(*arg, include_once_tag)) ctx_data->flags |= EXT_INCLUDE_FLAG_ONCE; else ctx_data->flags |= EXT_INCLUDE_FLAG_OPTIONAL; /* Delete this tag (for now) */ *arg = sieve_ast_arguments_detach(*arg, 1); return TRUE; } /* * Command registration */ static bool cmd_include_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_personal_tag, 0); sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_global_tag, 0); sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_once_tag, 0); sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_optional_tag, 0); return TRUE; } /* * Command validation */ static bool cmd_include_pre_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data; /* Assign context */ ctx_data = p_new(sieve_command_pool(cmd), struct cmd_include_context_data, 1); ctx_data->location = EXT_INCLUDE_LOCATION_PERSONAL; cmd->data = ctx_data; return TRUE; } static bool cmd_include_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *)cmd->data; struct sieve_script *script; const char *script_name; enum sieve_error error_code = SIEVE_ERROR_NONE; /* Check argument */ if (!sieve_validate_positional_argument(valdtr, cmd, arg, "value", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; /* * Variables are not allowed. */ if (!sieve_argument_is_string_literal(arg)) { sieve_argument_validate_error( valdtr, arg, "the include command requires a constant string for its value argument"); return FALSE; } /* Find the script */ script_name = sieve_ast_argument_strc(arg); if (!sieve_script_name_is_valid(script_name)) { sieve_argument_validate_error( valdtr, arg, "include: invalid script name '%s'", str_sanitize(script_name, 80)); return FALSE; } /* Open script */ if (ext_include_open_script(this_ext, ctx_data->location, sieve_validator_script_cause(valdtr), script_name, &script, &error_code) < 0) { if (error_code != SIEVE_ERROR_NOT_FOUND) { sieve_argument_validate_error( valdtr, arg, "failed to access included %s script '%s' " "(refer to server log for more information)", ext_include_script_location_name(ctx_data->location), str_sanitize(script_name, 80)); return FALSE; /* Not found */ } else { enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr); if ((ctx_data->flags & EXT_INCLUDE_FLAG_OPTIONAL) != 0) { /* :optional */ } else if ((cpflags & SIEVE_COMPILE_FLAG_UPLOADED) != 0) { /* Script is being uploaded */ sieve_argument_validate_warning( valdtr, arg, "included %s script '%s' does not exist (ignored during upload)", ext_include_script_location_name(ctx_data->location), str_sanitize(script_name, 80)); ctx_data->flags |= EXT_INCLUDE_FLAG_MISSING_AT_UPLOAD; } else { /* Should have existed */ sieve_argument_validate_error( valdtr, arg, "included %s script '%s' does not exist", ext_include_script_location_name(ctx_data->location), str_sanitize(script_name, 80)); return FALSE; } } } ext_include_ast_link_included_script(cmd->ext, cmd->ast_node->ast, script); ctx_data->script_name = p_strdup(sieve_command_pool(cmd), script_name); ctx_data->script = script; (void)sieve_ast_arguments_detach(arg, 1); return TRUE; } /* * Code Generation */ static bool cmd_include_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *)cmd->data; const struct ext_include_script_info *included; int ret; /* Compile (if necessary) and include the script into the binary. This yields the id of the binary block containing the compiled byte code. */ ret = ext_include_generate_include(cgenv, cmd, ctx_data->location, ctx_data->script_name, ctx_data->flags, ctx_data->script, &included); if (ret < 0) return FALSE; if (ret > 0) { (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &include_operation); (void)sieve_binary_emit_unsigned(cgenv->sblock, included->id); (void)sieve_binary_emit_byte(cgenv->sblock, ctx_data->flags); } return TRUE; } /* * Code dump */ static bool opc_include_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct ext_include_script_info *included; struct ext_include_binary_context *binctx; unsigned int include_id, flags; sieve_code_dumpf(denv, "INCLUDE:"); sieve_code_mark(denv); if (!sieve_binary_read_unsigned(denv->sblock, address, &include_id)) return FALSE; if (!sieve_binary_read_byte(denv->sblock, address, &flags)) return FALSE; binctx = ext_include_binary_get_context(denv->oprtn->ext, denv->sbin); included = ext_include_binary_script_get_included(binctx, include_id); if (included == NULL || included->block == NULL) return FALSE; sieve_code_descend(denv); sieve_code_dumpf( denv, "script: '%s' %s%s[ID: %d, BLOCK: %d]", sieve_script_label(included->script), ((flags & EXT_INCLUDE_FLAG_ONCE) != 0 ? "(once) " : ""), ((flags & EXT_INCLUDE_FLAG_OPTIONAL) != 0 ? "(optional) " : ""), include_id, sieve_binary_block_get_id(included->block)); return TRUE; } /* * Execution */ static int opc_include_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { unsigned int include_id, flags; if (!sieve_binary_read_unsigned(renv->sblock, address, &include_id)) { sieve_runtime_trace_error(renv, "invalid include-id operand"); return SIEVE_EXEC_BIN_CORRUPT; } if (!sieve_binary_read_unsigned(renv->sblock, address, &flags)) { sieve_runtime_trace_error(renv, "invalid flags operand"); return SIEVE_EXEC_BIN_CORRUPT; } return ext_include_execute_include(renv, include_id, (enum ext_include_flags)flags); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-variables.c0000644000175100001700000001643315100335616031113 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-script.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-include-common.h" #include "ext-include-binary.h" #include "ext-include-variables.h" /* * Variable import-export */ struct sieve_variable * ext_include_variable_import_global(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *variable) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast *ast = cmd->ast_node->ast; struct ext_include_ast_context *ctx = ext_include_get_ast_context(this_ext, ast); struct ext_include_context *extctx = ext_include_get_context(this_ext); struct sieve_variable_scope *local_scope; struct sieve_variable_scope *global_scope = ctx->global_vars; struct sieve_variable *global_var = NULL, *local_var; /* Sanity safeguard */ i_assert (ctx->global_vars != NULL); if (!sieve_variable_identifier_is_valid(variable)) { sieve_command_validate_error( valdtr, cmd, "invalid variable identifier '%s'", str_sanitize(variable,80)); return NULL; } /* Get/Declare the variable in the global scope */ global_var = sieve_variable_scope_declare(global_scope, variable); /* Check whether scope is over its size limit */ if (global_var == NULL) { sieve_command_validate_error( valdtr, cmd, "declaration of new global variable '%s' exceeds the limit " "(max variables: %u)", variable, sieve_variables_get_max_scope_count(extctx->var_ext)); return NULL; } /* Import the global variable into the local script scope */ local_scope = sieve_ext_variables_get_local_scope( extctx->var_ext, valdtr); local_var = sieve_variable_scope_get_variable(local_scope, variable); if (local_var != NULL && local_var->ext != this_ext) { /* FIXME: indicate location of conflicting set statement */ sieve_command_validate_error( valdtr, cmd, "declaration of new global variable '%s' " "conflicts with earlier local use", variable); return NULL; } return sieve_variable_scope_import(local_scope, global_var); } /* * Binary symbol table */ bool ext_include_variables_save(struct sieve_binary_block *sblock, struct sieve_variable_scope_binary *global_vars, enum sieve_error *error_code_r ATTR_UNUSED) { struct sieve_variable_scope *global_scope = sieve_variable_scope_binary_get(global_vars); unsigned int count = sieve_variable_scope_size(global_scope); sieve_size_t jump; sieve_binary_emit_unsigned(sblock, count); jump = sieve_binary_emit_offset(sblock, 0); if (count > 0) { unsigned int size, i; struct sieve_variable *const *vars = sieve_variable_scope_get_variables(global_scope, &size); for (i = 0; i < size; i++) { sieve_binary_emit_cstring(sblock, vars[i]->identifier); } } sieve_binary_resolve_offset(sblock, jump); return TRUE; } bool ext_include_variables_load( const struct sieve_extension *this_ext, struct sieve_binary_block *sblock, sieve_size_t *offset, struct sieve_variable_scope_binary **global_vars_r) { struct ext_include_context *extctx = ext_include_get_context(this_ext); /* Sanity assert */ i_assert(*global_vars_r == NULL); *global_vars_r = sieve_variable_scope_binary_read( this_ext->svinst, extctx->var_ext, this_ext, sblock, offset); return (*global_vars_r != NULL); } bool ext_include_variables_dump(struct sieve_dumptime_env *denv, struct sieve_variable_scope_binary *global_vars) { struct sieve_variable_scope *global_scope = sieve_variable_scope_binary_get(global_vars); unsigned int size; struct sieve_variable *const *vars; i_assert(global_scope != NULL); vars = sieve_variable_scope_get_variables(global_scope, &size); if (size > 0) { unsigned int i; sieve_binary_dump_sectionf(denv, "Global variables"); for (i = 0; i < size; i++) { sieve_binary_dumpf(denv, "%3d: '%s' \n", i, vars[i]->identifier); } } return TRUE; } /* * Global variables namespace */ static bool vnspc_global_variables_validate(struct sieve_validator *valdtr, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, bool assignment); static bool vnspc_global_variables_generate(const struct sieve_codegen_env *cgenv, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd, void *var_data); static const struct sieve_variables_namespace_def global_variables_namespace = { SIEVE_OBJECT("global", NULL, 0), .validate = vnspc_global_variables_validate, .generate = vnspc_global_variables_generate }; static bool vnspc_global_variables_validate(struct sieve_validator *valdtr, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED, ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, bool assignment ATTR_UNUSED) { const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); struct sieve_ast *ast = arg->ast; struct ext_include_context *extctx = ext_include_get_context(this_ext); struct ext_include_ast_context *ctx = ext_include_get_ast_context(this_ext, ast); struct sieve_variable *var = NULL; const struct sieve_variable_name *name_element; const char *variable; /* Sanity safeguard */ i_assert (ctx->global_vars != NULL); /* Check variable name */ if (array_count(var_name) != 2) { sieve_argument_validate_error( valdtr, arg, "invalid variable name within global namespace: " "encountered sub-namespace"); return FALSE; } name_element = array_idx(var_name, 1); if (name_element->num_variable >= 0) { sieve_argument_validate_error( valdtr, arg, "invalid variable name within global namespace: " "encountered numeric variable name"); return FALSE; } variable = str_c(name_element->identifier); /* Get/Declare the variable in the global scope */ var = sieve_variable_scope_declare(ctx->global_vars, variable); if (var == NULL) { sieve_argument_validate_error( valdtr, arg, "(implicit) declaration of new global variable '%s' " "exceeds the limit (max variables: %u)", variable, sieve_variables_get_max_scope_count(extctx->var_ext)); return FALSE; } *var_data = var; return TRUE; } bool vnspc_global_variables_generate( const struct sieve_codegen_env *cgenv, const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg ATTR_UNUSED, struct sieve_command *cmd ATTR_UNUSED, void *var_data) { const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); struct ext_include_context *extctx = ext_include_get_context(this_ext); struct sieve_variable *var = (struct sieve_variable *)var_data; sieve_variables_opr_variable_emit(cgenv->sblock, extctx->var_ext, var); return TRUE; } void ext_include_variables_global_namespace_init( const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_include_context *extctx = ext_include_get_context(this_ext); sieve_variables_namespace_register(extctx->var_ext, valdtr, this_ext, &global_variables_namespace); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-limits.h0000644000175100001700000000030115100335616030434 0ustar00buildbotbuildbot00000000000000#ifndef EXT_INCLUDE_LIMITS_H #define EXT_INCLUDE_LIMITS_H #include "sieve-common.h" #define EXT_INCLUDE_DEFAULT_MAX_NESTING_DEPTH 10 #define EXT_INCLUDE_DEFAULT_MAX_INCLUDES 255 #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-variables.h0000644000175100001700000000174515100335616031120 0ustar00buildbotbuildbot00000000000000#ifndef EXT_INCLUDE_VARIABLES_H #define EXT_INCLUDE_VARIABLES_H #include "sieve-common.h" #include "sieve-ext-variables.h" #include "ext-include-common.h" /* * Variable import-export */ struct sieve_variable * ext_include_variable_import_global(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *variable); /* * Binary symbol table */ bool ext_include_variables_save(struct sieve_binary_block *sblock, struct sieve_variable_scope_binary *global_vars, enum sieve_error *error_code_r); bool ext_include_variables_load( const struct sieve_extension *this_ext, struct sieve_binary_block *sblock, sieve_size_t *offset, struct sieve_variable_scope_binary **global_vars_r); bool ext_include_variables_dump( struct sieve_dumptime_env *denv, struct sieve_variable_scope_binary *global_vars); /* * Validation */ void ext_include_variables_global_namespace_init( const struct sieve_extension *this_ext, struct sieve_validator *valdtr); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include.c0000644000175100001700000000600415100335616027136 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension include * ----------------- * * Authors: Stephan Bosch * Specification: RFC 6609 * Implementation: full * Status: testing * */ /* FIXME: Current include implementation does not allow for parts of the script to be located in external binaries; all included scripts are recompiled and the resulting byte code is imported into the main binary in separate blocks. */ #include "lib.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-binary.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-include-common.h" #include "ext-include-binary.h" #include "ext-include-variables.h" /* * Operations */ static const struct sieve_operation_def *ext_include_operations[] = { &include_operation, &return_operation, &global_operation, }; /* * Extension */ /* Forward declaration */ static bool ext_include_validator_load(const struct sieve_extension *ext, struct sieve_validator *validator); static bool ext_include_generator_load(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); static bool ext_include_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); static bool ext_include_binary_load(const struct sieve_extension *ext, struct sieve_binary *binary); /* Extension objects */ const struct sieve_extension_def include_extension = { .name = "include", .version = 2, .load = ext_include_load, .unload = ext_include_unload, .validator_load = ext_include_validator_load, .generator_load = ext_include_generator_load, .interpreter_load = ext_include_interpreter_load, .binary_load = ext_include_binary_load, .binary_dump = ext_include_binary_dump, .code_dump = ext_include_code_dump, SIEVE_EXT_DEFINE_OPERATIONS(ext_include_operations), }; static bool ext_include_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new commands */ sieve_validator_register_command(valdtr, ext, &cmd_include); sieve_validator_register_command(valdtr, ext, &cmd_return); sieve_validator_register_command(valdtr, ext, &cmd_global); /* Initialize global variables namespace */ ext_include_variables_global_namespace_init(ext, valdtr); return TRUE; } static bool ext_include_generator_load(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv) { ext_include_register_generator_context(ext, cgenv); return TRUE; } static bool ext_include_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { ext_include_interpreter_context_init(ext, renv->interp); return TRUE; } static bool ext_include_binary_load(const struct sieve_extension *ext, struct sieve_binary *sbin) { (void)ext_include_binary_get_context(ext, sbin); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-common.c0000644000175100001700000006247215100335616030437 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str-sanitize.h" #include "home-expand.h" #include "settings.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-script.h" #include "sieve-storage.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-include-common.h" #include "ext-include-binary.h" #include "ext-include-variables.h" /* * Forward declarations */ /* Generator context */ struct ext_include_generator_context { unsigned int nesting_depth; enum ext_include_script_location location; const char *script_name; struct sieve_script *script; struct ext_include_generator_context *parent; }; static inline struct ext_include_generator_context * ext_include_get_generator_context(const struct sieve_extension *ext_this, struct sieve_generator *gentr); /* Interpreter context */ struct ext_include_interpreter_global { ARRAY(struct sieve_script *) included_scripts; struct sieve_variable_scope_binary *var_scope; struct sieve_variable_storage *var_storage; }; struct ext_include_interpreter_context { struct ext_include_interpreter_context *parent; struct ext_include_interpreter_global *global; struct sieve_interpreter *interp; pool_t pool; unsigned int nesting_depth; struct sieve_script *script; const struct ext_include_script_info *script_info; const struct ext_include_script_info *include; bool returned; }; /* * Extension configuration */ /* Extension hooks */ int ext_include_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct sieve_extension *var_ext; const struct ext_include_settings *set; struct ext_include_context *extctx; const char *error; /* Extension dependencies */ if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0) return -1; if (settings_get(svinst->event, &ext_include_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_include_context, 1); extctx->var_ext = var_ext; extctx->set = set; *context_r = extctx; return 0; } void ext_include_unload(const struct sieve_extension *ext) { struct ext_include_context *extctx = ext->context; if (extctx == NULL) return; sieve_storage_unref(&extctx->personal_storage); settings_free(extctx->set); i_free(extctx); } /* * Script access */ static int ext_include_open_script_personal(struct sieve_instance *svinst, struct ext_include_context *extctx, const char *cause, const char *script_name, struct sieve_script **script_r, enum sieve_error *error_code_r) { if (extctx->personal_storage == NULL && sieve_storage_create_personal(svinst, NULL, cause, 0, &extctx->personal_storage, error_code_r) < 0) return -1; return sieve_storage_open_script(extctx->personal_storage, script_name, script_r, error_code_r); } static int ext_include_open_script_global(struct sieve_instance *svinst, const char *cause, const char *script_name, struct sieve_script **script_r, enum sieve_error *error_code_r) { return sieve_script_create_open(svinst, cause, SIEVE_STORAGE_TYPE_GLOBAL, script_name, script_r, error_code_r, NULL); } int ext_include_open_script(const struct sieve_extension *ext, enum ext_include_script_location location, const char *cause, const char *script_name, struct sieve_script **script_r, enum sieve_error *error_code_r) { struct sieve_instance *svinst = ext->svinst; struct ext_include_context *extctx = ext->context; int ret; *script_r = NULL; switch (location) { case EXT_INCLUDE_LOCATION_PERSONAL: ret = ext_include_open_script_personal(svinst, extctx, cause, script_name, script_r, error_code_r); break; case EXT_INCLUDE_LOCATION_GLOBAL: ret = ext_include_open_script_global(svinst, cause, script_name, script_r, error_code_r); break; default: i_unreached(); } return ret; } /* * AST context management */ static void ext_include_ast_free(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_ast *ast ATTR_UNUSED, void *context) { struct ext_include_ast_context *actx = (struct ext_include_ast_context *)context; struct sieve_script **scripts; unsigned int count, i; /* Unreference included scripts */ scripts = array_get_modifiable(&actx->included_scripts, &count); for (i = 0; i < count; i++) { sieve_script_unref(&scripts[i]); } /* Unreference variable scopes */ if (actx->global_vars != NULL) sieve_variable_scope_unref(&actx->global_vars); } static const struct sieve_ast_extension include_ast_extension = { &include_extension, ext_include_ast_free }; struct ext_include_ast_context * ext_include_create_ast_context(const struct sieve_extension *this_ext, struct sieve_ast *ast, struct sieve_ast *parent) { struct ext_include_ast_context *actx; pool_t pool = sieve_ast_pool(ast); actx = p_new(pool, struct ext_include_ast_context, 1); p_array_init(&actx->included_scripts, pool, 32); if (parent != NULL) { struct ext_include_ast_context *parent_ctx = (struct ext_include_ast_context *) sieve_ast_extension_get_context(parent, this_ext); actx->global_vars = parent_ctx->global_vars; i_assert(actx->global_vars != NULL); sieve_variable_scope_ref(actx->global_vars); } else { struct ext_include_context *extctx = ext_include_get_context(this_ext); actx->global_vars = sieve_variable_scope_create( this_ext->svinst, extctx->var_ext, this_ext); } sieve_ast_extension_register(ast, this_ext, &include_ast_extension, actx); return actx; } struct ext_include_ast_context * ext_include_get_ast_context(const struct sieve_extension *this_ext, struct sieve_ast *ast) { struct ext_include_ast_context *actx = (struct ext_include_ast_context *) sieve_ast_extension_get_context(ast, this_ext); if (actx != NULL) return actx; return ext_include_create_ast_context(this_ext, ast, NULL); } void ext_include_ast_link_included_script( const struct sieve_extension *this_ext, struct sieve_ast *ast, struct sieve_script *script) { struct ext_include_ast_context *actx = ext_include_get_ast_context(this_ext, ast); array_append(&actx->included_scripts, &script, 1); } bool ext_include_validator_have_variables( const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_include_context *extctx = ext_include_get_context(this_ext); return sieve_ext_variables_is_active(extctx->var_ext, valdtr); } /* * Generator context management */ static struct ext_include_generator_context * ext_include_create_generator_context( struct sieve_generator *gentr, struct ext_include_generator_context *parent, enum ext_include_script_location location, const char *script_name, struct sieve_script *script) { struct ext_include_generator_context *ctx; pool_t pool = sieve_generator_pool(gentr); ctx = p_new(pool, struct ext_include_generator_context, 1); ctx->parent = parent; ctx->location = location; ctx->script_name = p_strdup(pool, script_name); ctx->script = script; if (parent == NULL) ctx->nesting_depth = 0; else ctx->nesting_depth = parent->nesting_depth + 1; return ctx; } static inline struct ext_include_generator_context * ext_include_get_generator_context(const struct sieve_extension *this_ext, struct sieve_generator *gentr) { return (struct ext_include_generator_context *) sieve_generator_extension_get_context(gentr, this_ext); } static inline void ext_include_initialize_generator_context( const struct sieve_extension *this_ext, struct sieve_generator *gentr, struct ext_include_generator_context *parent, enum ext_include_script_location location, const char *script_name, struct sieve_script *script) { sieve_generator_extension_set_context( gentr, this_ext, ext_include_create_generator_context(gentr, parent, location, script_name, script)); } void ext_include_register_generator_context( const struct sieve_extension *this_ext, const struct sieve_codegen_env *cgenv) { struct ext_include_generator_context *ctx = ext_include_get_generator_context(this_ext, cgenv->gentr); /* Initialize generator context if necessary */ if (ctx == NULL) { i_assert(cgenv->script != NULL); enum ext_include_script_location location; const char *storage_type = sieve_script_storage_type(cgenv->script); if (strcasecmp(storage_type, SIEVE_STORAGE_TYPE_PERSONAL) == 0) location = EXT_INCLUDE_LOCATION_PERSONAL; else if (strcasecmp(storage_type, SIEVE_STORAGE_TYPE_GLOBAL) == 0) location = EXT_INCLUDE_LOCATION_GLOBAL; else location = EXT_INCLUDE_LOCATION_INVALID; ctx = ext_include_create_generator_context( cgenv->gentr, NULL, location, sieve_script_name(cgenv->script), cgenv->script); sieve_generator_extension_set_context( cgenv->gentr, this_ext, ctx); } /* Initialize ast context if necessary */ (void)ext_include_get_ast_context(this_ext, cgenv->ast); (void)ext_include_binary_init(this_ext, cgenv->sbin, cgenv->ast); } /* * Runtime initialization */ static int ext_include_runtime_init(const struct sieve_extension *this_ext, const struct sieve_runtime_env *renv, void *context, bool deferred ATTR_UNUSED) { struct ext_include_interpreter_context *ctx = (struct ext_include_interpreter_context *)context; struct ext_include_context *extctx = ext_include_get_context(this_ext); if (ctx->parent == NULL) { ctx->global = p_new(ctx->pool, struct ext_include_interpreter_global, 1); p_array_init(&ctx->global->included_scripts, ctx->pool, 10); ctx->global->var_scope = ext_include_binary_get_global_scope( this_ext, renv->sbin); ctx->global->var_storage = sieve_variable_storage_create(extctx->var_ext, ctx->pool, ctx->global->var_scope); } else { ctx->global = ctx->parent->global; } sieve_ext_variables_runtime_set_storage(extctx->var_ext, renv, this_ext, ctx->global->var_storage); return SIEVE_EXEC_OK; } static struct sieve_interpreter_extension include_interpreter_extension = { .ext_def = &include_extension, .run = ext_include_runtime_init }; /* * Interpreter context management */ static struct ext_include_interpreter_context * ext_include_interpreter_context_create( struct sieve_interpreter *interp, struct ext_include_interpreter_context *parent, struct sieve_script *script, const struct ext_include_script_info *sinfo) { struct ext_include_interpreter_context *ctx; pool_t pool = sieve_interpreter_pool(interp); ctx = p_new(pool, struct ext_include_interpreter_context, 1); ctx->pool = pool; ctx->parent = parent; ctx->interp = interp; ctx->script = script; ctx->script_info = sinfo; if (parent == NULL) ctx->nesting_depth = 0; else ctx->nesting_depth = parent->nesting_depth + 1; return ctx; } static inline struct ext_include_interpreter_context * ext_include_get_interpreter_context(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { return (struct ext_include_interpreter_context *) sieve_interpreter_extension_get_context(interp, this_ext); } static inline struct ext_include_interpreter_context * ext_include_interpreter_context_init_child( const struct sieve_extension *this_ext, struct sieve_interpreter *interp, struct ext_include_interpreter_context *parent, struct sieve_script *script, const struct ext_include_script_info *sinfo) { struct ext_include_interpreter_context *ctx = ext_include_interpreter_context_create(interp, parent, script, sinfo); sieve_interpreter_extension_register(interp, this_ext, &include_interpreter_extension, ctx); return ctx; } void ext_include_interpreter_context_init( const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_include_interpreter_context *ctx = ext_include_get_interpreter_context(this_ext, interp); /* Is this is the top-level interpreter ? */ if (ctx == NULL) { struct sieve_script *script; /* Initialize top context */ script = sieve_interpreter_script(interp); ctx = ext_include_interpreter_context_create(interp, NULL, script, NULL); sieve_interpreter_extension_register( interp, this_ext, &include_interpreter_extension, ctx); } } struct sieve_variable_storage * ext_include_interpreter_get_global_variables( const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_include_interpreter_context *ctx = ext_include_get_interpreter_context(this_ext, interp); return ctx->global->var_storage; } /* * Including a script during code generation */ int ext_include_generate_include( const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, enum ext_include_script_location location, const char *script_name, enum ext_include_flags flags, struct sieve_script *script, const struct ext_include_script_info **included_r) { const struct sieve_extension *this_ext = cmd->ext; struct ext_include_context *extctx = this_ext->context; int result = 1; struct sieve_ast *ast; struct sieve_binary *sbin = cgenv->sbin; struct sieve_generator *gentr = cgenv->gentr; struct ext_include_binary_context *binctx; struct sieve_generator *subgentr; struct ext_include_generator_context *ctx = ext_include_get_generator_context(this_ext, gentr); struct ext_include_generator_context *pctx; struct sieve_error_handler *ehandler = sieve_generator_error_handler(gentr); struct ext_include_script_info *included; *included_r = NULL; /* Just to be sure: do not include more scripts when errors have occured already. */ if (sieve_get_errors(ehandler) > 0) return -1; /* Limit nesting level */ if (ctx->nesting_depth >= extctx->set->max_nesting_depth) { sieve_command_generate_error( gentr, cmd, "cannot nest includes deeper than %d levels", extctx->set->max_nesting_depth); return -1; } /* Check for circular include */ if ((flags & EXT_INCLUDE_FLAG_ONCE) == 0) { pctx = ctx; while (pctx != NULL) { if (pctx->location == location && strcmp(pctx->script_name, script_name) == 0 && (pctx->script == NULL || script == NULL || sieve_script_equals(pctx->script, script))) { /* Just drop circular include when uploading inactive script; not an error */ if ((cgenv->flags & SIEVE_COMPILE_FLAG_UPLOADED) != 0 && (cgenv->flags & SIEVE_COMPILE_FLAG_ACTIVATED) == 0) { sieve_command_generate_warning( gentr, cmd, "circular include (ignored during upload)"); return 0; } sieve_command_generate_error(gentr, cmd, "circular include"); return -1; } pctx = pctx->parent; } } /* Get binary context */ binctx = ext_include_binary_init(this_ext, sbin, cgenv->ast); /* Is the script already compiled into the current binary? */ included = ext_include_binary_script_get_include_info( binctx, location, script_name); if (included != NULL) { /* Yes, only update flags */ if ((flags & EXT_INCLUDE_FLAG_OPTIONAL) == 0) included->flags &= ENUM_NEGATE(EXT_INCLUDE_FLAG_OPTIONAL); if ((flags & EXT_INCLUDE_FLAG_ONCE) == 0) included->flags &= ENUM_NEGATE(EXT_INCLUDE_FLAG_ONCE); } else { enum sieve_compile_flags cpflags = cgenv->flags; /* No, include new script */ /* Check whether include limit is exceeded */ if (ext_include_binary_script_get_count(binctx) >= extctx->set->max_includes) { sieve_command_generate_error( gentr, cmd, "failed to include script '%s': " "no more than %u includes allowed", str_sanitize(script_name, 80), extctx->set->max_includes); return -1; } /* Allocate a new block in the binary and mark the script as included. */ if (script == NULL) { /* Just making an empty entry to mark a missing script */ i_assert((flags & EXT_INCLUDE_FLAG_MISSING_AT_UPLOAD) != 0 || (flags & EXT_INCLUDE_FLAG_OPTIONAL) != 0); included = ext_include_binary_script_include( binctx, location, script_name, flags, NULL, NULL); result = 0; } else { struct sieve_binary_block *inc_block = sieve_binary_block_create(sbin); /* Real include */ included = ext_include_binary_script_include( binctx, location, script_name, flags, script, inc_block); /* Parse */ if ((ast = sieve_parse(script, ehandler, NULL)) == NULL) { sieve_command_generate_error( gentr, cmd, "failed to parse included script '%s'", str_sanitize(script_name, 80)); return -1; } /* Included scripts inherit global variable scope */ (void)ext_include_create_ast_context( this_ext, ast, cmd->ast_node->ast); if (location == EXT_INCLUDE_LOCATION_GLOBAL) { cpflags &= ENUM_NEGATE(SIEVE_EXECUTE_FLAG_NOGLOBAL); } else { cpflags |= SIEVE_EXECUTE_FLAG_NOGLOBAL; } /* Validate */ if (!sieve_validate(ast, ehandler, cpflags, NULL)) { sieve_command_generate_error( gentr, cmd, "failed to validate included script '%s'", str_sanitize(script_name, 80)); sieve_ast_unref(&ast); return -1; } /* Generate FIXME: It might not be a good idea to recurse code generation for included scripts. */ subgentr = sieve_generator_create(ast, ehandler, cpflags); ext_include_initialize_generator_context( cmd->ext, subgentr, ctx, location, script_name, script); if (sieve_generator_run(subgentr, &inc_block) == NULL) { sieve_command_generate_error( gentr, cmd, "failed to generate code for included script '%s'", str_sanitize(script_name, 80)); result = -1; } sieve_generator_free(&subgentr); /* Cleanup */ sieve_ast_unref(&ast); } } if (result > 0) *included_r = included; return result; } /* * Executing an included script during interpretation */ static bool ext_include_runtime_check_circular( struct ext_include_interpreter_context *ctx, const struct ext_include_script_info *include) { struct ext_include_interpreter_context *pctx; pctx = ctx; while (pctx != NULL) { if (sieve_script_equals(include->script, pctx->script)) return TRUE; pctx = pctx->parent; } return FALSE; } static bool ext_include_runtime_include_mark(struct ext_include_interpreter_context *ctx, const struct ext_include_script_info *include, bool once) { struct sieve_script *const *includes; unsigned int count, i; includes = array_get(&ctx->global->included_scripts, &count); for (i = 0; i < count; i++) { if (sieve_script_equals(include->script, includes[i])) return (!once); } array_append(&ctx->global->included_scripts, &include->script, 1); return TRUE; } int ext_include_execute_include(const struct sieve_runtime_env *renv, unsigned int include_id, enum ext_include_flags flags) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_extension *this_ext = renv->oprtn->ext; int result = SIEVE_EXEC_OK; struct ext_include_interpreter_context *ctx; const struct ext_include_script_info *included; struct ext_include_binary_context *binctx = ext_include_binary_get_context(this_ext, renv->sbin); bool once = ((flags & EXT_INCLUDE_FLAG_ONCE) != 0); unsigned int block_id; /* Check for invalid include id (== corrupt binary) */ included = ext_include_binary_script_get_included(binctx, include_id); if (included == NULL || included->block == NULL) { sieve_runtime_trace_error( renv, "include: include id %d is invalid", include_id); return SIEVE_EXEC_BIN_CORRUPT; } ctx = ext_include_get_interpreter_context(this_ext, renv->interp); block_id = sieve_binary_block_get_id(included->block); /* If :once modifier is specified, check for duplicate include */ if (ext_include_runtime_include_mark(ctx, included, once)) { sieve_runtime_trace( renv, SIEVE_TRLVL_NONE, "include: start script '%s' [inc id: %d, block: %d]", sieve_script_name(included->script), include_id, block_id); } else { /* skip */ sieve_runtime_trace( renv, SIEVE_TRLVL_NONE, "include: skipped include for script '%s' " "[inc id: %d, block: %d]; already run once", sieve_script_name(included->script), include_id, block_id); return result; } /* Check circular include during interpretation as well. * Let's not trust binaries. */ if (ext_include_runtime_check_circular(ctx, included)) { sieve_runtime_trace_error(renv, "include: circular include of script '%s' " "[inc id: %d, block: %d]", sieve_script_name(included->script), include_id, block_id); /* Situation has no valid way to emerge at runtime */ return SIEVE_EXEC_BIN_CORRUPT; } if (ctx->parent == NULL) { struct ext_include_interpreter_context *curctx = NULL; struct sieve_error_handler *ehandler = renv->ehandler; struct sieve_interpreter *subinterp; bool interrupted = FALSE; /* We are the top-level interpreter instance */ if (result == SIEVE_EXEC_OK) { struct sieve_execute_env eenv_new = *eenv; if (included->location != EXT_INCLUDE_LOCATION_GLOBAL) eenv_new.flags |= SIEVE_EXECUTE_FLAG_NOGLOBAL; else { eenv_new.flags &= ENUM_NEGATE(SIEVE_EXECUTE_FLAG_NOGLOBAL); } /* Create interpreter for top-level included script (first sub-interpreter) */ subinterp = sieve_interpreter_create_for_block( included->block, included->script, renv->interp, &eenv_new, ehandler); if (subinterp != NULL) { curctx = ext_include_interpreter_context_init_child( this_ext, subinterp, ctx, included->script, included); /* Activate and start the top-level included script */ result = sieve_interpreter_start( subinterp, renv->result, &interrupted); } else { result = SIEVE_EXEC_BIN_CORRUPT; } } /* Included scripts can have includes of their own. This is not implemented recursively. Rather, the sub-interpreter interrupts and defers the include to the top-level interpreter, which is here. */ if (result == SIEVE_EXEC_OK && interrupted && !curctx->returned) { while (result == SIEVE_EXEC_OK) { if (((interrupted && curctx->returned) || (!interrupted)) && curctx->parent != NULL) { const struct ext_include_script_info *ended_script = curctx->script_info; /* Sub-interpreter ended or executed return */ /* Ascend interpreter stack */ curctx = curctx->parent; sieve_interpreter_free(&subinterp); sieve_runtime_trace(renv, SIEVE_TRLVL_NONE, "include: script '%s' ended " "[inc id: %d, block: %d]", sieve_script_name(ended_script->script), ended_script->id, sieve_binary_block_get_id(ended_script->block)); /* This is the top-most sub-interpreter, bail out */ if (curctx->parent == NULL) break; subinterp = curctx->interp; /* Continue parent */ curctx->include = NULL; curctx->returned = FALSE; result = sieve_interpreter_continue( subinterp, &interrupted); } else { if (curctx->include != NULL) { /* Sub-include requested */ if (result == SIEVE_EXEC_OK) { struct sieve_execute_env eenv_new = *eenv; if (curctx->include->location != EXT_INCLUDE_LOCATION_GLOBAL) eenv_new.flags |= SIEVE_EXECUTE_FLAG_NOGLOBAL; else { eenv_new.flags &= ENUM_NEGATE(SIEVE_EXECUTE_FLAG_NOGLOBAL); } /* Create sub-interpreter */ subinterp = sieve_interpreter_create_for_block( curctx->include->block, curctx->include->script, curctx->interp, &eenv_new, ehandler); if (subinterp != NULL) { curctx = ext_include_interpreter_context_init_child( this_ext, subinterp, curctx, curctx->include->script, curctx->include); /* Start the sub-include's interpreter */ curctx->include = NULL; curctx->returned = FALSE; result = sieve_interpreter_start( subinterp, renv->result, &interrupted); } else { result = SIEVE_EXEC_BIN_CORRUPT; } } } else { /* Sub-interpreter was interrupted outside this extension, probably stop command was executed. Generate an interrupt ourselves, ending all script execution. */ sieve_interpreter_interrupt(renv->interp); break; } } } } /* Free any sub-interpreters that might still be active */ while (curctx != NULL && curctx->parent != NULL) { struct ext_include_interpreter_context *nextctx = curctx->parent; struct sieve_interpreter *killed_interp = curctx->interp; const struct ext_include_script_info *ended_script = curctx->script_info; /* This kills curctx too */ sieve_interpreter_free(&killed_interp); sieve_runtime_trace( renv, SIEVE_TRLVL_NONE, "include: script '%s' ended [id: %d, block: %d]", sieve_script_name(ended_script->script), ended_script->id, sieve_binary_block_get_id(ended_script->block)); /* Luckily we recorded the parent earlier */ curctx = nextctx; } } else { /* We are an included script already, defer inclusion to main interpreter */ ctx->include = included; sieve_interpreter_interrupt(renv->interp); } return result; } void ext_include_execute_return(const struct sieve_runtime_env *renv) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_include_interpreter_context *ctx = ext_include_get_interpreter_context(this_ext, renv->interp); sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "return: exiting included script"); ctx->returned = TRUE; sieve_interpreter_interrupt(renv->interp); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-settings.c0000644000175100001700000000177515100335616031006 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-include-limits.h" #include "ext-include-settings.h" #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_include_"#name, name, \ struct ext_include_settings) static const struct setting_define ext_include_setting_defines[] = { DEF(UINT, max_nesting_depth), DEF(UINT, max_includes), SETTING_DEFINE_LIST_END, }; static const struct ext_include_settings ext_include_default_settings = { .max_nesting_depth = EXT_INCLUDE_DEFAULT_MAX_NESTING_DEPTH, .max_includes = EXT_INCLUDE_DEFAULT_MAX_INCLUDES, }; const struct setting_parser_info ext_include_setting_parser_info = { .name = "sieve_include", .defines = ext_include_setting_defines, .defaults = &ext_include_default_settings, .struct_size = sizeof(struct ext_include_settings), .pool_offset1 = 1 + offsetof(struct ext_include_settings, pool), }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/Makefile.in0000644000175100001700000005724115100335630026623 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_include_la_LIBADD = am__objects_1 = cmd-include.lo cmd-return.lo cmd-global.lo am_libsieve_ext_include_la_OBJECTS = $(am__objects_1) \ ext-include-settings.lo ext-include-common.lo \ ext-include-binary.lo ext-include-variables.lo ext-include.lo libsieve_ext_include_la_OBJECTS = \ $(am_libsieve_ext_include_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-global.Plo \ ./$(DEPDIR)/cmd-include.Plo ./$(DEPDIR)/cmd-return.Plo \ ./$(DEPDIR)/ext-include-binary.Plo \ ./$(DEPDIR)/ext-include-common.Plo \ ./$(DEPDIR)/ext-include-settings.Plo \ ./$(DEPDIR)/ext-include-variables.Plo \ ./$(DEPDIR)/ext-include.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_include_la_SOURCES) DIST_SOURCES = $(libsieve_ext_include_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_include.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../variables \ $(LIBDOVECOT_INCLUDE) cmds = \ cmd-include.c \ cmd-return.c \ cmd-global.c libsieve_ext_include_la_SOURCES = \ $(cmds) \ ext-include-settings.c \ ext-include-common.c \ ext-include-binary.c \ ext-include-variables.c \ ext-include.c noinst_HEADERS = \ ext-include-settings.h \ ext-include-common.h \ ext-include-limits.h \ ext-include-binary.h \ ext-include-variables.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/include/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_include.la: $(libsieve_ext_include_la_OBJECTS) $(libsieve_ext_include_la_DEPENDENCIES) $(EXTRA_libsieve_ext_include_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_include_la_OBJECTS) $(libsieve_ext_include_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-global.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-include.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-return.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-binary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-variables.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-global.Plo -rm -f ./$(DEPDIR)/cmd-include.Plo -rm -f ./$(DEPDIR)/cmd-return.Plo -rm -f ./$(DEPDIR)/ext-include-binary.Plo -rm -f ./$(DEPDIR)/ext-include-common.Plo -rm -f ./$(DEPDIR)/ext-include-settings.Plo -rm -f ./$(DEPDIR)/ext-include-variables.Plo -rm -f ./$(DEPDIR)/ext-include.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-global.Plo -rm -f ./$(DEPDIR)/cmd-include.Plo -rm -f ./$(DEPDIR)/cmd-return.Plo -rm -f ./$(DEPDIR)/ext-include-binary.Plo -rm -f ./$(DEPDIR)/ext-include-common.Plo -rm -f ./$(DEPDIR)/ext-include-settings.Plo -rm -f ./$(DEPDIR)/ext-include-variables.Plo -rm -f ./$(DEPDIR)/ext-include.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-binary.h0000644000175100001700000000357515100335616030437 0ustar00buildbotbuildbot00000000000000#ifndef EXT_INCLUDE_BINARY_H #define EXT_INCLUDE_BINARY_H #include "sieve-common.h" /* * Binary context management */ struct ext_include_binary_context; struct ext_include_binary_context * ext_include_binary_init(const struct sieve_extension *this_ext, struct sieve_binary *sbin, struct sieve_ast *ast); struct ext_include_binary_context * ext_include_binary_get_context(const struct sieve_extension *this_ext, struct sieve_binary *sbin); /* * Variables */ struct sieve_variable_scope_binary * ext_include_binary_get_global_scope(const struct sieve_extension *this_ext, struct sieve_binary *sbin); /* * Including scripts */ struct ext_include_script_info { unsigned int id; enum ext_include_script_location location; const char *script_name; struct sieve_script *script; enum ext_include_flags flags; struct sieve_binary_block *block; }; struct ext_include_script_info * ext_include_binary_script_include(struct ext_include_binary_context *binctx, enum ext_include_script_location location, const char *script_name, enum ext_include_flags flags, struct sieve_script *script, struct sieve_binary_block *inc_block); struct ext_include_script_info * ext_include_binary_script_get_include_info( struct ext_include_binary_context *binctx, enum ext_include_script_location location, const char *script_name); const struct ext_include_script_info * ext_include_binary_script_get_included( struct ext_include_binary_context *binctx, unsigned int include_id); unsigned int ext_include_binary_script_get_count(struct ext_include_binary_context *binctx); /* * Dumping the binary */ bool ext_include_binary_dump(const struct sieve_extension *ext, struct sieve_dumptime_env *denv); bool ext_include_code_dump(const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/ext-include-settings.h0000644000175100001700000000037615100335616031007 0ustar00buildbotbuildbot00000000000000#ifndef EXT_INCLUDE_SETTINGS_H #define EXT_INCLUDE_SETTINGS_H struct ext_include_settings { pool_t pool; unsigned int max_nesting_depth; unsigned int max_includes; }; extern const struct setting_parser_info ext_include_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/include/cmd-global.c0000644000175100001700000001670415100335616026726 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" #include "ext-include-common.h" #include "ext-include-binary.h" #include "ext-include-variables.h" /* * Commands */ static bool cmd_global_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_global_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def cmd_global = { .identifier = "global", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_global_validate, .generate = cmd_global_generate, }; /* * Operations */ static bool opc_global_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int opc_global_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); /* Global operation */ const struct sieve_operation_def global_operation = { .mnemonic = "GLOBAL", .ext_def = &include_extension, .code = EXT_INCLUDE_OPERATION_GLOBAL, .dump = opc_global_dump, .execute = opc_global_execute, }; /* * Validation */ static inline struct sieve_argument * _create_variable_argument(struct sieve_command *cmd, struct sieve_variable *var) { struct sieve_argument *argument = sieve_argument_create(cmd->ast_node->ast, NULL, cmd->ext, 0); argument->data = var; return argument; } static bool cmd_global_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_command *prev = sieve_command_prev(cmd); /* Check for use of variables extension */ if (!ext_include_validator_have_variables(this_ext, valdtr)) { sieve_command_validate_error( valdtr, cmd, "%s command requires that variables extension is active", sieve_command_identifier(cmd)); return FALSE; } /* Register global variable */ if (sieve_ast_argument_type(arg) == SAAT_STRING) { /* Single string */ const char *identifier = sieve_ast_argument_strc(arg); struct sieve_variable *var; var = ext_include_variable_import_global(valdtr, cmd, identifier); if (var == NULL) return FALSE; arg->argument = _create_variable_argument(cmd, var); } else if (sieve_ast_argument_type(arg) == SAAT_STRING_LIST) { /* String list */ struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); while (stritem != NULL) { const char *identifier = sieve_ast_argument_strc(stritem); struct sieve_variable *var; var = ext_include_variable_import_global(valdtr, cmd, identifier); if (var == NULL) return FALSE; stritem->argument = _create_variable_argument(cmd, var); stritem = sieve_ast_strlist_next(stritem); } } else { /* Something else */ sieve_argument_validate_error( valdtr, arg, "the %s command accepts a single string or string list argument, " "but %s was found", sieve_command_identifier(cmd), sieve_ast_argument_name(arg)); return FALSE; } /* Join global commands with predecessors if possible */ if (sieve_commands_equal(prev, cmd)) { /* Join this command's string list with the previous one */ prev->first_positional = sieve_ast_stringlist_join( prev->first_positional, cmd->first_positional); if (prev->first_positional == NULL) { /* Not going to happen unless MAXINT stringlist items are specified */ sieve_command_validate_error( valdtr, cmd, "compiler reached AST limit " "(script too complex)"); return FALSE; } /* Detach this command node */ sieve_ast_node_detach(cmd->ast_node); } return TRUE; } /* * Code generation */ static bool cmd_global_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; sieve_operation_emit(cgenv->sblock, cmd->ext, &global_operation); if (sieve_ast_argument_type(arg) == SAAT_STRING) { /* Single string */ struct sieve_variable *var = (struct sieve_variable *)arg->argument->data; (void)sieve_binary_emit_unsigned(cgenv->sblock, 1); (void)sieve_binary_emit_unsigned(cgenv->sblock, var->index); } else if (sieve_ast_argument_type(arg) == SAAT_STRING_LIST) { /* String list */ struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); (void)sieve_binary_emit_unsigned(cgenv->sblock, sieve_ast_strlist_count(arg)); while (stritem != NULL) { struct sieve_variable *var = (struct sieve_variable *) stritem->argument->data; (void)sieve_binary_emit_unsigned(cgenv->sblock, var->index); stritem = sieve_ast_strlist_next(stritem); } } else { i_unreached(); } return TRUE; } /* * Code dump */ static bool opc_global_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct sieve_extension *this_ext = denv->oprtn->ext; unsigned int count, i, var_count; struct sieve_variable_scope_binary *global_vars; struct sieve_variable_scope *global_scope; struct sieve_variable *const *vars; if (!sieve_binary_read_unsigned(denv->sblock, address, &count)) return FALSE; sieve_code_dumpf(denv, "GLOBAL (count: %u):", count); global_vars = ext_include_binary_get_global_scope(this_ext, denv->sbin); global_scope = sieve_variable_scope_binary_get(global_vars); vars = sieve_variable_scope_get_variables(global_scope, &var_count); sieve_code_descend(denv); for (i = 0; i < count; i++) { unsigned int index; sieve_code_mark(denv); if (!sieve_binary_read_unsigned(denv->sblock, address, &index) || index >= var_count) return FALSE; sieve_code_dumpf(denv, "%d: VAR[%d]: '%s'", i, index, vars[index]->identifier); } return TRUE; } /* * Execution */ static int opc_global_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; struct sieve_variable_scope_binary *global_vars; struct sieve_variable_scope *global_scope; struct sieve_variable_storage *storage; struct sieve_variable *const *vars; unsigned int var_count, count, i; if (!sieve_binary_read_unsigned(renv->sblock, address, &count)) { sieve_runtime_trace_error( renv, "global: count operand invalid"); return SIEVE_EXEC_BIN_CORRUPT; } global_vars = ext_include_binary_get_global_scope(this_ext, renv->sbin); global_scope = sieve_variable_scope_binary_get(global_vars); vars = sieve_variable_scope_get_variables(global_scope, &var_count); storage = ext_include_interpreter_get_global_variables(this_ext, renv->interp); for (i = 0; i < count; i++) { unsigned int index; if (!sieve_binary_read_unsigned(renv->sblock, address, &index)) { sieve_runtime_trace_error( renv, "global: variable index operand invalid"); return SIEVE_EXEC_BIN_CORRUPT; } if (index >= var_count) { sieve_runtime_trace_error( renv, "global: " "variable index %u is invalid in global storage " "(> %u)", index, var_count); return SIEVE_EXEC_BIN_CORRUPT; } sieve_runtime_trace( renv, SIEVE_TRLVL_COMMANDS, "global: exporting variable '%s' [gvid: %u, vid: %u]", vars[index]->identifier, i, index); /* Make sure variable is initialized (export) */ (void)sieve_variable_get_modifiable(storage, index, NULL); } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/0000755000175100001700000000000015100335670026057 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-settings.h0000644000175100001700000000166215100335616033622 0ustar00buildbotbuildbot00000000000000#ifndef EXT_SPAMVIRUSTEST_SETTINGS_H #define EXT_SPAMVIRUSTEST_SETTINGS_H /* */ enum ext_spamvirustest_status_type { EXT_SPAMVIRUSTEST_STATUS_TYPE_SCORE, EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN, EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT, }; /* */ struct ext_spamvirustest_settings { pool_t pool; const char *status_header; const char *status_type; const char *score_max_header; const char *score_max_value; ARRAY_TYPE(const_string) text_value; struct { enum ext_spamvirustest_status_type status_type; float score_max_value; const char *text_values[11]; } parsed; }; extern const struct setting_parser_info ext_spamtest_setting_parser_info; extern const struct setting_parser_info ext_virustest_setting_parser_info; /* */ bool ext_spamvirustest_parse_decimal_value(const char *str_value, float *value_r, const char **error_r); /* */ #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/Makefile.am0000644000175100001700000000055215100335616030115 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_spamvirustest.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-spamvirustest.c libsieve_ext_spamvirustest_la_SOURCES = \ $(tests) \ ext-spamvirustest-settings.c \ ext-spamvirustest-common.c \ ext-spamvirustest.c noinst_HEADERS = \ ext-spamvirustest-settings.h \ ext-spamvirustest-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c0000644000175100001700000003027615100335616033250 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "strfuncs.h" #include "mail-storage.h" #include "settings.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-message.h" #include "sieve-interpreter.h" #include "sieve-runtime-trace.h" #include "ext-spamvirustest-settings.h" #include "ext-spamvirustest-common.h" #include "dregex.h" #include #include /* * Extension data */ struct ext_spamvirustest_header_spec { const char *header_name; struct dregex_code *regexp; bool regexp_match; }; struct ext_spamvirustest_context { pool_t pool; unsigned int reload_id; const struct ext_spamvirustest_settings *set; struct ext_spamvirustest_header_spec status_header; struct ext_spamvirustest_header_spec score_max_header; }; /* * Configuration parser */ static bool ext_spamvirustest_header_spec_parse( pool_t pool, const char *data, struct ext_spamvirustest_header_spec *spec_r, const char **error_r) { const char *p; const char *regexp_error; if (*data == '\0') { *error_r = "empty header specification"; return FALSE; } /* Parse header name */ p = data; while (*p == ' ' || *p == '\t') p++; while (*p != ':' && *p != '\0' && *p != ' ' && *p != '\t') p++; if (*p == '\0') { spec_r->header_name = p_strdup(pool, data); return TRUE; } spec_r->header_name = p_strdup_until(pool, data, p); while (*p == ' ' || *p == '\t') p++; if (*p == '\0') { spec_r->regexp_match = FALSE; return TRUE; } /* Parse and compile regular expression */ if (*p != ':') { *error_r = t_strdup_printf("expecting ':', but found '%c'", *p); return FALSE; } p++; while (*p == ' ' || *p == '\t') p++; spec_r->regexp_match = TRUE; struct dregex_code *code = dregex_code_create(); if (dregex_code_compile(code, p, DREGEX_ICASE|DREGEX_ASCII_ONLY, ®exp_error) < 0) { *error_r = t_strdup_printf( "failed to compile regular expression '%s': %s", p, regexp_error); dregex_code_free(&code); return FALSE; } spec_r->regexp = code; return TRUE; } static void ext_spamvirustest_header_spec_free(struct ext_spamvirustest_header_spec *spec) { dregex_code_free(&spec->regexp); } static bool ext_spamvirustest_parse_strlen_value(const char *str_value, float *value_r, const char **error_r) { const char *p = str_value; char ch = *p; if (*str_value == '\0') { *value_r = 0; return TRUE; } while (*p == ch) p++; if (*p != '\0') { *error_r = t_strdup_printf( "different character '%c' encountered in strlen value", *p); return FALSE; } *value_r = (p - str_value); return TRUE; } /* * Extension initialization */ int ext_spamvirustest_load(const struct sieve_extension *ext, void **context_r) { static unsigned int reload_id = 0; struct sieve_instance *svinst = ext->svinst; struct ext_spamvirustest_context *extctx; const struct setting_parser_info *set_info; const struct ext_spamvirustest_settings *set; const char *error; pool_t pool; int ret = 0; /* Get settings */ if (sieve_extension_is(ext, spamtest_extension) || sieve_extension_is(ext, spamtestplus_extension)) set_info = &ext_spamtest_setting_parser_info; else if (sieve_extension_is(ext, virustest_extension)) set_info = &ext_virustest_setting_parser_info; else i_unreached(); if (settings_get(svinst->event, set_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } /* Base configuration */ if (*set->status_header == '\0') { settings_free(set); return 0; } pool = pool_alloconly_create("spamvirustest_data", 512); extctx = p_new(pool, struct ext_spamvirustest_context, 1); extctx->pool = pool; extctx->reload_id = ++reload_id; extctx->set = set; if (!ext_spamvirustest_header_spec_parse(extctx->pool, set->status_header, &extctx->status_header, &error)) { e_error(svinst->event, "%s: " "Invalid status header specification '%s': %s", sieve_extension_name(ext), set->status_header, error); ret = -1; } if (ret == 0 && set->parsed.status_type != EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT && *set->score_max_header != '\0' && !ext_spamvirustest_header_spec_parse(extctx->pool, set->score_max_header, &extctx->score_max_header, &error)) { e_error(svinst->event, "%s: " "Invalid max score header specification '%s': %s", sieve_extension_name(ext), set->score_max_header, error); ret = -1; } *context_r = extctx; if (ret < 0) { e_warning(svinst->event, "%s: " "Extension not configured, " "tests will always match against \"0\"", sieve_extension_name(ext)); ext_spamvirustest_unload(ext); *context_r = NULL; } return ret; } void ext_spamvirustest_unload(const struct sieve_extension *ext) { struct ext_spamvirustest_context *extctx = ext->context; if (extctx == NULL) return; ext_spamvirustest_header_spec_free(&extctx->status_header); ext_spamvirustest_header_spec_free(&extctx->score_max_header); settings_free(extctx->set); pool_unref(&extctx->pool); } /* * Runtime */ struct ext_spamvirustest_message_context { unsigned int reload_id; float score_ratio; }; static const char * ext_spamvirustest_get_score(const struct sieve_extension *ext, float score_ratio, bool percent) { int score; if (score_ratio < 0) return "0"; if (score_ratio > 1) score_ratio = 1; if (percent) score = score_ratio * 100 + 0.001; else if (sieve_extension_is(ext, virustest_extension)) score = score_ratio * 4 + 1.001; else score = score_ratio * 9 + 1.001; return t_strdup_printf("%d", score); } int ext_spamvirustest_get_value(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, bool percent, const char **value_r) { struct ext_spamvirustest_context *extctx = ext->context; struct ext_spamvirustest_header_spec *status_header, *max_header; struct sieve_message_context *msgctx = renv->msgctx; struct ext_spamvirustest_message_context *mctx; struct mail *mail; ARRAY_TYPE(const_string) match_values; const char *header_value, *error; const char *status = NULL, *max = NULL; float status_value, max_value; unsigned int i, max_text; pool_t pool = sieve_interpreter_pool(renv->interp); *value_r = "0"; /* * Check whether extension is properly configured */ if (extctx == NULL) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "error: extension not configured"); return SIEVE_EXEC_OK; } /* * Check wether a cached result is available */ mctx = (struct ext_spamvirustest_message_context *) sieve_message_context_extension_get(msgctx, ext); if (mctx == NULL) { /* Create new context */ mctx = p_new(pool, struct ext_spamvirustest_message_context, 1); sieve_message_context_extension_set(msgctx, ext, mctx); } else if (mctx->reload_id == extctx->reload_id) { /* Use cached result */ *value_r = ext_spamvirustest_get_score(ext, mctx->score_ratio, percent); return SIEVE_EXEC_OK; } else { /* Extension was reloaded (probably in testsuite) */ } mctx->reload_id = extctx->reload_id; /* * Get max status value */ mail = sieve_message_get_mail(renv->msgctx); status_header = &extctx->status_header; max_header = &extctx->score_max_header; if (extctx->set->parsed.status_type != EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT) { if (max_header->header_name != NULL) { /* Get header from message */ if (mail_get_first_header_utf8( mail, max_header->header_name, &header_value) < 0) { return sieve_runtime_mail_error ( renv, mail, "%s test: " "failed to read header field '%s'", sieve_extension_name(ext), max_header->header_name); } if (header_value == NULL) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "header '%s' not found in message", max_header->header_name); goto failed; } if (max_header->regexp_match) { t_array_init(&match_values, 2); int ret; /* Execute regex */ if ((ret = dregex_code_match_groups(max_header->regexp, header_value, &match_values, &error)) < 1) { if (ret < 0) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "score_max_header regexp for header '%s' failed" "on value '%s': %s", max_header->header_name, header_value, error); } else { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "score_max_header regexp for header '%s' did not match " "on value '%s'", max_header->header_name, header_value); } goto failed; } if (array_count(&match_values) < 2) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "regexp did not return match value " "for string '%s'", header_value); goto failed; } max = array_idx_elem(&match_values, 1); } else { max = header_value; } if (!ext_spamvirustest_parse_decimal_value( max, &max_value, &error)) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "failed to parse maximum value: %s", error); goto failed; } } else { max_value = extctx->set->parsed.score_max_value; } if (max_value == 0) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "error: max value is 0"); goto failed; } } else { max_value = (sieve_extension_is(ext, virustest_extension) ? 5 : 10); } /* * Get status value */ /* Get header from message */ if (mail_get_first_header_utf8(mail, status_header->header_name, &header_value) < 0) { return sieve_runtime_mail_error( renv, mail, "%s test: failed to read header field '%s'", sieve_extension_name(ext), status_header->header_name); } if (header_value == NULL) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "header '%s' not found in message", status_header->header_name); goto failed; } /* Execute regex */ if (status_header->regexp_match) { int ret; t_array_init(&match_values, 2); if ((ret = dregex_code_match_groups(status_header->regexp, header_value, &match_values, &error)) < 1) { if (ret < 0) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "status_header regexp for header '%s' did failed on value '%s': %s", status_header->header_name, header_value, error); } else { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "status_header regexp for header '%s' did not match on value '%s'", status_header->header_name, header_value); } goto failed; } if (array_count(&match_values) < 2) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "regexp did not return match value for string '%s'", header_value); goto failed; } status = array_idx_elem(&match_values, 1); } else { status = header_value; } switch (extctx->set->parsed.status_type) { case EXT_SPAMVIRUSTEST_STATUS_TYPE_SCORE: if (!ext_spamvirustest_parse_decimal_value( status, &status_value, &error)) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "failed to parse status value '%s': %s", status, error); goto failed; } break; case EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN: if (!ext_spamvirustest_parse_strlen_value( status, &status_value, &error)) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "failed to parse status value '%s': %s", status, error); goto failed; } break; case EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT: max_text = (sieve_extension_is(ext, virustest_extension) ? 5 : 10); status_value = 0; i = 0; while (i <= max_text) { if (extctx->set->parsed.text_values[i] != NULL && strcmp(status, extctx->set->parsed.text_values[i]) == 0) { status_value = (float)i; break; } i++; } if (i > max_text) { sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "failed to match textstatus value '%s'", status); goto failed; } break; default: i_unreached(); } /* Calculate value */ if (status_value < 0) mctx->score_ratio = 0; else if (status_value > max_value) mctx->score_ratio = 1; else mctx->score_ratio = (status_value / max_value); sieve_runtime_trace( renv, SIEVE_TRLVL_TESTS, "extracted score=%.3f, max=%.3f, ratio=%.0f %%", status_value, max_value, mctx->score_ratio * 100); *value_r = ext_spamvirustest_get_score(ext, mctx->score_ratio, percent); return SIEVE_EXEC_OK; failed: mctx->score_ratio = -1; *value_r = "0"; return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-settings.c0000644000175100001700000001414015100335616033610 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-spamvirustest-settings.h" #include static bool ext_spamtest_settings_check(void *_set, pool_t pool, const char **error_r); static bool ext_virustest_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_spamtest_"#name, name, \ struct ext_spamvirustest_settings) static const struct setting_define ext_spamtest_setting_defines[] = { DEF(STR, status_header), DEF(ENUM, status_type), DEF(STR, score_max_header), DEF(STR, score_max_value), { .type = SET_STRLIST, .key = "sieve_spamtest_text_value", .offset = offsetof(struct ext_spamvirustest_settings, text_value) }, SETTING_DEFINE_LIST_END, }; #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_virustest_"#name, name, \ struct ext_spamvirustest_settings) static const struct setting_define ext_virustest_setting_defines[] = { DEF(STR, status_header), DEF(ENUM, status_type), DEF(STR, score_max_header), DEF(STR, score_max_value), { .type = SET_STRLIST, .key = "sieve_virustest_text_value", .offset = offsetof(struct ext_spamvirustest_settings, text_value) }, SETTING_DEFINE_LIST_END, }; static const struct ext_spamvirustest_settings ext_spamvirustest_default_settings = { .status_header = "", .status_type = "score:strlen:text", .score_max_header = "", .score_max_value = "", .text_value = ARRAY_INIT, }; const struct setting_parser_info ext_spamtest_setting_parser_info = { .name = "sieve_spamtest", .defines = ext_spamtest_setting_defines, .defaults = &ext_spamvirustest_default_settings, .struct_size = sizeof(struct ext_spamvirustest_settings), .check_func = ext_spamtest_settings_check, .pool_offset1 = 1 + offsetof(struct ext_spamvirustest_settings, pool), }; const struct setting_parser_info ext_virustest_setting_parser_info = { .name = "sieve_virustest", .defines = ext_virustest_setting_defines, .defaults = &ext_spamvirustest_default_settings, .struct_size = sizeof(struct ext_spamvirustest_settings), .check_func = ext_virustest_settings_check, .pool_offset1 = 1 + offsetof(struct ext_spamvirustest_settings, pool), }; /* */ bool ext_spamvirustest_parse_decimal_value(const char *str_value, float *value_r, const char **error_r) { const char *p = str_value; float value; float sign = 1; int digits; if (*p == '\0') { *error_r = "empty value"; return FALSE; } if (*p == '+' || *p == '-') { if (*p == '-') sign = -1; p++; } value = 0; digits = 0; while (i_isdigit(*p)) { value = value*10 + (*p-'0'); if (digits++ > 4) { *error_r = t_strdup_printf( "Decimal value has too many digits before radix point: %s", str_value); return FALSE; } p++; } if (*p == '.' || *p == ',') { float radix = .1; p++; digits = 0; while (i_isdigit(*p)) { value = value + (*p-'0')*radix; if (digits++ > 4) { *error_r = t_strdup_printf( "Decimal value has too many digits after radix point: %s", str_value); return FALSE; } radix /= 10; p++; } } if (*p != '\0') { *error_r = t_strdup_printf( "Invalid decimal point value: %s", str_value); return FALSE; } *value_r = value * sign; return TRUE; } static bool ext_spamvirustest_settings_check(void *_set, bool virustest, pool_t pool ATTR_UNUSED, const char **error_r) { struct ext_spamvirustest_settings *set = _set; const char *ext_name = (virustest ? "virustest" : "spamtest"); const char *error; if (*set->status_header == '\0') return TRUE; if (*set->status_type == '\0' || strcmp(set->status_type, "score") == 0) set->parsed.status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_SCORE; else if (strcmp(set->status_type, "strlen") == 0) set->parsed.status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN; else if (strcmp(set->status_type, "text") == 0) set->parsed.status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT; else { *error_r = t_strdup_printf("Invalid status type '%s'", set->status_type); return FALSE; } if (set->parsed.status_type != EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT) { if (*set->score_max_header != '\0' && *set->score_max_value != '\0') { *error_r = t_strdup_printf( "sieve_%s_score_max_header and sieve_%s_score_max_value " "cannot both be configured", ext_name, ext_name); return FALSE; } if (*set->score_max_header == '\0' && *set->score_max_value == '\0') { *error_r = t_strdup_printf( "None of sieve_%s_score_max_header or " "sieve_%s_score_max_value is configured", ext_name, ext_name); return FALSE; } if (*set->score_max_value != '\0' && !ext_spamvirustest_parse_decimal_value( set->score_max_value, &set->parsed.score_max_value, &error)) { *error_r = t_strdup_printf( "Invalid max score value specification " "'%s': %s", set->score_max_value, error); return FALSE; } } else { const char *const *tvalues; unsigned int tvalues_count, i; unsigned int tv_index_max = (virustest ? 5 : 10); tvalues = array_get(&set->text_value, &tvalues_count); i_assert(tvalues_count % 2 == 0); for (i = 0; i < tvalues_count; i += 2) { unsigned int tv_index; if (str_to_uint(tvalues[i], &tv_index) < 0) { *error_r = t_strdup_printf( "Invalid text value index '%s'", tvalues[i]); return FALSE; } if (tv_index > tv_index_max) { *error_r = t_strdup_printf( "Text value index out of range " "(%u > %u)", tv_index, tv_index_max); return FALSE; } set->parsed.text_values[tv_index] = tvalues[i + 1]; } set->parsed.score_max_value = 1; } return TRUE; } static bool ext_spamtest_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { return ext_spamvirustest_settings_check(_set, FALSE, pool, error_r); } static bool ext_virustest_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { return ext_spamvirustest_settings_check(_set, TRUE, pool, error_r); } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/Makefile.in0000644000175100001700000005550715100335630030134 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/spamvirustest ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_spamvirustest_la_LIBADD = am__objects_1 = tst-spamvirustest.lo am_libsieve_ext_spamvirustest_la_OBJECTS = $(am__objects_1) \ ext-spamvirustest-settings.lo ext-spamvirustest-common.lo \ ext-spamvirustest.lo libsieve_ext_spamvirustest_la_OBJECTS = \ $(am_libsieve_ext_spamvirustest_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-spamvirustest-common.Plo \ ./$(DEPDIR)/ext-spamvirustest-settings.Plo \ ./$(DEPDIR)/ext-spamvirustest.Plo \ ./$(DEPDIR)/tst-spamvirustest.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_spamvirustest_la_SOURCES) DIST_SOURCES = $(libsieve_ext_spamvirustest_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_spamvirustest.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-spamvirustest.c libsieve_ext_spamvirustest_la_SOURCES = \ $(tests) \ ext-spamvirustest-settings.c \ ext-spamvirustest-common.c \ ext-spamvirustest.c noinst_HEADERS = \ ext-spamvirustest-settings.h \ ext-spamvirustest-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/spamvirustest/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/spamvirustest/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_spamvirustest.la: $(libsieve_ext_spamvirustest_la_OBJECTS) $(libsieve_ext_spamvirustest_la_DEPENDENCIES) $(EXTRA_libsieve_ext_spamvirustest_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_spamvirustest_la_OBJECTS) $(libsieve_ext_spamvirustest_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-spamvirustest-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-spamvirustest-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-spamvirustest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-spamvirustest.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-spamvirustest-common.Plo -rm -f ./$(DEPDIR)/ext-spamvirustest-settings.Plo -rm -f ./$(DEPDIR)/ext-spamvirustest.Plo -rm -f ./$(DEPDIR)/tst-spamvirustest.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-spamvirustest-common.Plo -rm -f ./$(DEPDIR)/ext-spamvirustest-settings.Plo -rm -f ./$(DEPDIR)/ext-spamvirustest.Plo -rm -f ./$(DEPDIR)/tst-spamvirustest.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h0000644000175100001700000000156115100335616033250 0ustar00buildbotbuildbot00000000000000#ifndef EXT_SPAMVIRUSTEST_COMMON_H #define EXT_SPAMVIRUSTEST_COMMON_H #include "sieve-common.h" /* * Extensions */ extern const struct sieve_extension_def spamtest_extension; extern const struct sieve_extension_def spamtestplus_extension; extern const struct sieve_extension_def virustest_extension; int ext_spamvirustest_load(const struct sieve_extension *ext, void **context_r); void ext_spamvirustest_unload(const struct sieve_extension *ext); /* * Tests */ extern const struct sieve_command_def spamtest_test; extern const struct sieve_command_def virustest_test; int ext_spamvirustest_get_value(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, bool percent, const char **value_r); /* * Operations */ extern const struct sieve_operation_def spamtest_operation; extern const struct sieve_operation_def virustest_operation; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c0000644000175100001700000001671315100335616031774 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-match.h" #include "ext-spamvirustest-common.h" /* * Tests */ static bool tst_spamvirustest_validate (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_spamvirustest_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); static bool tst_spamvirustest_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); /* Spamtest test * * Syntax: * spamtest [":percent"] [COMPARATOR] [MATCH-TYPE] */ const struct sieve_command_def spamtest_test = { .identifier = "spamtest", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_spamvirustest_registered, .validate = tst_spamvirustest_validate, .generate = tst_spamvirustest_generate }; /* Virustest test * * Syntax: * virustest [COMPARATOR] [MATCH-TYPE] */ const struct sieve_command_def virustest_test = { .identifier = "virustest", .type = SCT_TEST, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_spamvirustest_registered, .validate = tst_spamvirustest_validate, .generate = tst_spamvirustest_generate }; /* * Tagged arguments */ static bool tst_spamtest_validate_percent_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *tst); static const struct sieve_argument_def spamtest_percent_tag = { .identifier = "percent", .validate = tst_spamtest_validate_percent_tag }; /* * Spamtest and virustest operations */ static bool tst_spamvirustest_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_spamvirustest_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def spamtest_operation = { .mnemonic = "SPAMTEST", .ext_def = &spamtest_extension, .dump = tst_spamvirustest_operation_dump, .execute = tst_spamvirustest_operation_execute }; const struct sieve_operation_def virustest_operation = { .mnemonic = "VIRUSTEST", .ext_def = &virustest_extension, .dump = tst_spamvirustest_operation_dump, .execute = tst_spamvirustest_operation_execute }; /* * Optional operands */ enum tst_spamvirustest_optional { OPT_SPAMTEST_PERCENT = SIEVE_MATCH_OPT_LAST, OPT_SPAMTEST_LAST }; /* * Test registration */ static bool tst_spamvirustest_registered (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); if ( sieve_extension_is(ext, spamtestplus_extension) || sieve_extension_is(ext, spamtest_extension) ) { sieve_validator_register_tag (valdtr, cmd_reg, ext, &spamtest_percent_tag, OPT_SPAMTEST_PERCENT); } return TRUE; } /* * Validation */ static bool tst_spamtest_validate_percent_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *tst) { if ( !sieve_extension_is(tst->ext, spamtestplus_extension) ) { sieve_argument_validate_error(valdtr, *arg, "the spamtest test only accepts the :percent argument when " "the spamtestplus extension is active"); return FALSE; } /* Skip tag */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool tst_spamvirustest_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; const struct sieve_match_type mcht_default = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_comparator cmp_default = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); /* Check value */ if ( !sieve_validate_positional_argument (valdtr, tst, arg, "value", 1, SAAT_STRING) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate (valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ static bool tst_spamvirustest_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { if ( sieve_command_is(tst, spamtest_test) ) sieve_operation_emit(cgenv->sblock, tst->ext, &spamtest_operation); else if ( sieve_command_is(tst, virustest_test) ) sieve_operation_emit(cgenv->sblock, tst->ext, &virustest_operation); else i_unreached(); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); } /* * Code dump */ static bool tst_spamvirustest_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; const struct sieve_operation *op = denv->oprtn; sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); /* Optional operands */ for (;;) { int opt; if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; if ( opt == 0 ) break; switch ( opt_code ) { case OPT_SPAMTEST_PERCENT: sieve_code_dumpf(denv, "percent"); break; default: return FALSE; } } return sieve_opr_string_dump(denv, address, "value"); } /* * Code execution */ static int tst_spamvirustest_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *op = renv->oprtn; const struct sieve_extension *this_ext = op->ext; int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); bool percent = FALSE; struct sieve_stringlist *value_list, *key_list; const char *score_value; int match, ret; /* Read optional operands */ for (;;) { int opt; if ( (opt=sieve_match_opr_optional_read (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) return ret; if ( opt == 0 ) break; switch ( opt_code ) { case OPT_SPAMTEST_PERCENT: percent = TRUE; break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } /* Read value part */ if ( (ret=sieve_opr_stringlist_read(renv, address, "value", &key_list)) <= 0 ) return ret; /* Perform test */ if ( sieve_operation_is(op, spamtest_operation) ) { sieve_runtime_trace (renv, SIEVE_TRLVL_TESTS, "spamtest test [percent=%s]", ( percent ? "true" : "false" )); } else { sieve_runtime_trace (renv, SIEVE_TRLVL_TESTS, "virustest test"); } /* Get score value */ sieve_runtime_trace_descend(renv); if ( (ret=ext_spamvirustest_get_value (renv, this_ext, percent, &score_value)) <= 0 ) return ret; sieve_runtime_trace_ascend(renv); /* Construct value list */ value_list = sieve_single_stringlist_create_cstr(renv, score_value, TRUE); /* Perform match */ if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest.c0000644000175100001700000000553615100335616031763 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extensions spamtest, spamtestplus and virustest * ----------------------------------------------- * * Authors: Stephan Bosch * Specification: RFC 5235 * Implementation: full * Status: testing * */ #include "lib.h" #include "array.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "ext-spamvirustest-common.h" /* * Extensions */ /* Spamtest */ static bool ext_spamvirustest_validator_load (const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def spamtest_extension = { .name = "spamtest", .load = ext_spamvirustest_load, .unload = ext_spamvirustest_unload, .validator_load = ext_spamvirustest_validator_load, SIEVE_EXT_DEFINE_OPERATION(spamtest_operation) }; const struct sieve_extension_def spamtestplus_extension = { .name = "spamtestplus", .load = ext_spamvirustest_load, .unload = ext_spamvirustest_unload, .validator_load = ext_spamvirustest_validator_load, SIEVE_EXT_DEFINE_OPERATION(spamtest_operation) }; const struct sieve_extension_def virustest_extension = { .name = "virustest", .load = ext_spamvirustest_load, .unload = ext_spamvirustest_unload, .validator_load = ext_spamvirustest_validator_load, SIEVE_EXT_DEFINE_OPERATION(virustest_operation) }; /* * Implementation */ static bool ext_spamtest_validator_check_conflict (const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, const struct sieve_extension *ext_other, bool required); const struct sieve_validator_extension spamtest_validator_extension = { .ext = &spamtest_extension, .check_conflict = ext_spamtest_validator_check_conflict }; static bool ext_spamvirustest_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ if ( sieve_extension_is(ext, virustest_extension) ) { sieve_validator_register_command(valdtr, ext, &virustest_test); } else { if ( sieve_extension_is(ext, spamtest_extension) ) { /* Register validator extension to warn for duplicate */ sieve_validator_extension_register (valdtr, ext, &spamtest_validator_extension, NULL); } sieve_validator_register_command(valdtr, ext, &spamtest_test); } return TRUE; } static bool ext_spamtest_validator_check_conflict (const struct sieve_extension *ext ATTR_UNUSED, struct sieve_validator *valdtr, void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg, const struct sieve_extension *ext_other, bool required ATTR_UNUSED) { if ( sieve_extension_name_is(ext_other, "spamtestplus") ) { sieve_argument_validate_warning(valdtr, require_arg, "the spamtest and spamtestplus extensions should " "not be specified at the same time"); } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/subaddress/0000755000175100001700000000000015100335670025265 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/subaddress/Makefile.am0000644000175100001700000000036315100335616027323 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_subaddress.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_subaddress_la_SOURCES = \ ext-subaddress-settings.c \ ext-subaddress.c noinst_HEADERS = \ ext-subaddress-settings.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/subaddress/ext-subaddress-settings.h0000644000175100001700000000035715100335616032236 0ustar00buildbotbuildbot00000000000000#ifndef EXT_SUBADDRESS_SETTINGS_H #define EXT_SUBADDRESS_SETTINGS_H struct ext_subaddress_settings { pool_t pool; const char *recipient_delimiter; }; extern const struct setting_parser_info ext_subaddress_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/subaddress/Makefile.in0000644000175100001700000005412415100335630027334 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/subaddress ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_subaddress_la_LIBADD = am_libsieve_ext_subaddress_la_OBJECTS = ext-subaddress-settings.lo \ ext-subaddress.lo libsieve_ext_subaddress_la_OBJECTS = \ $(am_libsieve_ext_subaddress_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-subaddress-settings.Plo \ ./$(DEPDIR)/ext-subaddress.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_subaddress_la_SOURCES) DIST_SOURCES = $(libsieve_ext_subaddress_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_subaddress.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) libsieve_ext_subaddress_la_SOURCES = \ ext-subaddress-settings.c \ ext-subaddress.c noinst_HEADERS = \ ext-subaddress-settings.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/subaddress/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/subaddress/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_subaddress.la: $(libsieve_ext_subaddress_la_OBJECTS) $(libsieve_ext_subaddress_la_DEPENDENCIES) $(EXTRA_libsieve_ext_subaddress_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_subaddress_la_OBJECTS) $(libsieve_ext_subaddress_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-subaddress-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-subaddress.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-subaddress-settings.Plo -rm -f ./$(DEPDIR)/ext-subaddress.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-subaddress-settings.Plo -rm -f ./$(DEPDIR)/ext-subaddress.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/subaddress/ext-subaddress-settings.c0000644000175100001700000000160215100335616032223 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-subaddress-settings.h" #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type(#name, name, \ struct ext_subaddress_settings) static const struct setting_define ext_subaddress_setting_defines[] = { DEF(STR, recipient_delimiter), SETTING_DEFINE_LIST_END, }; static const struct ext_subaddress_settings ext_subaddress_default_settings = { .recipient_delimiter = "+", }; const struct setting_parser_info ext_subaddress_setting_parser_info = { .name = "sieve_subaddress", .defines = ext_subaddress_setting_defines, .defaults = &ext_subaddress_default_settings, .struct_size = sizeof(struct ext_subaddress_settings), .pool_offset1 = 1 + offsetof(struct ext_subaddress_settings, pool), }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/subaddress/ext-subaddress.c0000644000175100001700000001113215100335616030364 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension subaddress * -------------------- * * Author: Stephan Bosch * Specification: RFC 3598 * Implementation: full * Status: testing * */ #include "lib.h" #include "settings.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-address.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-address-parts.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "ext-subaddress-settings.h" #include /* * Configuration */ struct ext_subaddress_context { const struct ext_subaddress_settings *set; }; /* * Forward declarations */ const struct sieve_address_part_def user_address_part; const struct sieve_address_part_def detail_address_part; static struct sieve_operand_def subaddress_operand; /* * Extension */ static int ext_subaddress_load(const struct sieve_extension *ext, void **context); static void ext_subaddress_unload(const struct sieve_extension *ext); static bool ext_subaddress_validator_load(const struct sieve_extension *ext, struct sieve_validator *validator); const struct sieve_extension_def subaddress_extension = { .name = "subaddress", .load = ext_subaddress_load, .unload = ext_subaddress_unload, .validator_load = ext_subaddress_validator_load, SIEVE_EXT_DEFINE_OPERAND(subaddress_operand), }; static int ext_subaddress_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct ext_subaddress_settings *set; struct ext_subaddress_context *extctx; const char *error; if (settings_get(svinst->event, &ext_subaddress_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_subaddress_context, 1); extctx->set = set; *context_r = extctx; return 0; } static void ext_subaddress_unload(const struct sieve_extension *ext) { struct ext_subaddress_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); i_free(extctx); } static bool ext_subaddress_validator_load(const struct sieve_extension *ext, struct sieve_validator *validator) { sieve_address_part_register(validator, ext, &user_address_part); sieve_address_part_register(validator, ext, &detail_address_part); return TRUE; } /* * Address parts */ enum ext_subaddress_address_part { SUBADDRESS_USER, SUBADDRESS_DETAIL }; /* Forward declarations */ static const char * subaddress_user_extract_from(const struct sieve_address_part *addrp, const struct smtp_address *address); static const char * subaddress_detail_extract_from(const struct sieve_address_part *addrp, const struct smtp_address *address); /* Address part objects */ const struct sieve_address_part_def user_address_part = { SIEVE_OBJECT("user", &subaddress_operand, SUBADDRESS_USER), subaddress_user_extract_from, }; const struct sieve_address_part_def detail_address_part = { SIEVE_OBJECT("detail", &subaddress_operand, SUBADDRESS_DETAIL), .extract_from = subaddress_detail_extract_from, }; /* Address part implementation */ static const char * subaddress_user_extract_from(const struct sieve_address_part *addrp, const struct smtp_address *address) { struct ext_subaddress_context *extctx = addrp->object.ext->context; const char *delim; size_t idx; idx = strcspn(address->localpart, extctx->set->recipient_delimiter); delim = (address->localpart[idx] != '\0' ? address->localpart + idx : NULL); if (delim == NULL) return address->localpart; return t_strdup_until(address->localpart, delim); } static const char * subaddress_detail_extract_from(const struct sieve_address_part *addrp, const struct smtp_address *address) { struct ext_subaddress_context *extctx = addrp->object.ext->context; const char *delim; size_t idx; idx = strcspn(address->localpart, extctx->set->recipient_delimiter); delim = (address->localpart[idx] != '\0' ? address->localpart + idx + 1: NULL); /* Just to be sure */ if (delim == NULL || delim > (address->localpart + strlen(address->localpart))) return NULL; return delim; } /* * Operand */ const struct sieve_address_part_def *ext_subaddress_parts[] = { &user_address_part, &detail_address_part, }; static const struct sieve_extension_objects ext_address_parts = SIEVE_EXT_DEFINE_ADDRESS_PARTS(ext_subaddress_parts); static struct sieve_operand_def subaddress_operand = { .name = "address-part", .ext_def = &subaddress_extension, .class = &sieve_address_part_operand_class, .interface = &ext_address_parts, }; dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/0000755000175100001700000000000015100335670024732 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/ext-vacation-common.c0000644000175100001700000000173315100335616030772 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "settings.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "ext-vacation-common.h" int ext_vacation_load(const struct sieve_extension *ext, void **context) { struct sieve_instance *svinst = ext->svinst; const struct ext_vacation_settings *set; struct ext_vacation_context *extctx; const char *error; if (*context != NULL) { ext_vacation_unload(ext); *context = NULL; } if (settings_get(svinst->event, &ext_vacation_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_vacation_context, 1); extctx->set = set; *context = extctx; return 0; } void ext_vacation_unload(const struct sieve_extension *ext) { struct ext_vacation_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); i_free(extctx); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/ext-vacation-settings.h0000644000175100001700000000071715100335616031350 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VACATION_SETTINGS_H #define EXT_VACATION_SETTINGS_H struct ext_vacation_settings { pool_t pool; unsigned int min_period; unsigned int max_period; unsigned int default_period; const char *default_subject; const char *default_subject_template; bool use_original_recipient; bool check_recipient; bool send_from_recipient; bool to_header_ignore_envelope; }; extern const struct setting_parser_info ext_vacation_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/ext-vacation.c0000644000175100001700000000664215100335616027510 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension vacation * ------------------ * * Authors: Stephan Bosch * Specification: RFC 5230 * Implementation: full * Status: testing * */ #include "lib.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-vacation-common.h" /* * Extension */ static bool ext_vacation_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_vacation_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address); static bool ext_vacation_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg, bool required); static int ext_vacation_interpreter_run(const struct sieve_extension *this_ext, const struct sieve_runtime_env *renv, void *context, bool deferred); const struct sieve_extension_def vacation_extension = { .name = "vacation", .load = ext_vacation_load, .unload = ext_vacation_unload, .validator_load = ext_vacation_validator_load, .interpreter_load = ext_vacation_interpreter_load, SIEVE_EXT_DEFINE_OPERATION(vacation_operation), }; const struct sieve_validator_extension vacation_validator_extension = { .ext = &vacation_extension, .validate = ext_vacation_validator_validate, }; const struct sieve_interpreter_extension vacation_interpreter_extension = { .ext_def = &vacation_extension, .run = ext_vacation_interpreter_run, }; static bool ext_vacation_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ sieve_validator_register_command(valdtr, ext, &vacation_command); sieve_validator_extension_register(valdtr, ext, &vacation_validator_extension, NULL); return TRUE; } static bool ext_vacation_interpreter_load(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_interpreter_extension_register( renv->interp, ext, &vacation_interpreter_extension, NULL); return TRUE; } static bool ext_vacation_validator_validate(const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg, bool required) { if (required) { enum sieve_compile_flags flags = sieve_validator_compile_flags(valdtr); if ((flags & SIEVE_COMPILE_FLAG_NO_ENVELOPE) != 0) { sieve_argument_validate_error( valdtr, require_arg, "the %s extension cannot be used in this context " "(needs access to message envelope)", sieve_extension_name(ext)); return FALSE; } } return TRUE; } static int ext_vacation_interpreter_run(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, void *context ATTR_UNUSED, bool deferred) { const struct sieve_execute_env *eenv = renv->exec_env; if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0) { if (!deferred) { sieve_runtime_error( renv, NULL, "the %s extension cannot be used in this context " "(needs access to message envelope)", sieve_extension_name(ext)); } return SIEVE_EXEC_FAILURE; } return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/Makefile.am0000644000175100001700000000056515100335616026774 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_vacation.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ $(LIBDOVECOT_INCLUDE) cmds = \ cmd-vacation.c libsieve_ext_vacation_la_SOURCES = \ $(cmds) \ ext-vacation-settings.c \ ext-vacation-common.c \ ext-vacation.c \ ext-vacation-seconds.c noinst_HEADERS = \ ext-vacation-settings.h \ ext-vacation-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/ext-vacation-settings.c0000644000175100001700000000417515100335616031345 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-vacation-settings.h" static bool ext_vacation_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r); #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_vacation_"#name, name, \ struct ext_vacation_settings) static const struct setting_define ext_vacation_setting_defines[] = { DEF(TIME, min_period), DEF(TIME, max_period), DEF(TIME, default_period), DEF(STR, default_subject), DEF(STR, default_subject_template), DEF(BOOL, use_original_recipient), DEF(BOOL, check_recipient), DEF(BOOL, send_from_recipient), DEF(BOOL, to_header_ignore_envelope), SETTING_DEFINE_LIST_END, }; static const struct ext_vacation_settings ext_vacation_default_settings = { .min_period = (24*60*60), .max_period = (60*24*60*60), .default_period = (7*24*60*60), .default_subject = "", .default_subject_template = "", .use_original_recipient = FALSE, .check_recipient = TRUE, .send_from_recipient = FALSE, .to_header_ignore_envelope = FALSE, }; const struct setting_parser_info ext_vacation_setting_parser_info = { .name = "sieve_vacation", .defines = ext_vacation_setting_defines, .defaults = &ext_vacation_default_settings, .struct_size = sizeof(struct ext_vacation_settings), .check_func = ext_vacation_settings_check, .pool_offset1 = 1 + offsetof(struct ext_vacation_settings, pool), }; /* */ static bool ext_vacation_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct ext_vacation_settings *set = _set; if (set->max_period == 0) { *error_r = "sieve_vacation_max_period must not be 0"; return FALSE; } if (set->max_period > 0 && (set->min_period > set->max_period || set->default_period < set->min_period || set->default_period > set->max_period)) { *error_r = "Violated sieve_vacation_min_period < " "sieve_vacation_default_period < " "sieve_vacation_max_period"; return FALSE; } return TRUE; } /* */ dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/ext-vacation-common.h0000644000175100001700000000150215100335616030771 0ustar00buildbotbuildbot00000000000000#ifndef EXT_VACATION_COMMON_H #define EXT_VACATION_COMMON_H #include "sieve-common.h" #include "ext-vacation-settings.h" /* * Commands */ extern const struct sieve_command_def vacation_command; /* * Operations */ extern const struct sieve_operation_def vacation_operation; /* * Context */ struct ext_vacation_context { const struct ext_vacation_settings *set; }; /* * Extensions */ /* Vacation */ extern const struct sieve_extension_def vacation_extension; int ext_vacation_load(const struct sieve_extension *ext, void **context); void ext_vacation_unload(const struct sieve_extension *ext); /* Vacation-seconds */ extern const struct sieve_extension_def vacation_seconds_extension; bool ext_vacation_register_seconds_tag( struct sieve_validator *valdtr, const struct sieve_extension *vacation_ext); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/Makefile.in0000644000175100001700000005564615100335630027013 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/vacation ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_vacation_la_LIBADD = am__objects_1 = cmd-vacation.lo am_libsieve_ext_vacation_la_OBJECTS = $(am__objects_1) \ ext-vacation-settings.lo ext-vacation-common.lo \ ext-vacation.lo ext-vacation-seconds.lo libsieve_ext_vacation_la_OBJECTS = \ $(am_libsieve_ext_vacation_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cmd-vacation.Plo \ ./$(DEPDIR)/ext-vacation-common.Plo \ ./$(DEPDIR)/ext-vacation-seconds.Plo \ ./$(DEPDIR)/ext-vacation-settings.Plo \ ./$(DEPDIR)/ext-vacation.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_vacation_la_SOURCES) DIST_SOURCES = $(libsieve_ext_vacation_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_vacation.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ -I$(srcdir)/../../util \ $(LIBDOVECOT_INCLUDE) cmds = \ cmd-vacation.c libsieve_ext_vacation_la_SOURCES = \ $(cmds) \ ext-vacation-settings.c \ ext-vacation-common.c \ ext-vacation.c \ ext-vacation-seconds.c noinst_HEADERS = \ ext-vacation-settings.h \ ext-vacation-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/vacation/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/vacation/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_vacation.la: $(libsieve_ext_vacation_la_OBJECTS) $(libsieve_ext_vacation_la_DEPENDENCIES) $(EXTRA_libsieve_ext_vacation_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_vacation_la_OBJECTS) $(libsieve_ext_vacation_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-vacation.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vacation-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vacation-seconds.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vacation-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vacation.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cmd-vacation.Plo -rm -f ./$(DEPDIR)/ext-vacation-common.Plo -rm -f ./$(DEPDIR)/ext-vacation-seconds.Plo -rm -f ./$(DEPDIR)/ext-vacation-settings.Plo -rm -f ./$(DEPDIR)/ext-vacation.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cmd-vacation.Plo -rm -f ./$(DEPDIR)/ext-vacation-common.Plo -rm -f ./$(DEPDIR)/ext-vacation-seconds.Plo -rm -f ./$(DEPDIR)/ext-vacation-settings.Plo -rm -f ./$(DEPDIR)/ext-vacation.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/cmd-vacation.c0000644000175100001700000012053115100335616027445 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "strfuncs.h" #include "md5.h" #include "hostpid.h" #include "str-sanitize.h" #include "ostream.h" #include "message-address.h" #include "message-date.h" #include "var-expand.h" #include "ioloop.h" #include "mail-storage.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-stringlist.h" #include "sieve-code.h" #include "sieve-address.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-result.h" #include "sieve-message.h" #include "sieve-smtp.h" #include "ext-vacation-common.h" #include /* * Forward declarations */ static const struct sieve_argument_def vacation_days_tag; static const struct sieve_argument_def vacation_subject_tag; static const struct sieve_argument_def vacation_from_tag; static const struct sieve_argument_def vacation_addresses_tag; static const struct sieve_argument_def vacation_mime_tag; static const struct sieve_argument_def vacation_handle_tag; /* * Vacation command * * Syntax: * vacation [":days" number] [":subject" string] * [":from" string] [":addresses" string-list] * [":mime"] [":handle" string] */ static bool cmd_vacation_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_vacation_pre_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_vacation_validate(struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_vacation_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def vacation_command = { .identifier = "vacation", .type = SCT_COMMAND, .positional_args = 1, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = cmd_vacation_registered, .pre_validate = cmd_vacation_pre_validate, .validate = cmd_vacation_validate, .generate = cmd_vacation_generate, }; /* * Vacation command tags */ /* Forward declarations */ static bool cmd_vacation_validate_number_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool cmd_vacation_validate_string_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool cmd_vacation_validate_stringlist_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool cmd_vacation_validate_mime_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); /* Argument objects */ static const struct sieve_argument_def vacation_days_tag = { .identifier = "days", .validate = cmd_vacation_validate_number_tag, }; static const struct sieve_argument_def vacation_seconds_tag = { .identifier = "seconds", .validate = cmd_vacation_validate_number_tag, }; static const struct sieve_argument_def vacation_subject_tag = { .identifier = "subject", .validate = cmd_vacation_validate_string_tag, }; static const struct sieve_argument_def vacation_from_tag = { .identifier = "from", .validate = cmd_vacation_validate_string_tag, }; static const struct sieve_argument_def vacation_addresses_tag = { .identifier = "addresses", .validate = cmd_vacation_validate_stringlist_tag, }; static const struct sieve_argument_def vacation_mime_tag = { .identifier = "mime", .validate = cmd_vacation_validate_mime_tag, }; static const struct sieve_argument_def vacation_handle_tag = { .identifier = "handle", .validate = cmd_vacation_validate_string_tag, }; /* Codes for optional arguments */ enum cmd_vacation_optional { OPT_END, OPT_SECONDS, OPT_SUBJECT, OPT_FROM, OPT_ADDRESSES, OPT_MIME, }; /* * Vacation operation */ static bool ext_vacation_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_vacation_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def vacation_operation = { .mnemonic = "VACATION", .ext_def = &vacation_extension, .dump = ext_vacation_operation_dump, .execute = ext_vacation_operation_execute, }; /* * Vacation action */ /* Forward declarations */ static int act_vacation_check_duplicate(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); int act_vacation_check_conflict(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other); static void act_vacation_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static int act_vacation_commit(const struct sieve_action_exec_env *aenv, void *tr_context); /* Action object */ const struct sieve_action_def act_vacation = { .name = "vacation", .flags = SIEVE_ACTFLAG_SENDS_RESPONSE, .check_duplicate = act_vacation_check_duplicate, .check_conflict = act_vacation_check_conflict, .print = act_vacation_print, .commit = act_vacation_commit, }; /* Action context information */ struct act_vacation_context { const char *reason; sieve_number_t seconds; const char *subject; const char *handle; bool mime; const char *from; const struct smtp_address *from_address; const struct smtp_address *const *addresses; }; /* * Command validation context */ struct cmd_vacation_context_data { string_t *from; string_t *subject; bool mime; struct sieve_ast_argument *handle_arg; }; /* * Tag validation */ static bool cmd_vacation_validate_number_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { const struct sieve_extension *ext = sieve_argument_ext(*arg); const struct ext_vacation_context *extctx = ext->context; struct sieve_ast_argument *tag = *arg; sieve_number_t period, seconds; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :days number */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_NUMBER, FALSE)) return FALSE; period = sieve_ast_argument_number(*arg); if (sieve_argument_is(tag, vacation_days_tag)) seconds = period * (24*60*60); else if (sieve_argument_is(tag, vacation_seconds_tag)) seconds = period; else i_unreached(); i_assert(extctx->set->max_period > 0); /* Enforce :seconds >= min_period */ if (seconds < extctx->set->min_period) { seconds = extctx->set->min_period; sieve_argument_validate_warning( valdtr, *arg, "specified :%s value '%llu' is under the minimum", sieve_argument_identifier(tag), (unsigned long long)period); /* Enforce :days <= max_period */ } else if (seconds > extctx->set->max_period) { seconds = extctx->set->max_period; sieve_argument_validate_warning( valdtr, *arg, "specified :%s value '%llu' is over the maximum", sieve_argument_identifier(tag), (unsigned long long)period); } sieve_ast_argument_number_set(*arg, seconds); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool cmd_vacation_validate_string_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_vacation_context_data *ctx_data = (struct cmd_vacation_context_data *)cmd->data; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :subject string * :from string * :handle string */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE)) return FALSE; if (sieve_argument_is(tag, vacation_from_tag)) { if (sieve_argument_is_string_literal(*arg)) { string_t *address = sieve_ast_argument_str(*arg); const char *error; bool result; T_BEGIN { result = sieve_address_validate_str(address, &error); if (!result) { sieve_argument_validate_error( valdtr, *arg, "specified :from address '%s' is invalid for vacation action: %s", str_sanitize(str_c(address), 128), error); } } T_END; if (!result) return FALSE; } ctx_data->from = sieve_ast_argument_str(*arg); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); } else if (sieve_argument_is(tag, vacation_subject_tag)) { ctx_data->subject = sieve_ast_argument_str(*arg); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); } else if (sieve_argument_is(tag, vacation_handle_tag)) { ctx_data->handle_arg = *arg; /* Detach optional argument (emitted as mandatory) */ *arg = sieve_ast_arguments_detach(*arg, 1); } return TRUE; } static bool cmd_vacation_validate_stringlist_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :addresses string-list */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING_LIST, FALSE)) return FALSE; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool cmd_vacation_validate_mime_tag(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct cmd_vacation_context_data *ctx_data = (struct cmd_vacation_context_data *)cmd->data; ctx_data->mime = TRUE; /* Skip tag */ *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Command registration */ static bool cmd_vacation_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, &vacation_days_tag, OPT_SECONDS); sieve_validator_register_tag(valdtr, cmd_reg, ext, &vacation_subject_tag, OPT_SUBJECT); sieve_validator_register_tag(valdtr, cmd_reg, ext, &vacation_from_tag, OPT_FROM); sieve_validator_register_tag(valdtr, cmd_reg, ext, &vacation_addresses_tag, OPT_ADDRESSES); sieve_validator_register_tag(valdtr, cmd_reg, ext, &vacation_mime_tag, OPT_MIME); sieve_validator_register_tag(valdtr, cmd_reg, ext, &vacation_handle_tag, 0); return TRUE; } bool ext_vacation_register_seconds_tag( struct sieve_validator *valdtr, const struct sieve_extension *vacation_ext) { sieve_validator_register_external_tag( valdtr, vacation_command.identifier, vacation_ext, &vacation_seconds_tag, OPT_SECONDS); return TRUE; } /* * Command validation */ static bool cmd_vacation_pre_validate(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct cmd_vacation_context_data *ctx_data; /* Assign context */ ctx_data = p_new(sieve_command_pool(cmd), struct cmd_vacation_context_data, 1); cmd->data = ctx_data; return TRUE; } static const char _handle_empty_subject[] = ""; static const char _handle_empty_from[] = ""; static const char _handle_mime_enabled[] = ""; static const char _handle_mime_disabled[] = ""; static bool cmd_vacation_validate(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_vacation_context_data *ctx_data = (struct cmd_vacation_context_data *)cmd->data; if (!sieve_validate_positional_argument(valdtr, cmd, arg, "reason", 1, SAAT_STRING)) return FALSE; if (!sieve_validator_argument_activate(valdtr, cmd, arg, FALSE)) return FALSE; /* Construct handle if not set explicitly */ if (ctx_data->handle_arg == NULL) { T_BEGIN { string_t *handle; string_t *reason = sieve_ast_argument_str(arg); unsigned int size = str_len(reason); /* Precalculate the size of it all */ size += (ctx_data->subject == NULL ? sizeof(_handle_empty_subject) - 1 : str_len(ctx_data->subject)); size += (ctx_data->from == NULL ? sizeof(_handle_empty_from) - 1 : str_len(ctx_data->from)); size += (ctx_data->mime ? sizeof(_handle_mime_enabled) - 1 : sizeof(_handle_mime_disabled) - 1); /* Construct the string */ handle = t_str_new(size); str_append_str(handle, reason); if (ctx_data->subject != NULL) str_append_str(handle, ctx_data->subject); else str_append(handle, _handle_empty_subject); if (ctx_data->from != NULL) str_append_str(handle, ctx_data->from); else str_append(handle, _handle_empty_from); str_append(handle, (ctx_data->mime ? _handle_mime_enabled : _handle_mime_disabled)); /* Create positional handle argument */ ctx_data->handle_arg = sieve_ast_argument_string_create( cmd->ast_node, handle, sieve_ast_node_line(cmd->ast_node)); } T_END; if (!sieve_validator_argument_activate( valdtr, cmd, ctx_data->handle_arg, TRUE)) return FALSE; } else { /* Attach explicit handle argument as positional */ (void)sieve_ast_argument_attach(cmd->ast_node, ctx_data->handle_arg); } return TRUE; } /* * Code generation */ static bool cmd_vacation_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &vacation_operation); /* Generate arguments */ if (!sieve_generate_arguments(cgenv, cmd, NULL)) return FALSE; return TRUE; } /* * Code dump */ static bool ext_vacation_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; sieve_code_dumpf(denv, "VACATION"); sieve_code_descend(denv); /* Dump optional operands */ for (;;) { int opt; bool opok = TRUE; if ((opt = sieve_opr_optional_dump(denv, address, &opt_code)) < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_SECONDS: opok = sieve_opr_number_dump(denv, address, "seconds"); break; case OPT_SUBJECT: opok = sieve_opr_string_dump(denv, address, "subject"); break; case OPT_FROM: opok = sieve_opr_string_dump(denv, address, "from"); break; case OPT_ADDRESSES: opok = sieve_opr_stringlist_dump(denv, address, "addresses"); break; case OPT_MIME: sieve_code_dumpf(denv, "mime"); break; default: return FALSE; } if (!opok) return FALSE; } /* Dump reason and handle operands */ return (sieve_opr_string_dump(denv, address, "reason") && sieve_opr_string_dump(denv, address, "handle")); } /* * Code execution */ static int ext_vacation_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; const struct ext_vacation_context *extctx = this_ext->context; struct sieve_side_effects_list *slist = NULL; struct act_vacation_context *act; pool_t pool; int opt_code = 0; sieve_number_t seconds = extctx->set->default_period; bool mime = FALSE; struct sieve_stringlist *addresses = NULL; string_t *reason, *subject = NULL, *from = NULL, *handle = NULL; const struct smtp_address *from_address = NULL; int ret; /* * Read code */ /* Optional operands */ for (;;) { int opt; if ((opt = sieve_opr_optional_read(renv, address, &opt_code)) < 0) return SIEVE_EXEC_BIN_CORRUPT; if (opt == 0) break; switch (opt_code) { case OPT_SECONDS: ret = sieve_opr_number_read(renv, address, "seconds", &seconds); break; case OPT_SUBJECT: ret = sieve_opr_string_read(renv, address, "subject", &subject); break; case OPT_FROM: ret = sieve_opr_string_read(renv, address, "from", &from); break; case OPT_ADDRESSES: ret = sieve_opr_stringlist_read(renv, address, "addresses", &addresses); break; case OPT_MIME: mime = TRUE; ret = SIEVE_EXEC_OK; break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); ret = SIEVE_EXEC_BIN_CORRUPT; } if (ret <= 0) return ret; } /* Fixed operands */ ret = sieve_opr_string_read(renv, address, "reason", &reason); if (ret <= 0) return ret; ret = sieve_opr_string_read(renv, address, "handle", &handle); if (ret <= 0) return ret; /* * Perform operation */ /* Trace */ if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS)) { sieve_runtime_trace(renv, 0, "vacation action"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, "auto-reply with message '%s'", str_sanitize(str_c(reason), 80)); } /* Parse :from address */ if (from != NULL) { const char *error; from_address = sieve_address_parse_str(from, &error); if (from_address == NULL) { sieve_runtime_error( renv, NULL, "specified :from address '%s' is invalid for vacation action: %s", str_sanitize(str_c(from), 128), error); } } /* Add vacation action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_vacation_context, 1); act->reason = p_strdup(pool, str_c(reason)); act->handle = p_strdup(pool, str_c(handle)); act->seconds = seconds; act->mime = mime; if (subject != NULL) act->subject = p_strdup(pool, str_c(subject)); if (from != NULL) { act->from = p_strdup(pool, str_c(from)); act->from_address = smtp_address_clone(pool, from_address); } /* Normalize all addresses */ if (addresses != NULL) { ARRAY_TYPE(smtp_address_const) addrs; string_t *raw_address; int ret; sieve_stringlist_reset(addresses); p_array_init(&addrs, pool, 4); raw_address = NULL; while ((ret = sieve_stringlist_next_item(addresses, &raw_address)) > 0) { const struct smtp_address *addr; const char *error; addr = sieve_address_parse_str(raw_address, &error); if (addr != NULL) { addr = smtp_address_clone(pool, addr); array_append(&addrs, &addr, 1); } else { sieve_runtime_error( renv, NULL, "specified :addresses item '%s' is invalid: " "%s for vacation action (ignored)", str_sanitize(str_c(raw_address),128), error); } } if (ret < 0) { sieve_runtime_trace_error( renv, "invalid addresses stringlist"); return SIEVE_EXEC_BIN_CORRUPT; } (void)array_append_space(&addrs); act->addresses = array_idx(&addrs, 0); } if (sieve_result_add_action(renv, this_ext, "vacation", &act_vacation, slist, act, 0, FALSE) < 0) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } /* * Action */ /* Runtime verification */ static int act_vacation_check_duplicate(const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *act, const struct sieve_action *act_other) { if (!sieve_action_is_executed(act_other, renv->result)) { sieve_runtime_error( renv, act->location, "duplicate vacation action not allowed " "(previously triggered one was here: %s)", act_other->location); return -1; } /* Not an error if executed in preceeding script */ return 1; } int act_vacation_check_conflict(const struct sieve_runtime_env *renv, const struct sieve_action *act, const struct sieve_action *act_other) { if ((act_other->def->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0) { if (!sieve_action_is_executed(act_other, renv->result)) { sieve_runtime_error( renv, act->location, "vacation action conflicts with other action: " "the %s action (%s) also sends a response back to the sender", act_other->def->name, act_other->location); return -1; } else { /* Not an error if executed in preceeding script */ return 1; } } return 0; } /* Result printing */ static void act_vacation_print(const struct sieve_action *action ATTR_UNUSED, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { struct act_vacation_context *ctx = (struct act_vacation_context *)action->context; sieve_result_action_printf(rpenv, "send vacation message:"); sieve_result_printf(rpenv, " => seconds : %llu\n", (unsigned long long)ctx->seconds); if (ctx->subject != NULL) { sieve_result_printf(rpenv, " => subject : %s\n", ctx->subject); } if (ctx->from != NULL) { sieve_result_printf(rpenv, " => from : %s\n", ctx->from); } if (ctx->handle != NULL) { sieve_result_printf(rpenv, " => handle : %s\n", ctx->handle); } sieve_result_printf(rpenv, "\nSTART MESSAGE\n%s\nEND MESSAGE\n", ctx->reason); } /* Result execution */ /* Headers known to be associated with mailing lists */ static const char *const _list_headers[] = { "list-id", "list-owner", "list-subscribe", "list-post", "list-unsubscribe", "list-help", "list-archive", NULL }; /* Headers that should be searched for the user's own mail address(es) */ static const char *const _my_address_headers[] = { "to", "cc", "bcc", "resent-to", "resent-cc", "resent-bcc", NULL }; /* Headers that should be searched for the full sender address */ static const char *const _sender_headers[] = { "sender", "resent-from", "from", NULL }; static inline bool _is_system_address(const struct smtp_address *address) { if (strcasecmp(address->localpart, "MAILER-DAEMON") == 0) return TRUE; if (strcasecmp(address->localpart, "LISTSERV") == 0) return TRUE; if (strcasecmp(address->localpart, "majordomo") == 0) return TRUE; if (strstr(address->localpart, "-request") != NULL) return TRUE; if (str_begins_with(address->localpart, "owner-")) return TRUE; return FALSE; } static bool _msg_address_equals(const struct message_address *addr1, const struct smtp_address *addr2) { struct smtp_address saddr; i_assert(addr1->mailbox != NULL); return (smtp_address_init_from_msg(&saddr, addr1) >= 0 && smtp_address_equals_icase(addr2, &saddr)); } static inline bool _header_contains_my_address(const char *header_val, const struct smtp_address *my_address) { const struct message_address *msg_addr; msg_addr = message_address_parse(pool_datastack_create(), (const unsigned char *)header_val, strlen(header_val), 256, 0); while (msg_addr != NULL) { if (msg_addr->domain != NULL) { if (_msg_address_equals(msg_addr, my_address)) return TRUE; } msg_addr = msg_addr->next; } return FALSE; } static inline bool _contains_my_address(const char *const *headers, const struct smtp_address *my_address) { const char *const *hdsp = headers; while (*hdsp != NULL) { bool result; T_BEGIN { result = _header_contains_my_address(*hdsp, my_address); } T_END; if (result) return TRUE; hdsp++; } return FALSE; } static bool _contains_8bit(const char *text) { const unsigned char *p = (const unsigned char *)text; for (; *p != '\0'; p++) { if ((*p & 0x80) != 0) return TRUE; } return FALSE; } static bool _header_get_full_reply_recipient(const struct ext_vacation_context *extctx, const struct smtp_address *smtp_to, const char *header, struct message_address *reply_to_r) { const struct message_address *addr; addr = message_address_parse( pool_datastack_create(), (const unsigned char *)header, strlen(header), 256, 0); for (; addr != NULL; addr = addr->next) { bool matched = extctx->set->to_header_ignore_envelope; if (addr->domain == NULL || addr->invalid_syntax) continue; if (!matched) matched = _msg_address_equals(addr, smtp_to); if (matched) { *reply_to_r = *addr; return TRUE; } } return FALSE; } static int _get_full_reply_recipient(const struct sieve_action_exec_env *aenv, const struct ext_vacation_context *extctx, const struct smtp_address *smtp_to, struct message_address *reply_to_r) { const struct sieve_execute_env *eenv = aenv->exec_env; const struct sieve_message_data *msgdata = eenv->msgdata; const char *const *hdsp; int ret; hdsp = _sender_headers; for (; *hdsp != NULL; hdsp++) { const char *header; ret = mail_get_first_header(msgdata->mail, *hdsp, &header); if (ret < 0) { return sieve_result_mail_error( aenv, msgdata->mail, "failed to read header field '%s'", *hdsp); } if (ret == 0 || header == NULL) continue; if (_header_get_full_reply_recipient(extctx, smtp_to, header, reply_to_r)) return SIEVE_EXEC_OK; } reply_to_r->mailbox = smtp_to->localpart; reply_to_r->domain = smtp_to->domain; return SIEVE_EXEC_OK; } static const struct var_expand_table * _get_var_expand_table(const struct sieve_action_exec_env *aenv ATTR_UNUSED, const char *subject) { const struct var_expand_table stack_tab[] = { { .key = "subject", .value = subject }, VAR_EXPAND_TABLE_END }; return p_memdup(unsafe_data_stack_pool, stack_tab, sizeof(stack_tab)); } static int act_vacation_get_default_subject(const struct sieve_action_exec_env *aenv, const struct ext_vacation_context *extctx, const char **subject_r) { const struct sieve_execute_env *eenv = aenv->exec_env; const struct sieve_message_data *msgdata = eenv->msgdata; const char *header, *error; string_t *str; int ret; *subject_r = (*extctx->set->default_subject == '\0' ? "Automated reply" : extctx->set->default_subject); ret = mail_get_first_header_utf8(msgdata->mail, "subject", &header); if (ret < 0) { return sieve_result_mail_error( aenv, msgdata->mail, "failed to read header field 'subject'"); } if (ret == 0) return SIEVE_EXEC_OK; if (*extctx->set->default_subject_template == '\0') { *subject_r = t_strconcat("Auto: ", header, NULL); return SIEVE_EXEC_OK; } str = t_str_new(256); const struct var_expand_params params = { .table = _get_var_expand_table(aenv, header), }; if (var_expand(str, extctx->set->default_subject_template, ¶ms, &error) < 0) { e_error(aenv->event, "Failed to expand deliver_log_format=%s: %s", extctx->set->default_subject_template, error); *subject_r = t_strconcat("Auto: ", header, NULL); return SIEVE_EXEC_OK; } *subject_r = str_c(str); return SIEVE_EXEC_OK; } static int act_vacation_send(const struct sieve_action_exec_env *aenv, const struct ext_vacation_context *extctx, struct act_vacation_context *actx, const struct smtp_address *smtp_to, const struct smtp_address *smtp_from, const struct message_address *reply_from) { const struct sieve_execute_env *eenv = aenv->exec_env; const struct sieve_message_data *msgdata = eenv->msgdata; const struct sieve_script_env *senv = eenv->scriptenv; struct sieve_smtp_context *sctx; struct ostream *output; string_t *msg; struct message_address reply_to; const char *header, *outmsgid, *subject, *error; int ret; /* Check smpt functions just to be sure */ if (!sieve_smtp_available(senv)) { sieve_result_global_warning( aenv, "vacation action has no means to send mail"); return SIEVE_EXEC_OK; } /* Make sure we have a subject for our reply */ if (actx->subject == NULL || *(actx->subject) == '\0') { ret = act_vacation_get_default_subject(aenv, extctx, &subject); if (ret <= 0) return ret; } else { subject = actx->subject; } subject = str_sanitize_utf8( subject, SIEVE_MAX_SUBJECT_HEADER_CODEPOINTS); /* Obtain full To address for reply */ i_zero(&reply_to); reply_to.mailbox = smtp_to->localpart; reply_to.domain = smtp_to->domain; ret = _get_full_reply_recipient(aenv, extctx, smtp_to, &reply_to); if (ret <= 0) return ret; /* Open smtp session */ sctx = sieve_smtp_start_single(senv, smtp_to, smtp_from, &output); outmsgid = sieve_message_get_new_id(eenv->svinst); /* Produce a proper reply */ msg = t_str_new(512); rfc2822_header_write(msg, "X-Sieve", SIEVE_IMPLEMENTATION); rfc2822_header_write(msg, "Message-ID", outmsgid); rfc2822_header_write(msg, "Date", message_date_create(ioloop_time)); if (actx->from != NULL && *(actx->from) != '\0') { rfc2822_header_write_address(msg, "From", actx->from); } else { if (reply_from == NULL || reply_from->mailbox == NULL || *reply_from->mailbox == '\0') reply_from = sieve_get_postmaster(senv); rfc2822_header_write( msg, "From", message_address_first_to_string(reply_from)); } rfc2822_header_write(msg, "To", message_address_first_to_string(&reply_to)); if (_contains_8bit(subject)) rfc2822_header_utf8_printf(msg, "Subject", "%s", subject); else rfc2822_header_printf(msg, "Subject", "%s", subject); /* Compose proper in-reply-to and references headers */ ret = mail_get_first_header(msgdata->mail, "references", &header); if (ret < 0) { sieve_smtp_abort(sctx); return sieve_result_mail_error( aenv, msgdata->mail, "failed to read header field 'references'"); } if (msgdata->id != NULL) { rfc2822_header_write(msg, "In-Reply-To", msgdata->id); if (ret > 0 && header != NULL) { rfc2822_header_write( msg, "References", t_strconcat(header, " ", msgdata->id, NULL)); } else { rfc2822_header_write(msg, "References", msgdata->id); } } else if (ret > 0 && header != NULL) { rfc2822_header_write(msg, "References", header); } rfc2822_header_write(msg, "Auto-Submitted", "auto-replied (vacation)"); rfc2822_header_write(msg, "Precedence", "bulk"); /* Prevent older Microsoft products from replying to this message */ rfc2822_header_write(msg, "X-Auto-Response-Suppress", "All"); rfc2822_header_write(msg, "MIME-Version", "1.0"); if (!actx->mime) { rfc2822_header_write(msg, "Content-Type", "text/plain; charset=utf-8"); rfc2822_header_write(msg, "Content-Transfer-Encoding", "8bit"); str_append(msg, "\r\n"); } str_printfa(msg, "%s\r\n", actx->reason); o_stream_nsend(output, str_data(msg), str_len(msg)); /* Close smtp session */ ret = sieve_smtp_finish(sctx, &error); if (ret <= 0) { if (ret < 0) { sieve_result_global_error( aenv, "failed to send vacation response to %s: " "<%s> (temporary error)", smtp_address_encode(smtp_to), str_sanitize(error, 512)); } else { sieve_result_global_log_error( aenv, "failed to send vacation response to %s: " "<%s> (permanent error)", smtp_address_encode(smtp_to), str_sanitize(error, 512)); } /* This error will be ignored in the end */ return SIEVE_EXEC_FAILURE; } eenv->exec_status->significant_action_executed = TRUE; return SIEVE_EXEC_OK; } static void act_vacation_hash(struct act_vacation_context *vctx, const char *sender, unsigned char hash_r[]) { const char *rpath = t_str_lcase(sender); struct md5_context ctx; md5_init(&ctx); md5_update(&ctx, rpath, strlen(rpath)); md5_update(&ctx, vctx->handle, strlen(vctx->handle)); md5_final(&ctx, hash_r); } static int act_vacation_commit(const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED) { const struct sieve_action *action = aenv->action; const struct sieve_extension *ext = action->ext; const struct sieve_execute_env *eenv = aenv->exec_env; struct sieve_instance *svinst = eenv->svinst; const struct ext_vacation_context *extctx = ext->context; struct act_vacation_context *actx = action->context; unsigned char dupl_hash[MD5_RESULTLEN]; struct mail *mail = sieve_message_get_mail(aenv->msgctx); const struct smtp_address *sender, *recipient; const struct smtp_address *orig_recipient, *user_email; const struct smtp_address *smtp_from; struct message_address reply_from; const char *const *hdsp, *const *headers; int ret; if ((eenv->flags & SIEVE_EXECUTE_FLAG_SKIP_RESPONSES) != 0) { sieve_result_global_log( aenv, "not sending vacation reply (skipped)"); return SIEVE_EXEC_OK; } sender = sieve_message_get_sender(aenv->msgctx); recipient = sieve_message_get_final_recipient(aenv->msgctx); i_zero(&reply_from); smtp_from = orig_recipient = user_email = NULL; /* Is the recipient unset? */ if (smtp_address_isnull(recipient)) { sieve_result_global_warning( aenv, "vacation action aborted: " "envelope recipient is <>"); return SIEVE_EXEC_OK; } /* Is the return path unset ? */ if (smtp_address_isnull(sender)) { sieve_result_global_log(aenv, "discarded vacation reply to <>"); return SIEVE_EXEC_OK; } /* Are we perhaps trying to respond to ourselves ? */ if (smtp_address_equals_icase(sender, recipient)) { sieve_result_global_log( aenv, "discarded vacation reply to own address <%s>", smtp_address_encode(sender)); return SIEVE_EXEC_OK; } /* Are we perhaps trying to respond to one of our alternative :addresses? */ if (actx->addresses != NULL) { const struct smtp_address *const *alt_address; alt_address = actx->addresses; while (*alt_address != NULL) { if (smtp_address_equals_icase(sender, *alt_address)) { sieve_result_global_log( aenv, "discarded vacation reply to own address <%s> " "(as specified using :addresses argument)", smtp_address_encode(sender)); return SIEVE_EXEC_OK; } alt_address++; } } /* Did whe respond to this user before? */ if (sieve_action_duplicate_check_available(aenv)) { bool duplicate; act_vacation_hash(actx, smtp_address_encode(sender), dupl_hash); ret = sieve_action_duplicate_check(aenv, dupl_hash, sizeof(dupl_hash), &duplicate); if (ret < SIEVE_EXEC_OK) { sieve_result_critical( aenv, "failed to check for duplicate vacation response", "failed to check for duplicate vacation response%s", (ret == SIEVE_EXEC_TEMP_FAILURE ? " (temporaty failure)" : "")); return ret; } if (duplicate) { sieve_result_global_log( aenv, "discarded duplicate vacation response to <%s>", smtp_address_encode(sender)); return SIEVE_EXEC_OK; } } /* Are we trying to respond to a mailing list ? */ hdsp = _list_headers; while (*hdsp != NULL) { ret = mail_get_headers(mail, *hdsp, &headers); if (ret < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field '%s'", *hdsp); } if (ret > 0 && headers[0] != NULL) { /* Yes, bail out */ sieve_result_global_log( aenv, "discarding vacation response " "to mailinglist recipient <%s>", smtp_address_encode(sender)); return SIEVE_EXEC_OK; } hdsp++; } /* Is the message that we are replying to an automatic reply ? */ ret = mail_get_headers(mail, "auto-submitted", &headers); if (ret < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field 'auto-submitted'"); } /* Theoretically multiple headers could exist, so lets make sure */ if (ret > 0) { hdsp = headers; while (*hdsp != NULL) { if (strcasecmp(*hdsp, "no") != 0) { sieve_result_global_log( aenv, "discarding vacation response " "to auto-submitted message from <%s>", smtp_address_encode(sender)); return SIEVE_EXEC_OK; } hdsp++; } } /* Check for the (non-standard) precedence header */ ret = mail_get_headers(mail, "precedence", &headers); if (ret < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field 'precedence'"); } /* Theoretically multiple headers could exist, so lets make sure */ if (ret > 0) { hdsp = headers; while (*hdsp != NULL) { if (strcasecmp(*hdsp, "junk") == 0 || strcasecmp(*hdsp, "bulk") == 0 || strcasecmp(*hdsp, "list") == 0) { sieve_result_global_log( aenv, "discarding vacation response " "to precedence=%s message from <%s>", *hdsp, smtp_address_encode(sender)); return SIEVE_EXEC_OK; } hdsp++; } } /* Check for the (non-standard) Microsoft X-Auto-Response-Suppress header */ ret = mail_get_headers(mail, "x-auto-response-suppress", &headers); if (ret < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field 'x-auto-response-suppress'"); } /* Theoretically multiple headers could exist, so lets make sure */ if (ret > 0) { hdsp = headers; while (*hdsp != NULL) { const char *const *flags = t_strsplit(*hdsp, ","); while (*flags != NULL) { const char *flag = t_str_trim(*flags, " \t"); if (strcasecmp(flag, "All") == 0 || strcasecmp(flag, "OOF") == 0) { sieve_result_global_log( aenv, "discarding vacation response to message from <%s> " "('%s' flag found in x-auto-response-suppress header)", smtp_address_encode(sender), flag); return SIEVE_EXEC_OK; } flags++; } hdsp++; } } /* Do not reply to system addresses */ if (_is_system_address(sender)) { sieve_result_global_log( aenv, "not sending vacation response to system address <%s>", smtp_address_encode(sender)); return SIEVE_EXEC_OK; } /* Fetch original recipient if necessary */ if (extctx->set->use_original_recipient) orig_recipient = sieve_message_get_orig_recipient(aenv->msgctx); /* Fetch explicitly configured user email address */ if (svinst->set->parsed.user_email != NULL) user_email = svinst->set->parsed.user_email; /* Is the original message directly addressed to the user or the addresses * specified using the :addresses tag? */ hdsp = _my_address_headers; while (*hdsp != NULL) { ret = mail_get_headers(mail, *hdsp, &headers); if (ret < 0) { return sieve_result_mail_error( aenv, mail, "failed to read header field '%s'", *hdsp); } if (ret > 0 && headers[0] != NULL) { /* Final recipient directly listed in headers? */ if (_contains_my_address(headers, recipient)) { smtp_from = recipient; message_address_init_from_smtp( &reply_from, NULL, recipient); break; } /* Original recipient directly listed in headers? */ if (!smtp_address_isnull(orig_recipient) && _contains_my_address(headers, orig_recipient)) { smtp_from = orig_recipient; message_address_init_from_smtp( &reply_from, NULL, orig_recipient); break; } /* User-provided :addresses listed in headers? */ if (actx->addresses != NULL) { bool found = FALSE; const struct smtp_address *const *my_address; my_address = actx->addresses; while (!found && *my_address != NULL) { if ((found = _contains_my_address(headers, *my_address))) { /* Avoid letting user determine SMTP sender directly */ smtp_from = (orig_recipient == NULL ? recipient : orig_recipient); message_address_init_from_smtp( &reply_from, NULL, *my_address); } my_address++; } if (found) break; } /* Explicitly-configured user email address directly listed in headers? */ if (user_email != NULL && _contains_my_address(headers, user_email)) { smtp_from = user_email; message_address_init_from_smtp( &reply_from, NULL, smtp_from); break; } } hdsp++; } /* My address not found in the headers; we got an implicit delivery */ if (*hdsp == NULL) { if (!extctx->set->check_recipient) { /* Send reply from envelope recipient address */ smtp_from = (orig_recipient == NULL ? recipient : orig_recipient); if (user_email == NULL) user_email = sieve_get_user_email(svinst); message_address_init_from_smtp(&reply_from, NULL, user_email); } else { const char *orig_rcpt_str = "", *user_email_str = ""; /* Bail out */ if (extctx->set->use_original_recipient) { orig_rcpt_str = t_strdup_printf("original-recipient=<%s>, ", (orig_recipient == NULL ? "UNAVAILABLE" : smtp_address_encode(orig_recipient))); } if (user_email != NULL) { user_email_str = t_strdup_printf( "user-email=<%s>, ", smtp_address_encode(user_email)); } sieve_result_global_log( aenv, "discarding vacation response for implicitly delivered message; " "no known (envelope) recipient address found in message headers " "(recipient=<%s>, %s%sand%s additional ':addresses' are specified)", smtp_address_encode(recipient), orig_rcpt_str, user_email_str, (actx->addresses == NULL || *actx->addresses == NULL ? " no" : "")); return SIEVE_EXEC_OK; } } /* Send the message */ T_BEGIN { ret = act_vacation_send( aenv, extctx, actx, sender, (extctx->set->send_from_recipient ? smtp_from : NULL), &reply_from); } T_END; if (ret == SIEVE_EXEC_OK) { sieve_number_t seconds; eenv->exec_status->significant_action_executed = TRUE; struct event_passthrough *e = sieve_action_create_finish_event(aenv); sieve_result_event_log(aenv, e->event(), "sent vacation response to <%s>", smtp_address_encode(sender)); /* Check period limits once more */ seconds = actx->seconds; if (seconds < extctx->set->min_period) seconds = extctx->set->min_period; else if (extctx->set->max_period > 0 && seconds > extctx->set->max_period) seconds = extctx->set->max_period; /* Mark as replied */ if (seconds > 0) { sieve_action_duplicate_mark(aenv, dupl_hash, sizeof(dupl_hash), ioloop_time + seconds); } } if (ret == SIEVE_EXEC_TEMP_FAILURE) return SIEVE_EXEC_TEMP_FAILURE; /* Ignore all other errors */ return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/vacation/ext-vacation-seconds.c0000644000175100001700000000430015100335616031131 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension vacation-seconds * -------------------------- * * Authors: Stephan Bosch * Specification: RFC 6131 * Implementation: full * Status: testing * */ #include "lib.h" #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-validator.h" #include "ext-vacation-common.h" /* * Extension */ struct ext_vacation_seconds_context { const struct sieve_extension *ext_vacation; }; static int ext_vacation_seconds_load(const struct sieve_extension *ext, void **context); static void ext_vacation_seconds_unload(const struct sieve_extension *ext); static bool ext_vacation_seconds_validator_load(const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def vacation_seconds_extension = { .name = "vacation-seconds", .load = ext_vacation_seconds_load, .unload = ext_vacation_seconds_unload, .validator_load = ext_vacation_seconds_validator_load, }; static int ext_vacation_seconds_load(const struct sieve_extension *ext, void **context) { const struct sieve_extension *ext_vac; struct ext_vacation_seconds_context *extctx; if (*context != NULL) { ext_vacation_seconds_unload(ext); *context = NULL; } /* Make sure vacation extension is registered */ if (sieve_extension_require(ext->svinst, &vacation_extension, TRUE, &ext_vac) < 0) return -1; extctx = i_new(struct ext_vacation_seconds_context, 1); extctx->ext_vacation = ext_vac; *context = extctx; return 0; } static void ext_vacation_seconds_unload(const struct sieve_extension *ext) { struct ext_vacation_seconds_context *extctx = ext->context; if (extctx == NULL) return; i_free(extctx); } static bool ext_vacation_seconds_validator_load( const struct sieve_extension *ext ATTR_UNUSED, struct sieve_validator *valdtr) { const struct sieve_extension *vacation_ext; /* Load vacation extension implicitly */ vacation_ext = sieve_validator_extension_load_implicit( valdtr, vacation_extension.name); if (vacation_ext == NULL) return FALSE; /* Add seconds tag to vacation command */ return ext_vacation_register_seconds_tag(valdtr, vacation_ext); } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/0000755000175100001700000000000015100335670025100 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c0000644000175100001700000001725615100335616031315 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "md5.h" #include "ioloop.h" #include "str.h" #include "str-sanitize.h" #include "array.h" #include "settings.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-message.h" #include "sieve-code.h" #include "sieve-runtime.h" #include "sieve-interpreter.h" #include "sieve-actions.h" #include "sieve-result.h" #include "ext-duplicate-settings.h" #include "ext-duplicate-common.h" /* * Extension configuration */ int ext_duplicate_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; const struct ext_duplicate_settings *set; struct ext_duplicate_context *extctx; const char *error; if (settings_get(svinst->event, &ext_duplicate_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } extctx = i_new(struct ext_duplicate_context, 1); extctx->set = set; *context_r = extctx; return 0; } void ext_duplicate_unload(const struct sieve_extension *ext) { struct ext_duplicate_context *extctx = ext->context; if (extctx == NULL) return; settings_free(extctx->set); i_free(extctx); } /* * Duplicate_mark action */ struct act_duplicate_mark_data { const char *handle; unsigned int period; unsigned char hash[MD5_RESULTLEN]; bool last:1; }; static void act_duplicate_mark_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep); static void act_duplicate_mark_finish(const struct sieve_action_exec_env *aenv, void *tr_context, int status); static const struct sieve_action_def act_duplicate_mark = { .name = "duplicate_mark", .print = act_duplicate_mark_print, .finish = act_duplicate_mark_finish, }; static void act_duplicate_mark_print(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { struct act_duplicate_mark_data *data = (struct act_duplicate_mark_data *)action->context; const char *last = (data->last ? " last" : ""); if (data->handle != NULL) { sieve_result_action_printf( rpenv, "track%s duplicate with handle: %s", last, str_sanitize(data->handle, 128)); } else { sieve_result_action_printf(rpenv, "track%s duplicate", last); } } static void act_duplicate_mark_finish(const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED, int status) { const struct sieve_execute_env *eenv = aenv->exec_env; struct act_duplicate_mark_data *data = (struct act_duplicate_mark_data *)aenv->action->context; if (status != SIEVE_EXEC_OK) { e_debug(aenv->event, "Not marking duplicate (status=%s)", sieve_execution_exitcode_to_str(status)); return; } e_debug(aenv->event, "Marking duplicate"); /* Message was handled successfully, so track duplicate for this * message. */ eenv->exec_status->significant_action_executed = TRUE; sieve_action_duplicate_mark(aenv, data->hash, sizeof(data->hash), ioloop_time + data->period); } /* * Duplicate checking */ struct ext_duplicate_handle { const char *handle; bool last:1; bool duplicate:1; }; struct ext_duplicate_hash { unsigned char hash[MD5_RESULTLEN]; ARRAY(struct ext_duplicate_handle) handles; }; struct ext_duplicate_runtime_context { ARRAY(struct ext_duplicate_hash) hashes; }; static void ext_duplicate_hash(string_t *handle, const char *value, size_t value_len, bool last, unsigned char hash_r[]) { static const char *id = "sieve duplicate"; struct md5_context md5ctx; md5_init(&md5ctx); md5_update(&md5ctx, id, strlen(id)); if (last) md5_update(&md5ctx, "0", 1); else md5_update(&md5ctx, "+", 1); if (handle != NULL) { md5_update(&md5ctx, "h-", 2); md5_update(&md5ctx, str_c(handle), str_len(handle)); } else { md5_update(&md5ctx, "default", 7); } md5_update(&md5ctx, value, value_len); md5_final(&md5ctx, hash_r); } int ext_duplicate_check(const struct sieve_runtime_env *renv, string_t *handle, const char *value, size_t value_len, sieve_number_t period, bool last, bool *duplicate_r) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_extension *this_ext = renv->oprtn->ext; struct ext_duplicate_runtime_context *rctx; bool duplicate = FALSE; pool_t msg_pool = NULL, result_pool = NULL; unsigned char hash[MD5_RESULTLEN]; struct ext_duplicate_hash *hash_record = NULL; struct ext_duplicate_handle *handle_record = NULL; struct act_duplicate_mark_data *act; int ret; *duplicate_r = FALSE; if (!sieve_execute_duplicate_check_available(eenv)) { sieve_runtime_warning( renv, NULL, "duplicate test: " "duplicate checking not available in this context"); return SIEVE_EXEC_OK; } if (value == NULL) return SIEVE_EXEC_OK; /* Create hash */ ext_duplicate_hash(handle, value, value_len, last, hash); /* Get context; find out whether duplicate was checked earlier */ rctx = sieve_message_context_extension_get(renv->msgctx, this_ext); if (rctx == NULL) { /* Create context */ msg_pool = sieve_message_context_pool(renv->msgctx); rctx = p_new(msg_pool, struct ext_duplicate_runtime_context, 1); sieve_message_context_extension_set(renv->msgctx, this_ext, rctx); } else if (array_is_created(&rctx->hashes)) { struct ext_duplicate_hash *record; array_foreach_modifiable(&rctx->hashes, record) { if (memcmp(record->hash, hash, MD5_RESULTLEN) == 0) { hash_record = record; break; } } } if (hash_record != NULL) { const struct ext_duplicate_handle *rhandle; array_foreach(&hash_record->handles, rhandle) { const char *handle_str = (handle == NULL ? NULL : str_c(handle)); if (null_strcmp(rhandle->handle, handle_str) == 0 && rhandle->last == last) return (rhandle->duplicate ? SIEVE_DUPLICATE_CHECK_RESULT_EXISTS : SIEVE_DUPLICATE_CHECK_RESULT_NOT_FOUND); } } result_pool = sieve_result_pool(renv->result); act = p_new(result_pool, struct act_duplicate_mark_data, 1); if (handle != NULL) act->handle = p_strdup(result_pool, str_c(handle)); act->period = period; memcpy(act->hash, hash, MD5_RESULTLEN); act->last = last; /* Check duplicate */ ret = sieve_execute_duplicate_check(eenv, hash, sizeof(hash), &duplicate); if (ret >= SIEVE_EXEC_OK && !duplicate && last) { unsigned char no_last_hash[MD5_RESULTLEN]; /* Check for entry without :last */ ext_duplicate_hash(handle, value, value_len, FALSE, no_last_hash); ret = sieve_execute_duplicate_check( eenv, no_last_hash, sizeof(no_last_hash), &duplicate); } if (ret < SIEVE_EXEC_OK) { sieve_runtime_critical( renv, NULL, "failed to check for duplicate", "failed to check for duplicate%s", (ret == SIEVE_EXEC_TEMP_FAILURE ? " (temporary failure)" : "")); return ret; } /* We may only mark the message as duplicate when Sieve script executes successfully; therefore defer this operation until successful result execution. */ if (!duplicate || last) { if (sieve_result_add_action(renv, NULL, NULL, &act_duplicate_mark, NULL, act, 0, FALSE) < 0) return SIEVE_EXEC_FAILURE; } /* Cache result */ if (msg_pool == NULL) msg_pool = sieve_message_context_pool(renv->msgctx); if (hash_record == NULL) { if (!array_is_created(&rctx->hashes)) p_array_init(&rctx->hashes, msg_pool, 64); hash_record = array_append_space(&rctx->hashes); memcpy(hash_record->hash, hash, MD5_RESULTLEN); p_array_init(&hash_record->handles, msg_pool, 64); } handle_record = array_append_space(&hash_record->handles); if (handle != NULL) handle_record->handle = p_strdup(msg_pool, str_c(handle)); handle_record->last = last; handle_record->duplicate = duplicate; *duplicate_r = duplicate; return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/ext-duplicate.c0000644000175100001700000000205515100335616030016 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Extension duplicate * ------------------- * * Authors: Stephan Bosch * Specification: vendor-defined; spec-bosch-sieve-duplicate * Implementation: full * Status: experimental * */ #include "lib.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" #include "sieve-validator.h" #include "ext-duplicate-common.h" /* * Extensions */ static bool ext_duplicate_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr); const struct sieve_extension_def duplicate_extension = { .name = "duplicate", .load = ext_duplicate_load, .unload = ext_duplicate_unload, .validator_load = ext_duplicate_validator_load, SIEVE_EXT_DEFINE_OPERATION(tst_duplicate_operation) }; /* * Validation */ static bool ext_duplicate_validator_load (const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register duplicate test */ sieve_validator_register_command(valdtr, ext, &tst_duplicate); return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/Makefile.am0000644000175100001700000000055215100335616027136 0ustar00buildbotbuildbot00000000000000noinst_LTLIBRARIES = libsieve_ext_duplicate.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-duplicate.c extensions = \ ext-duplicate.c libsieve_ext_duplicate_la_SOURCES = \ $(tests) \ $(extensions) \ ext-duplicate-settings.c \ ext-duplicate-common.c noinst_HEADERS = \ ext-duplicate-settings.h \ ext-duplicate-common.h dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/ext-duplicate-settings.h0000644000175100001700000000040115100335616031652 0ustar00buildbotbuildbot00000000000000#ifndef EXT_DUPLICATE_SETTINGS_H #define EXT_DUPLICATE_SETTINGS_H struct ext_duplicate_settings { pool_t pool; unsigned int default_period; unsigned int max_period; }; extern const struct setting_parser_info ext_duplicate_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/tst-duplicate.c0000644000175100001700000002426615100335616030040 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mail-storage.h" #include "sieve-common.h" #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "ext-duplicate-settings.h" #include "ext-duplicate-common.h" /* Duplicate test * * Syntax: * Usage: "duplicate" [":handle" ] * [":header" / * ":uniqueid" ] * [":seconds" ] [":last"] */ static bool tst_duplicate_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_duplicate_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); const struct sieve_command_def tst_duplicate = { .identifier = "duplicate", .type = SCT_TEST, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .registered = tst_duplicate_registered, .generate = tst_duplicate_generate }; /* * Duplicate test tags */ static bool tst_duplicate_validate_number_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static bool tst_duplicate_validate_string_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd); static const struct sieve_argument_def duplicate_seconds_tag = { .identifier = "seconds", .validate = tst_duplicate_validate_number_tag }; static const struct sieve_argument_def duplicate_header_tag = { .identifier = "header", .validate = tst_duplicate_validate_string_tag }; static const struct sieve_argument_def duplicate_uniqueid_tag = { .identifier = "uniqueid", .validate = tst_duplicate_validate_string_tag }; static const struct sieve_argument_def duplicate_handle_tag = { .identifier = "handle", .validate = tst_duplicate_validate_string_tag }; static const struct sieve_argument_def duplicate_last_tag = { .identifier = "last" }; /* Codes for optional arguments */ enum tst_duplicate_optional { OPT_END, OPT_SECONDS, OPT_HEADER, OPT_UNIQUEID, OPT_LAST, OPT_HANDLE }; /* * Duplicate operation */ static bool tst_duplicate_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_duplicate_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def tst_duplicate_operation = { .mnemonic = "DUPLICATE", .ext_def = &duplicate_extension, .dump = tst_duplicate_operation_dump, .execute = tst_duplicate_operation_execute }; /* * Tag validation */ static bool tst_duplicate_validate_number_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { const struct sieve_extension *ext = sieve_argument_ext(*arg); const struct ext_duplicate_context *extctx = ext->context; struct sieve_ast_argument *tag = *arg; sieve_number_t seconds; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :seconds number */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_NUMBER, FALSE)) return FALSE; seconds = sieve_ast_argument_number(*arg); /* Enforce :days <= max_period */ if (extctx->set->max_period > 0 && seconds > extctx->set->max_period) { seconds = extctx->set->max_period; sieve_argument_validate_warning( valdtr, *arg, "specified :seconds value '%llu' is over the maximum", (unsigned long long)seconds); } sieve_ast_argument_number_set(*arg, seconds); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } static bool tst_duplicate_validate_string_tag(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { const struct sieve_extension *ext = cmd->ext; struct sieve_ast_argument *tag = *arg; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: :header :value :handle */ if (!sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE)) return FALSE; if (!sieve_argument_is(tag, duplicate_handle_tag) && (bool)cmd->data) { sieve_argument_validate_error( valdtr, *arg, "conflicting :header and %s arguments specified " "for the duplicate test", (sieve_extension_is(ext, duplicate_extension) ? ":uniqueid" : ":value")); return FALSE; } /* :header */ if (sieve_argument_is(tag, duplicate_header_tag)) { if (!sieve_command_verify_headers_argument(valdtr, *arg)) return FALSE; cmd->data = (void *)TRUE; /* :handle */ } else if (sieve_argument_is(tag, duplicate_handle_tag)) { /* nothing to be done */ } else if (sieve_argument_is(tag, duplicate_uniqueid_tag)) { i_assert(sieve_extension_is(ext, duplicate_extension)); cmd->data = (void *)TRUE; } else { i_unreached(); } /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); return TRUE; } /* * Command registration */ static bool tst_duplicate_registered(struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag(valdtr, cmd_reg, ext, &duplicate_seconds_tag, OPT_SECONDS); sieve_validator_register_tag(valdtr, cmd_reg, ext, &duplicate_last_tag, OPT_LAST); sieve_validator_register_tag(valdtr, cmd_reg, ext, &duplicate_header_tag, OPT_HEADER); sieve_validator_register_tag(valdtr, cmd_reg, ext, &duplicate_uniqueid_tag, OPT_UNIQUEID); sieve_validator_register_tag(valdtr, cmd_reg, ext, &duplicate_handle_tag, OPT_HANDLE); return TRUE; } /* * Code generation */ static bool tst_duplicate_generate(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { sieve_operation_emit(cgenv->sblock, cmd->ext, &tst_duplicate_operation); if (!sieve_generate_arguments(cgenv, cmd, NULL)) return FALSE; return TRUE; } /* * Code dump */ static bool tst_duplicate_operation_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct sieve_extension *ext = denv->oprtn->ext; int opt_code = 0; sieve_code_dumpf(denv, "DUPLICATE"); sieve_code_descend(denv); /* Dump optional operands */ for (;;) { int opt; bool opok = TRUE; if ((opt = sieve_opr_optional_dump(denv, address, &opt_code)) < 0) return FALSE; if (opt == 0) break; switch (opt_code) { case OPT_SECONDS: opok = sieve_opr_number_dump(denv, address, "seconds"); break; case OPT_LAST: sieve_code_dumpf(denv, "last"); break; case OPT_HEADER: opok = sieve_opr_string_dump(denv, address, "header"); break; case OPT_UNIQUEID: if (sieve_extension_is(ext, duplicate_extension)) { opok = sieve_opr_string_dump(denv, address, "uniqueid"); } else { opok = sieve_opr_string_dump(denv, address, "value"); } break; case OPT_HANDLE: opok = sieve_opr_string_dump(denv, address, "handle"); break; default: return FALSE; } if (!opok) return FALSE; } return TRUE; } /* * Code execution */ static int tst_duplicate_operation_execute(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { const struct sieve_execute_env *eenv = renv->exec_env; const struct sieve_extension *ext = renv->oprtn->ext; const struct ext_duplicate_context *extctx = ext->context; struct mail *mail = eenv->msgdata->mail; int opt_code = 0; string_t *handle = NULL, *header = NULL, *uniqueid = NULL; const char *val = NULL; size_t val_len = 0; sieve_number_t seconds = extctx->set->default_period; bool last = FALSE, duplicate = FALSE; int ret; /* * Read operands */ /* Optional operands */ for (;;) { int opt; if ((opt = sieve_opr_optional_read(renv, address, &opt_code)) < 0) return SIEVE_EXEC_BIN_CORRUPT; if (opt == 0) break; switch (opt_code) { case OPT_SECONDS: ret = sieve_opr_number_read(renv, address, "seconds", &seconds); break; case OPT_LAST: last = TRUE; ret = SIEVE_EXEC_OK; break; case OPT_HEADER: ret = sieve_opr_string_read(renv, address, "header", &header); break; case OPT_UNIQUEID: if (sieve_extension_is(ext, duplicate_extension)) { ret = sieve_opr_string_read(renv, address, "uniqueid", &uniqueid); } else { ret = sieve_opr_string_read(renv, address, "value", &uniqueid); } break; case OPT_HANDLE: ret = sieve_opr_string_read(renv, address, "handle", &handle); break; default: sieve_runtime_trace_error( renv, "unknown optional operand"); ret = SIEVE_EXEC_BIN_CORRUPT; } if (ret <= 0) return ret; } /* * Perform operation */ /* Trace */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "duplicate test"); sieve_runtime_trace_descend(renv); /* Get value */ if (uniqueid != NULL) { val = str_c(uniqueid); val_len = str_len(uniqueid); } else { if (header == NULL) { ret = mail_get_message_id(mail, &val); if (ret < 0) { return sieve_runtime_mail_error( renv, mail, "duplicate test: " "failed to read header field 'message-id'"); } } else { ret = mail_get_first_header_utf8(mail, str_c(header), &val); if (ret < 0) { return sieve_runtime_mail_error( renv, mail, "duplicate test: " "failed to read header field '%s'", str_c(header)); } } if (ret > 0) val_len = strlen(val); } /* Check duplicate */ if (val == NULL) { duplicate = FALSE; } else { ret = ext_duplicate_check(renv, handle, val, val_len, seconds, last, &duplicate); if (ret < SIEVE_EXEC_OK) return ret; } /* Trace */ if (duplicate) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "message is a duplicate"); } else { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "message is not a duplicate"); } /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, duplicate); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/Makefile.in0000644000175100001700000005533015100335630027147 0ustar00buildbotbuildbot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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 = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } 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 = : build_triplet = @build@ host_triplet = @host@ subdir = src/lib-sieve/plugins/duplicate ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dovecot.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/test_with.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dummy-config.h \ $(top_builddir)/pigeonhole-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsieve_ext_duplicate_la_LIBADD = am__objects_1 = tst-duplicate.lo am__objects_2 = ext-duplicate.lo am_libsieve_ext_duplicate_la_OBJECTS = $(am__objects_1) \ $(am__objects_2) ext-duplicate-settings.lo \ ext-duplicate-common.lo libsieve_ext_duplicate_la_OBJECTS = \ $(am_libsieve_ext_duplicate_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = 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)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ext-duplicate-common.Plo \ ./$(DEPDIR)/ext-duplicate-settings.Plo \ ./$(DEPDIR)/ext-duplicate.Plo ./$(DEPDIR)/tst-duplicate.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=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 = $(libsieve_ext_duplicate_la_SOURCES) DIST_SOURCES = $(libsieve_ext_duplicate_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINARY_CFLAGS = @BINARY_CFLAGS@ BINARY_LDFLAGS = @BINARY_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DOVECOT_BINARY_CFLAGS = @DOVECOT_BINARY_CFLAGS@ DOVECOT_BINARY_LDFLAGS = @DOVECOT_BINARY_LDFLAGS@ DOVECOT_CFLAGS = @DOVECOT_CFLAGS@ DOVECOT_COMPRESS_LIBS = @DOVECOT_COMPRESS_LIBS@ DOVECOT_INSTALLED = @DOVECOT_INSTALLED@ DOVECOT_LDAP_LIBS = @DOVECOT_LDAP_LIBS@ DOVECOT_LIBS = @DOVECOT_LIBS@ DOVECOT_LUA_CFLAGS = @DOVECOT_LUA_CFLAGS@ DOVECOT_LUA_LIBS = @DOVECOT_LUA_LIBS@ DOVECOT_SQL_LIBS = @DOVECOT_SQL_LIBS@ DOVECOT_SSL_LIBS = @DOVECOT_SSL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ LIBDOVECOT = @LIBDOVECOT@ LIBDOVECOT_ACL_INCLUDE = @LIBDOVECOT_ACL_INCLUDE@ LIBDOVECOT_AUTH_INCLUDE = @LIBDOVECOT_AUTH_INCLUDE@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_COMPRESS_DEPS = @LIBDOVECOT_COMPRESS_DEPS@ LIBDOVECOT_CONFIG_INCLUDE = @LIBDOVECOT_CONFIG_INCLUDE@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DOVEADM_INCLUDE = @LIBDOVECOT_DOVEADM_INCLUDE@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ LIBDOVECOT_DSYNC_DEPS = @LIBDOVECOT_DSYNC_DEPS@ LIBDOVECOT_DSYNC_INCLUDE = @LIBDOVECOT_DSYNC_INCLUDE@ LIBDOVECOT_FTS_INCLUDE = @LIBDOVECOT_FTS_INCLUDE@ LIBDOVECOT_GSSAPI = @LIBDOVECOT_GSSAPI@ LIBDOVECOT_GSSAPI_DEPS = @LIBDOVECOT_GSSAPI_DEPS@ LIBDOVECOT_IMAPC_INCLUDE = @LIBDOVECOT_IMAPC_INCLUDE@ LIBDOVECOT_IMAP_INCLUDE = @LIBDOVECOT_IMAP_INCLUDE@ LIBDOVECOT_IMAP_LOGIN_INCLUDE = @LIBDOVECOT_IMAP_LOGIN_INCLUDE@ LIBDOVECOT_INCLUDE = @LIBDOVECOT_INCLUDE@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LDAP_DEPS = @LIBDOVECOT_LDAP_DEPS@ LIBDOVECOT_LDAP_INCLUDE = @LIBDOVECOT_LDAP_INCLUDE@ LIBDOVECOT_LDA_DEPS = @LIBDOVECOT_LDA_DEPS@ LIBDOVECOT_LDA_INCLUDE = @LIBDOVECOT_LDA_INCLUDE@ LIBDOVECOT_LIBLANG = @LIBDOVECOT_LIBLANG@ LIBDOVECOT_LIBLANG_DEPS = @LIBDOVECOT_LIBLANG_DEPS@ LIBDOVECOT_LIBLANG_INCLUDE = @LIBDOVECOT_LIBLANG_INCLUDE@ LIBDOVECOT_LMTP_INCLUDE = @LIBDOVECOT_LMTP_INCLUDE@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ LIBDOVECOT_LOGIN_DEPS = @LIBDOVECOT_LOGIN_DEPS@ LIBDOVECOT_LOGIN_INCLUDE = @LIBDOVECOT_LOGIN_INCLUDE@ LIBDOVECOT_LUA = @LIBDOVECOT_LUA@ LIBDOVECOT_LUA_DEPS = @LIBDOVECOT_LUA_DEPS@ LIBDOVECOT_LUA_INCLUDE = @LIBDOVECOT_LUA_INCLUDE@ LIBDOVECOT_NOTIFY_INCLUDE = @LIBDOVECOT_NOTIFY_INCLUDE@ LIBDOVECOT_OPENSSL = @LIBDOVECOT_OPENSSL@ LIBDOVECOT_OPENSSL_DEPS = @LIBDOVECOT_OPENSSL_DEPS@ LIBDOVECOT_POP3_INCLUDE = @LIBDOVECOT_POP3_INCLUDE@ LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE = @LIBDOVECOT_PUSH_NOTIFICATION_INCLUDE@ LIBDOVECOT_SERVICE_INCLUDE = @LIBDOVECOT_SERVICE_INCLUDE@ LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ LIBDOVECOT_SQL_DEPS = @LIBDOVECOT_SQL_DEPS@ LIBDOVECOT_SQL_INCLUDE = @LIBDOVECOT_SQL_INCLUDE@ LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ LIBDOVECOT_STORAGE_INCLUDE = @LIBDOVECOT_STORAGE_INCLUDE@ LIBDOVECOT_SUBMISSION_INCLUDE = @LIBDOVECOT_SUBMISSION_INCLUDE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ 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@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ PIGEONHOLE_ASSET_URL = @PIGEONHOLE_ASSET_URL@ PIGEONHOLE_ASSET_VERSION = @PIGEONHOLE_ASSET_VERSION@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RELRO_LDFLAGS = @RELRO_LDFLAGS@ RUN_TEST = @RUN_TEST@ SED = @SED@ SETTING_FILES = @SETTING_FILES@ SETTING_LINKED_FILES = @SETTING_LINKED_FILES@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WGET = @WGET@ abs_builddir = @abs_builddir@ abs_dovecotdir = @abs_dovecotdir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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 = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dovecot_docdir = @dovecot_docdir@ dovecot_installed_moduledir = @dovecot_installed_moduledir@ dovecot_moduledir = @dovecot_moduledir@ dovecot_pkgincludedir = @dovecot_pkgincludedir@ dovecot_pkglibdir = @dovecot_pkglibdir@ dovecot_pkglibexecdir = @dovecot_pkglibexecdir@ dovecot_statedir = @dovecot_statedir@ dovecotdir = @dovecotdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sieve_docdir = @sieve_docdir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libsieve_ext_duplicate.la AM_CPPFLAGS = \ -I$(srcdir)/../.. \ $(LIBDOVECOT_INCLUDE) tests = \ tst-duplicate.c extensions = \ ext-duplicate.c libsieve_ext_duplicate_la_SOURCES = \ $(tests) \ $(extensions) \ ext-duplicate-settings.c \ ext-duplicate-common.c noinst_HEADERS = \ ext-duplicate-settings.h \ ext-duplicate-common.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .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) --foreign src/lib-sieve/plugins/duplicate/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/lib-sieve/plugins/duplicate/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 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): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsieve_ext_duplicate.la: $(libsieve_ext_duplicate_la_OBJECTS) $(libsieve_ext_duplicate_la_DEPENDENCIES) $(EXTRA_libsieve_ext_duplicate_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsieve_ext_duplicate_la_OBJECTS) $(libsieve_ext_duplicate_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-duplicate-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-duplicate-settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-duplicate.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-duplicate.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: 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-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ext-duplicate-common.Plo -rm -f ./$(DEPDIR)/ext-duplicate-settings.Plo -rm -f ./$(DEPDIR)/ext-duplicate.Plo -rm -f ./$(DEPDIR)/tst-duplicate.Plo -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-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ext-duplicate-common.Plo -rm -f ./$(DEPDIR)/ext-duplicate-settings.Plo -rm -f ./$(DEPDIR)/ext-duplicate.Plo -rm -f ./$(DEPDIR)/tst-duplicate.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/ext-duplicate-common.h0000644000175100001700000000137515100335616031315 0ustar00buildbotbuildbot00000000000000#ifndef EXT_DUPLICATE_COMMON_H #define EXT_DUPLICATE_COMMON_H #include "sieve-common.h" /* * Extension */ struct ext_duplicate_context { const struct ext_duplicate_settings *set; }; int ext_duplicate_load(const struct sieve_extension *ext, void **context_r); void ext_duplicate_unload(const struct sieve_extension *ext); extern const struct sieve_extension_def duplicate_extension; /* * Tests */ extern const struct sieve_command_def tst_duplicate; /* * Operations */ extern const struct sieve_operation_def tst_duplicate_operation; /* * Duplicate checking */ int ext_duplicate_check(const struct sieve_runtime_env *renv, string_t *handle, const char *value, size_t value_len, sieve_number_t period, bool last, bool *duplicate_r); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/plugins/duplicate/ext-duplicate-settings.c0000644000175100001700000000167415100335616031662 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "settings.h" #include "settings-parser.h" #include "ext-duplicate-settings.h" #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("sieve_duplicate_"#name, name, \ struct ext_duplicate_settings) static const struct setting_define ext_duplicate_setting_defines[] = { DEF(TIME, default_period), DEF(TIME, max_period), SETTING_DEFINE_LIST_END, }; static const struct ext_duplicate_settings ext_duplicate_default_settings = { .default_period = (12*60*60), .max_period = (2*24*60*60), }; const struct setting_parser_info ext_duplicate_setting_parser_info = { .name = "sieve_duplicate", .defines = ext_duplicate_setting_defines, .defaults = &ext_duplicate_default_settings, .struct_size = sizeof(struct ext_duplicate_settings), .pool_offset1 = 1 + offsetof(struct ext_duplicate_settings, pool), }; dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary.h0000644000175100001700000002075715100335616024226 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_BINARY_H #define SIEVE_BINARY_H #include "lib.h" #include "sieve-common.h" /* * Config */ #define SIEVE_BINARY_VERSION_MAJOR 3 #define SIEVE_BINARY_VERSION_MINOR 0 #define SIEVE_BINARY_BASE_HEADER_SIZE 20 /* * Binary object */ struct sieve_binary; struct sieve_binary *sieve_binary_create_new(struct sieve_script *script); void sieve_binary_ref(struct sieve_binary *sbin); void sieve_binary_unref(struct sieve_binary **_sbin); void sieve_binary_close(struct sieve_binary **_sbin); /* * Resource usage */ void sieve_binary_get_resource_usage(struct sieve_binary *sbin, struct sieve_resource_usage *rusage_r); bool sieve_binary_record_resource_usage( struct sieve_binary *sbin, const struct sieve_resource_usage *rusage) ATTR_NULL(1); void sieve_binary_set_resource_usage(struct sieve_binary *sbin, const struct sieve_resource_usage *rusage); /* * Accessors */ pool_t sieve_binary_pool(struct sieve_binary *sbin); struct sieve_instance *sieve_binary_svinst(struct sieve_binary *sbin); const char *sieve_binary_path(struct sieve_binary *sbin); struct sieve_script *sieve_binary_script(struct sieve_binary *sbin); time_t sieve_binary_mtime(struct sieve_binary *sbin); const struct stat *sieve_binary_stat(struct sieve_binary *sbin); const char *sieve_binary_script_name(struct sieve_binary *sbin); const char *sieve_binary_script_location(struct sieve_binary *sbin); const char *sieve_binary_source(struct sieve_binary *sbin); bool sieve_binary_loaded(struct sieve_binary *sbin); bool sieve_binary_saved(struct sieve_binary *sbin); /* * Utility */ const char *sieve_binfile_from_name(const char *name); /* * Activation after code generation */ void sieve_binary_activate(struct sieve_binary *sbin); /* * Saving the binary */ int sieve_binary_save(struct sieve_binary *sbin, const char *path, bool update, mode_t save_mode, enum sieve_error *error_code_r); /* * Loading the binary */ int sieve_binary_open(struct sieve_instance *svinst, const char *path, struct sieve_script *script, struct sieve_binary **sbin_r, enum sieve_error *error_code_r); bool sieve_binary_up_to_date(struct sieve_binary *sbin, enum sieve_compile_flags cpflags); int sieve_binary_check_executable(struct sieve_binary *sbin, enum sieve_error *error_code_r, const char **client_error_r); /* * Block management */ enum sieve_binary_system_block { SBIN_SYSBLOCK_SCRIPT_DATA, SBIN_SYSBLOCK_EXTENSIONS, SBIN_SYSBLOCK_MAIN_PROGRAM, SBIN_SYSBLOCK_LAST }; struct sieve_binary_block *sieve_binary_block_create(struct sieve_binary *sbin); unsigned int sieve_binary_block_count(struct sieve_binary *sbin); struct sieve_binary_block * sieve_binary_block_get(struct sieve_binary *sbin, unsigned int id); void sieve_binary_block_clear(struct sieve_binary_block *sblock); size_t sieve_binary_block_get_size(const struct sieve_binary_block *sblock); struct sieve_binary * sieve_binary_block_get_binary(const struct sieve_binary_block *sblock); unsigned int sieve_binary_block_get_id(const struct sieve_binary_block *sblock); /* * Extension support */ struct sieve_binary_extension { const struct sieve_extension_def *extension; bool (*binary_pre_save)(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_error *error_code_r); bool (*binary_post_save)(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_error *error_code_r); bool (*binary_open)(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); void (*binary_free)(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); bool (*binary_up_to_date)(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, enum sieve_compile_flags cpflags); }; void sieve_binary_extension_set_context(struct sieve_binary *sbin, const struct sieve_extension *ext, void *context); const void * sieve_binary_extension_get_context(struct sieve_binary *sbin, const struct sieve_extension *ext); void sieve_binary_extension_set(struct sieve_binary *sbin, const struct sieve_extension *ext, const struct sieve_binary_extension *bext, void *context); struct sieve_binary_block * sieve_binary_extension_create_block(struct sieve_binary *sbin, const struct sieve_extension *ext); struct sieve_binary_block * sieve_binary_extension_get_block(struct sieve_binary *sbin, const struct sieve_extension *ext); int sieve_binary_extension_link(struct sieve_binary *sbin, const struct sieve_extension *ext); const struct sieve_extension * sieve_binary_extension_get_by_index(struct sieve_binary *sbin, int index); int sieve_binary_extension_get_index(struct sieve_binary *sbin, const struct sieve_extension *ext); int sieve_binary_extensions_count(struct sieve_binary *sbin); /* * Code emission */ /* Low-level emission functions */ sieve_size_t sieve_binary_emit_data(struct sieve_binary_block *sblock, const void *data, sieve_size_t size); sieve_size_t sieve_binary_emit_byte(struct sieve_binary_block *sblock, uint8_t byte); void sieve_binary_update_data(struct sieve_binary_block *sblock, sieve_size_t address, const void *data, sieve_size_t size); /* Offset emission functions */ sieve_size_t sieve_binary_emit_offset(struct sieve_binary_block *sblock, sieve_offset_t offset); void sieve_binary_resolve_offset(struct sieve_binary_block *sblock, sieve_size_t address); /* Literal emission functions */ sieve_size_t sieve_binary_emit_integer(struct sieve_binary_block *sblock, sieve_number_t integer); sieve_size_t sieve_binary_emit_string(struct sieve_binary_block *sblock, const string_t *str); sieve_size_t sieve_binary_emit_cstring(struct sieve_binary_block *sblock, const char *str); static inline sieve_size_t sieve_binary_emit_unsigned(struct sieve_binary_block *sblock, unsigned int count) { return sieve_binary_emit_integer(sblock, count); } /* Extension emission functions */ sieve_size_t sieve_binary_emit_extension(struct sieve_binary_block *sblock, const struct sieve_extension *ext, unsigned int offset); void sieve_binary_emit_extension_object( struct sieve_binary_block *sblock, const struct sieve_extension_objects *objs, unsigned int code); /* * Code retrieval */ /* Literals */ bool sieve_binary_read_byte(struct sieve_binary_block *sblock, sieve_size_t *address, unsigned int *byte_r) ATTR_NULL(3); bool sieve_binary_read_code(struct sieve_binary_block *sblock, sieve_size_t *address, signed int *code_r) ATTR_NULL(3); bool sieve_binary_read_offset(struct sieve_binary_block *sblock, sieve_size_t *address, sieve_offset_t *offset_r) ATTR_NULL(3); bool sieve_binary_read_integer(struct sieve_binary_block *sblock, sieve_size_t *address, sieve_number_t *int_r) ATTR_NULL(3); bool sieve_binary_read_string(struct sieve_binary_block *sblock, sieve_size_t *address, string_t **str_r) ATTR_NULL(3); static inline bool ATTR_NULL(3) sieve_binary_read_unsigned(struct sieve_binary_block *sblock, sieve_size_t *address, unsigned int *count_r) { sieve_number_t integer = 0; if (!sieve_binary_read_integer(sblock, address, &integer)) return FALSE; if (count_r != NULL) *count_r = integer; return TRUE; } /* Extensions */ bool sieve_binary_read_extension(struct sieve_binary_block *sblock, sieve_size_t *address, unsigned int *offset_r, const struct sieve_extension **ext_r); const void * sieve_binary_read_extension_object(struct sieve_binary_block *sblock, sieve_size_t *address, const struct sieve_extension_objects *objs); /* * Debug info */ /* Writer */ struct sieve_binary_debug_writer; struct sieve_binary_debug_writer * sieve_binary_debug_writer_init(struct sieve_binary_block *sblock); void sieve_binary_debug_writer_deinit( struct sieve_binary_debug_writer **dwriter); void sieve_binary_debug_emit(struct sieve_binary_debug_writer *dwriter, sieve_size_t code_address, unsigned int code_line, unsigned int code_column); /* Reader */ struct sieve_binary_debug_reader * sieve_binary_debug_reader_init(struct sieve_binary_block *sblock); void sieve_binary_debug_reader_deinit( struct sieve_binary_debug_reader **dreader); void sieve_binary_debug_reader_reset(struct sieve_binary_debug_reader *dreader); unsigned int sieve_binary_debug_read_line(struct sieve_binary_debug_reader *dreader, sieve_size_t code_address); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve.c0000644000175100001700000010325715100335616022734 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "istream.h" #include "ostream.h" #include "buffer.h" #include "time-util.h" #include "eacces-error.h" #include "home-expand.h" #include "hostpid.h" #include "settings.h" #include "message-address.h" #include "mail-user.h" #include "sieve-extensions.h" #include "sieve-plugins.h" #include "sieve-address.h" #include "sieve-script.h" #include "sieve-storage-private.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-actions.h" #include "sieve-result.h" #include "sieve-parser.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-binary-dumper.h" #include "sieve.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-error-private.h" #include #include #include #include #include #include struct event_category event_category_sieve = { .name = "sieve", }; /* * Main Sieve library interface */ int sieve_init(const struct sieve_environment *env, const struct sieve_callbacks *callbacks, void *context, bool debug, struct sieve_instance **svinst_r) { struct event *event; struct sieve_instance *svinst; const char *error; struct sieve_settings *set; const char *lfilter, *domain; pool_t pool; *svinst_r = NULL; settings_info_register(&sieve_setting_parser_info); lfilter = NULL; switch (env->location) { case SIEVE_ENV_LOCATION_MDA: lfilter = "sieve_env_location_mda"; break; case SIEVE_ENV_LOCATION_MTA: lfilter = "sieve_env_location_mta"; break; case SIEVE_ENV_LOCATION_MS: lfilter = "sieve_env_location_ms"; break; default: break; } event = event_create(env->event_parent); event_add_category(event, &event_category_sieve); event_set_forced_debug(event, debug); event_set_append_log_prefix(event, "sieve: "); event_add_str(event, "user", env->username); if (lfilter != NULL) { event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, (void*)lfilter); } if (settings_get(event, &sieve_setting_parser_info, 0, &set, &error) < 0) { e_error(event, "%s", error); event_unref(&event); return -1; } /* Create Sieve engine instance */ pool = pool_alloconly_create("sieve", 8192); svinst = p_new(pool, struct sieve_instance, 1); svinst->pool = pool; svinst->callbacks = callbacks; svinst->context = context; svinst->debug = debug; svinst->base_dir = p_strdup_empty(pool, env->base_dir); svinst->username = p_strdup_empty(pool, env->username); svinst->home_dir = p_strdup_empty(pool, env->home_dir); svinst->temp_dir = p_strdup_empty(pool, env->temp_dir); svinst->flags = env->flags; svinst->env_location = env->location; svinst->delivery_phase = env->delivery_phase; svinst->event = event; svinst->set = set; /* Determine domain */ if (env->domainname != NULL && *(env->domainname) != '\0') domain = env->domainname; else { /* Fall back to parsing username localpart@domain */ domain = svinst->username == NULL ? NULL : strchr(svinst->username, '@'); if (domain == NULL || *(domain+1) == '\0') { /* Fall back to parsing hostname host.domain */ domain = (env->hostname != NULL ? strchr(env->hostname, '.') : NULL); if (domain == NULL || *(domain+1) == '\0' || strchr(domain+1, '.') == NULL) { /* Fall back to bare hostname */ domain = env->hostname; } else { domain++; } } else { domain++; } } svinst->hostname = p_strdup_empty(pool, env->hostname); svinst->domainname = p_strdup(pool, domain); sieve_errors_init(svinst); e_debug(event, "%s version %s initializing", PIGEONHOLE_NAME, PIGEONHOLE_VERSION_FULL); /* Initialize extensions */ if (sieve_extensions_init(svinst) < 0) { sieve_deinit(&svinst); return -1; } /* Initialize storage classes */ sieve_storages_init(svinst); /* Load plugins */ if (sieve_plugins_load(svinst, NULL, NULL) < 0) { sieve_deinit(&svinst); return -1; } /* Load extensions */ if (sieve_extensions_load(svinst) < 0) { sieve_deinit(&svinst); return -1; } *svinst_r = svinst; return 0; } void sieve_deinit(struct sieve_instance **_svinst) { struct sieve_instance *svinst = *_svinst; if (svinst == NULL) return; *_svinst = NULL; sieve_plugins_unload(svinst); sieve_storages_deinit(svinst); sieve_extensions_deinit(svinst); sieve_errors_deinit(svinst); settings_free(svinst->set); event_unref(&svinst->event); pool_unref(&(svinst)->pool); } int sieve_settings_reload(struct sieve_instance *svinst) { struct sieve_settings *set; const char *error; if (settings_get(svinst->event, &sieve_setting_parser_info, 0, &set, &error) < 0) { e_error(svinst->event, "%s", error); return -1; } settings_free(svinst->set); svinst->set = set; return 0; } void sieve_set_extensions(struct sieve_instance *svinst, const char *extensions) { (void)sieve_extensions_set_string(svinst, extensions, FALSE, FALSE); } const char * sieve_get_capabilities(struct sieve_instance *svinst, const char *name) { if (name == NULL || *name == '\0') return sieve_extensions_get_string(svinst); return sieve_extension_capabilities_get_string(svinst, name); } struct event *sieve_get_event(struct sieve_instance *svinst) { return svinst->event; } /* * Low-level compiler functions */ struct sieve_ast * sieve_parse(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r) { struct sieve_parser *parser; struct sieve_ast *ast = NULL; sieve_error_args_init(&error_code_r, NULL); /* Parse */ parser = sieve_parser_create(script, ehandler, error_code_r); if (parser == NULL) return NULL; if (!sieve_parser_run(parser, &ast)) ast = NULL; else sieve_ast_ref(ast); sieve_parser_free(&parser); if (ast == NULL) *error_code_r = SIEVE_ERROR_NOT_VALID; return ast; } bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, enum sieve_error *error_code_r) { bool result = TRUE; struct sieve_validator *validator; sieve_error_args_init(&error_code_r, NULL); validator = sieve_validator_create(ast, ehandler, flags); if (!sieve_validator_run(validator)) result = FALSE; sieve_validator_free(&validator); if (!result) *error_code_r = SIEVE_ERROR_NOT_VALID; return result; } static struct sieve_binary * sieve_generate(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, enum sieve_error *error_code_r) { struct sieve_generator *generator; struct sieve_binary *sbin = NULL; sieve_error_args_init(&error_code_r, NULL); generator = sieve_generator_create(ast, ehandler, flags); sbin = sieve_generator_run(generator, NULL); sieve_generator_free(&generator); if (sbin == NULL) *error_code_r = SIEVE_ERROR_NOT_VALID; return sbin; } /* * Sieve compilation */ int sieve_compile_script(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { struct sieve_ast *ast; struct sieve_binary *sbin; bool no_error_result = (error_code_r == NULL); *sbin_r = NULL; sieve_error_args_init(&error_code_r, NULL); /* Parse */ ast = sieve_parse(script, ehandler, error_code_r); if (ast == NULL) { switch (*error_code_r) { case SIEVE_ERROR_NOT_FOUND: if (no_error_result) { sieve_error(ehandler, sieve_script_name(script), "script not found"); } break; default: sieve_error(ehandler, sieve_script_name(script), "parse failed"); } return -1; } /* Validate */ if (!sieve_validate(ast, ehandler, flags, error_code_r)) { sieve_error(ehandler, sieve_script_name(script), "validation failed"); sieve_ast_unref(&ast); return -1; } /* Generate */ sbin = sieve_generate(ast, ehandler, flags, error_code_r); if (sbin == NULL) { sieve_error(ehandler, sieve_script_name(script), "code generation failed"); sieve_ast_unref(&ast); return -1; } /* Cleanup */ sieve_ast_unref(&ast); *sbin_r = sbin; return 0; } int sieve_compile(struct sieve_instance *svinst, const char *script_cause, const char *storage_name, const char *script_name, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { struct sieve_script *script; bool no_error_result = (error_code_r == NULL); *sbin_r = NULL; sieve_error_args_init(&error_code_r, NULL); if (sieve_script_create_open_in(svinst, script_cause, storage_name, script_name, &script, error_code_r, NULL) < 0) { switch (*error_code_r) { case SIEVE_ERROR_NOT_FOUND: if (no_error_result) { sieve_error(ehandler, script_name, "script not found"); } break; default: sieve_internal_error(ehandler, script_name, "failed to open script"); } return -1; } if (sieve_compile_script(script, ehandler, flags, sbin_r, error_code_r) < 0) { sieve_script_unref(&script); return -1; } e_debug(svinst->event, "Script '%s' successfully compiled", sieve_script_label(script)); sieve_script_unref(&script); return 0; } /* * Sieve runtime */ static int sieve_run(struct sieve_binary *sbin, struct sieve_result *result, struct sieve_execute_env *eenv, struct sieve_error_handler *ehandler) { struct sieve_interpreter *interp; int ret = 0; /* Create the interpreter */ interp = sieve_interpreter_create(sbin, NULL, eenv, ehandler); if (interp == NULL) return SIEVE_EXEC_BIN_CORRUPT; /* Run the interpreter */ ret = sieve_interpreter_run(interp, result); /* Free the interpreter */ sieve_interpreter_free(&interp); return ret; } /* * Reading/writing sieve binaries */ int sieve_load(struct sieve_instance *svinst, const char *bin_path, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { return sieve_binary_open(svinst, bin_path, NULL, sbin_r, error_code_r); } static int sieve_open_script_real(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { struct sieve_instance *svinst = sieve_script_svinst(script); struct sieve_resource_usage rusage; struct sieve_binary *sbin; const char *error = NULL; int ret; sieve_resource_usage_init(&rusage); /* Try to open the matching binary */ if (sieve_script_binary_load(script, &sbin, error_code_r) == 0) { sieve_binary_get_resource_usage(sbin, &rusage); /* Ok, it exists; now let's see if it is up to date */ if (!sieve_resource_usage_is_excessive(svinst, &rusage) && !sieve_binary_up_to_date(sbin, flags)) { /* Not up to date */ e_debug(svinst->event, "Script binary %s is not up-to-date", sieve_binary_path(sbin)); sieve_binary_close(&sbin); } } /* If the binary does not exist or is not up-to-date, we need * to (re-)compile. */ if (sbin != NULL) { e_debug(svinst->event, "Script binary %s successfully loaded", sieve_binary_path(sbin)); } else { if (sieve_compile_script(script, ehandler, flags, &sbin, error_code_r) < 0) return -1; e_debug(svinst->event, "Script '%s' successfully compiled", sieve_script_label(script)); sieve_binary_set_resource_usage(sbin, &rusage); } /* Check whether binary can be executed. */ ret = sieve_binary_check_executable(sbin, error_code_r, &error); if (ret <= 0) { const char *path = sieve_binary_path(sbin); i_assert(error != NULL); if (path != NULL) { e_debug(svinst->event, "Script binary %s cannot be executed", path); } else { e_debug(svinst->event, "Script binary from %s cannot be executed", sieve_binary_source(sbin)); } if (ret < 0) { sieve_internal_error(ehandler, sieve_script_name(script), "failed to open script"); } else { sieve_error(ehandler, sieve_script_name(script), "%s", error); } sieve_binary_close(&sbin); return -1; } *sbin_r = sbin; return 0; } int sieve_open_script(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { int ret; *sbin_r = NULL; sieve_error_args_init(&error_code_r, NULL); T_BEGIN { ret = sieve_open_script_real(script, ehandler, flags, sbin_r, error_code_r); } T_END; return ret; } int sieve_open(struct sieve_instance *svinst, const char *script_cause, const char *storage_name, const char *script_name, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { struct sieve_script *script; bool no_error_result = (error_code_r == NULL); int ret; *sbin_r = NULL; sieve_error_args_init(&error_code_r, NULL); /* First open the scriptfile itself */ if (sieve_script_create_open_in(svinst, script_cause, storage_name, script_name, &script, error_code_r, NULL) < 0) { /* Failed */ switch (*error_code_r) { case SIEVE_ERROR_NOT_FOUND: if (no_error_result) { sieve_error(ehandler, script_name, "script not found"); } break; default: sieve_internal_error(ehandler, script_name, "failed to open script"); } return -1; } /* Drop script reference, if sbin != NULL it holds a reference of its own. Otherwise the script object is freed here. */ ret = sieve_open_script(script, ehandler, flags, sbin_r, error_code_r); sieve_script_unref(&script); return ret; } const char *sieve_get_source(struct sieve_binary *sbin) { return sieve_binary_source(sbin); } bool sieve_is_loaded(struct sieve_binary *sbin) { return sieve_binary_loaded(sbin); } int sieve_save_as(struct sieve_binary *sbin, const char *bin_path, bool update, mode_t save_mode, enum sieve_error *error_code_r) { if (bin_path == NULL) return sieve_save(sbin, update, error_code_r); return sieve_binary_save(sbin, bin_path, update, save_mode, error_code_r); } int sieve_save(struct sieve_binary *sbin, bool update, enum sieve_error *error_code_r) { struct sieve_script *script = sieve_binary_script(sbin); if (script == NULL) { return sieve_binary_save(sbin, NULL, update, 0600, error_code_r); } return sieve_script_binary_save(script, sbin, update, error_code_r); } bool sieve_record_resource_usage(struct sieve_binary *sbin, const struct sieve_resource_usage *rusage) { return sieve_binary_record_resource_usage(sbin, rusage); } int sieve_check_executable(struct sieve_binary *sbin, enum sieve_error *error_code_r, const char **client_error_r) { return sieve_binary_check_executable(sbin, error_code_r, client_error_r); } void sieve_close(struct sieve_binary **_sbin) { sieve_binary_close(_sbin); } /* * Debugging */ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream, bool verbose) { struct sieve_binary_dumper *dumpr = sieve_binary_dumper_create(sbin); sieve_binary_dumper_run(dumpr, stream, verbose); sieve_binary_dumper_free(&dumpr); } void sieve_hexdump(struct sieve_binary *sbin, struct ostream *stream) { struct sieve_binary_dumper *dumpr = sieve_binary_dumper_create(sbin); sieve_binary_dumper_hexdump(dumpr, stream); sieve_binary_dumper_free(&dumpr); } int sieve_test(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct sieve_error_handler *ehandler, struct ostream *stream, enum sieve_execute_flags flags) { struct sieve_instance *svinst = sieve_binary_svinst(sbin); struct sieve_result *result; struct sieve_execute_env eenv; pool_t pool; int ret; pool = pool_alloconly_create("sieve execution", 4096); sieve_execute_init(&eenv, svinst, pool, msgdata, senv, flags); /* Create result object */ result = sieve_result_create(svinst, pool, &eenv); /* Run the script */ ret = sieve_run(sbin, result, &eenv, ehandler); /* Print result if successful */ if (ret > 0) { ret = (sieve_result_print(result, senv, stream, NULL) ? SIEVE_EXEC_OK : SIEVE_EXEC_FAILURE); } /* Cleanup */ sieve_result_unref(&result); sieve_execute_deinit(&eenv); pool_unref(&pool); return ret; } /* * Script execution */ int sieve_script_env_init(struct sieve_script_env *senv, struct mail_user *user, const char **error_r) { const struct message_address *postmaster; const char *error; if (!mail_user_get_postmaster_address(user, &postmaster, &error)) { *error_r = t_strdup_printf( "Invalid postmaster_address: %s", error); return -1; } i_zero(senv); senv->user = user; senv->postmaster_address = postmaster; return 0; } int sieve_execute(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct sieve_error_handler *exec_ehandler, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags) { struct sieve_instance *svinst = sieve_binary_svinst(sbin); struct sieve_result *result = NULL; struct sieve_result_execution *rexec; struct sieve_execute_env eenv; pool_t pool; int ret; pool = pool_alloconly_create("sieve execution", 4096); sieve_execute_init(&eenv, svinst, pool, msgdata, senv, flags); /* Create result object */ result = sieve_result_create(svinst, pool, &eenv); /* Run the script */ ret = sieve_run(sbin, result, &eenv, exec_ehandler); rexec = sieve_result_execution_create(result, pool); /* Evaluate status and execute the result: Strange situations, e.g. currupt binaries, must be handled by the caller. In that case no implicit keep is attempted, because the situation may be resolved. */ ret = sieve_result_execute(rexec, ret, TRUE, action_ehandler, NULL); sieve_result_execution_destroy(&rexec); /* Cleanup */ sieve_result_unref(&result); sieve_execute_finish(&eenv, ret); sieve_execute_deinit(&eenv); pool_unref(&pool); return ret; } /* * Multiscript support */ struct sieve_multiscript { pool_t pool; struct sieve_execute_env exec_env; struct sieve_result *result; struct sieve_result_execution *rexec; struct event *event; int status; bool keep; struct ostream *teststream; bool active:1; bool discard_handled:1; }; struct sieve_multiscript * sieve_multiscript_start_execute(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv) { pool_t pool; struct sieve_result *result; struct sieve_multiscript *mscript; pool = pool_alloconly_create("sieve execution", 4096); mscript = p_new(pool, struct sieve_multiscript, 1); mscript->pool = pool; sieve_execute_init(&mscript->exec_env, svinst, pool, msgdata, senv, 0); mscript->event = event_create(mscript->exec_env.event); event_set_append_log_prefix(mscript->event, "multi-script: "); result = sieve_result_create(svinst, pool, &mscript->exec_env); sieve_result_set_keep_action(result, NULL, NULL); mscript->result = result; mscript->rexec = sieve_result_execution_create(result, pool); mscript->status = SIEVE_EXEC_OK; mscript->active = TRUE; mscript->keep = TRUE; e_debug(mscript->event, "Start execute sequence"); return mscript; } static void sieve_multiscript_destroy(struct sieve_multiscript **_mscript) { struct sieve_multiscript *mscript = *_mscript; if (mscript == NULL) return; *_mscript = NULL; e_debug(mscript->event, "Destroy"); event_unref(&mscript->event); sieve_result_execution_destroy(&mscript->rexec); sieve_result_unref(&mscript->result); sieve_execute_deinit(&mscript->exec_env); pool_unref(&mscript->pool); } struct sieve_multiscript * sieve_multiscript_start_test(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct ostream *stream) { struct sieve_multiscript *mscript = sieve_multiscript_start_execute(svinst, msgdata, senv); mscript->teststream = stream; return mscript; } static void sieve_multiscript_test(struct sieve_multiscript *mscript) { const struct sieve_script_env *senv = mscript->exec_env.scriptenv; e_debug(mscript->event, "Test result"); if (mscript->status > 0) { mscript->status = (sieve_result_print(mscript->result, senv, mscript->teststream, &mscript->keep) ? SIEVE_EXEC_OK : SIEVE_EXEC_FAILURE); } else { mscript->keep = TRUE; } sieve_result_mark_executed(mscript->result); } static void sieve_multiscript_execute(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler, enum sieve_execute_flags flags) { e_debug(mscript->event, "Execute result"); mscript->exec_env.flags = flags; if (mscript->status > 0) { mscript->status = sieve_result_execute(mscript->rexec, SIEVE_EXEC_OK, FALSE, ehandler, &mscript->keep); } } bool sieve_multiscript_run(struct sieve_multiscript *mscript, struct sieve_binary *sbin, struct sieve_error_handler *exec_ehandler, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags) { if (!mscript->active) { e_debug(mscript->event, "Sequence ended"); return FALSE; } e_debug(mscript->event, "Run script '%s'", sieve_binary_source(sbin)); /* Run the script */ mscript->exec_env.flags = flags; mscript->status = sieve_run(sbin, mscript->result, &mscript->exec_env, exec_ehandler); if (mscript->status >= 0) { mscript->keep = FALSE; if (mscript->teststream != NULL) sieve_multiscript_test(mscript); else { sieve_multiscript_execute(mscript, action_ehandler, flags); } if (!mscript->keep) mscript->active = FALSE; } if (!mscript->active || mscript->status <= 0) { e_debug(mscript->event, "Sequence ended"); mscript->active = FALSE; return FALSE; } e_debug(mscript->event, "Sequence active"); return TRUE; } bool sieve_multiscript_will_discard(struct sieve_multiscript *mscript) { return (!mscript->active && mscript->status == SIEVE_EXEC_OK && !sieve_result_executed_delivery(mscript->rexec)); } void sieve_multiscript_run_discard(struct sieve_multiscript *mscript, struct sieve_binary *sbin, struct sieve_error_handler *exec_ehandler, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags) { if (!sieve_multiscript_will_discard(mscript)) { e_debug(mscript->event, "Not running discard script"); return; } i_assert(!mscript->discard_handled); e_debug(mscript->event, "Run discard script '%s'", sieve_binary_source(sbin)); sieve_result_set_keep_action(mscript->result, NULL, &act_store); /* Run the discard script */ flags |= SIEVE_EXECUTE_FLAG_DEFER_KEEP; mscript->exec_env.flags = flags; mscript->status = sieve_run(sbin, mscript->result, &mscript->exec_env, exec_ehandler); if (mscript->status >= 0) { mscript->keep = FALSE; if (mscript->teststream != NULL) sieve_multiscript_test(mscript); else { sieve_multiscript_execute(mscript, action_ehandler, flags); } if (mscript->status == SIEVE_EXEC_FAILURE) mscript->status = SIEVE_EXEC_KEEP_FAILED; mscript->active = FALSE; } mscript->discard_handled = TRUE; } int sieve_multiscript_status(struct sieve_multiscript *mscript) { return mscript->status; } int sieve_multiscript_finish(struct sieve_multiscript **_mscript, struct sieve_error_handler *action_ehandler, enum sieve_execute_flags flags, int status) { struct sieve_multiscript *mscript = *_mscript; if (mscript == NULL) return SIEVE_EXEC_OK; *_mscript = NULL; switch (status) { case SIEVE_EXEC_OK: status = mscript->status; break; case SIEVE_EXEC_TEMP_FAILURE: break; case SIEVE_EXEC_BIN_CORRUPT: case SIEVE_EXEC_FAILURE: case SIEVE_EXEC_KEEP_FAILED: case SIEVE_EXEC_RESOURCE_LIMIT: if (mscript->status == SIEVE_EXEC_TEMP_FAILURE) status = mscript->status; break; } e_debug(mscript->event, "Finishing sequence (status=%s)", sieve_execution_exitcode_to_str(status)); mscript->exec_env.flags = flags; sieve_result_set_keep_action(mscript->result, NULL, &act_store); mscript->keep = FALSE; if (mscript->teststream != NULL) mscript->keep = TRUE; else { status = sieve_result_execute( mscript->rexec, status, TRUE, action_ehandler, &mscript->keep); } e_debug(mscript->event, "Sequence finished (status=%s, keep=%s)", sieve_execution_exitcode_to_str(status), (mscript->keep ? "yes" : "no")); sieve_execute_finish(&mscript->exec_env, status); /* Cleanup */ sieve_multiscript_destroy(&mscript); return status; } /* * Configured Limits */ unsigned int sieve_max_redirects(struct sieve_instance *svinst) { return svinst->set->max_redirects; } unsigned int sieve_max_actions(struct sieve_instance *svinst) { return svinst->set->max_actions; } size_t sieve_max_script_size(struct sieve_instance *svinst) { return svinst->set->max_script_size; } /* * Errors */ #define CRITICAL_MSG \ "Internal error occurred. Refer to server log for more information." #define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]" void sieve_error_args_init(enum sieve_error **error_code_r, const char ***error_r) { /* Dummies */ static enum sieve_error dummy_error_code = SIEVE_ERROR_NONE; static const char *dummy_error = NULL; if (error_code_r != NULL) { if (*error_code_r == NULL) *error_code_r = &dummy_error_code; **error_code_r = SIEVE_ERROR_NONE; } if (error_r != NULL) { if (*error_r == NULL) *error_r = &dummy_error; **error_r = NULL; } } void sieve_error_create_internal(enum sieve_error *error_code_r, const char **error_r) { struct tm *tm; char buf[256]; /* Critical errors may contain sensitive data, so let user see only "Internal error" with a timestamp to make it easier to look from log files the actual error message. */ tm = localtime(&ioloop_time); if (strftime(buf, sizeof(buf), CRITICAL_MSG_STAMP, tm) > 0) *error_r = t_strdup(buf); else *error_r = CRITICAL_MSG; *error_code_r = SIEVE_ERROR_TEMP_FAILURE; } void sieve_error_create_script_not_found(const char *script_name, enum sieve_error *error_code_r, const char **error_r) { *error_code_r = SIEVE_ERROR_NOT_FOUND; if (script_name == NULL) *error_r = "Sieve script not found"; else *error_r = t_strdup_printf("Sieve script '%s' not found", script_name); } /* * User log */ const char * sieve_user_get_log_path(struct sieve_instance *svinst, struct sieve_script *user_script) { const char *log_path = (*svinst->set->user_log_path == '\0' ? NULL : svinst->set->user_log_path); /* Determine user log file path */ if (log_path == NULL) { const char *path; if (user_script == NULL || (path = sieve_file_script_get_path(user_script)) == NULL) { /* Default */ if (svinst->home_dir != NULL) { log_path = t_strconcat( svinst->home_dir, "/.dovecot.sieve.log", NULL); } } else { /* Use script file as a base (legacy behavior) */ log_path = t_strconcat(path, ".log", NULL); } } else if (svinst->home_dir != NULL) { /* Expand home dir if necessary */ if (log_path[0] == '~') { log_path = home_expand_tilde(log_path, svinst->home_dir); } else if (log_path[0] != '/') { log_path = t_strconcat(svinst->home_dir, "/", log_path, NULL); } } return log_path; } /* * Script trace log */ struct sieve_trace_log { struct sieve_instance *svinst; struct ostream *output; }; int sieve_trace_log_create(struct sieve_instance *svinst, const char *path, struct sieve_trace_log **trace_log_r) { struct sieve_trace_log *trace_log; struct ostream *output; int fd; *trace_log_r = NULL; if (path == NULL) output = o_stream_create_fd(1, 0); else { fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0600); if (fd == -1) { e_error(svinst->event, "trace: " "creat(%s) failed: %m", path); return -1; } output = o_stream_create_fd_autoclose(&fd, 0); o_stream_set_name(output, path); } trace_log = i_new(struct sieve_trace_log, 1); trace_log->svinst = svinst; trace_log->output = output; *trace_log_r = trace_log; return 0; } int sieve_trace_log_create_dir(struct sieve_instance *svinst, const char *dir, struct sieve_trace_log **trace_log_r) { static unsigned int counter = 0; const char *timestamp, *prefix; struct stat st; *trace_log_r = NULL; if (stat(dir, &st) < 0) { if (errno != ENOENT && errno != EACCES) { e_error(svinst->event, "trace: " "stat(%s) failed: %m", dir); } return -1; } timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time); counter++; prefix = t_strdup_printf("%s/%s.%s.%u.trace", dir, timestamp, my_pid, counter); return sieve_trace_log_create(svinst, prefix, trace_log_r); } int sieve_trace_log_open(struct sieve_instance *svinst, struct sieve_trace_log **trace_log_r) { const char *trace_dir = svinst->set->trace_dir; *trace_log_r = NULL; if (*trace_dir == '\0') return -1; if (svinst->home_dir != NULL) { /* Expand home dir if necessary */ if (trace_dir[0] == '~') { trace_dir = home_expand_tilde(trace_dir, svinst->home_dir); } else if (trace_dir[0] != '/') { trace_dir = t_strconcat(svinst->home_dir, "/", trace_dir, NULL); } } return sieve_trace_log_create_dir(svinst, trace_dir, trace_log_r); } void sieve_trace_log_write_line(struct sieve_trace_log *trace_log, const string_t *line) { struct const_iovec iov[2]; if (line == NULL) { o_stream_nsend_str(trace_log->output, "\n"); return; } memset(iov, 0, sizeof(iov)); iov[0].iov_base = str_data(line); iov[0].iov_len = str_len(line); iov[1].iov_base = "\n"; iov[1].iov_len = 1; o_stream_nsendv(trace_log->output, iov, 2); } void sieve_trace_log_printf(struct sieve_trace_log *trace_log, const char *fmt, ...) { va_list args; va_start(args, fmt); T_BEGIN { o_stream_nsend_str(trace_log->output, t_strdup_vprintf(fmt, args)); } T_END; va_end(args); } void sieve_trace_log_free(struct sieve_trace_log **_trace_log) { struct sieve_trace_log *trace_log = *_trace_log; *_trace_log = NULL; if (o_stream_finish(trace_log->output) < 0) { e_error(trace_log->svinst->event, "write(%s) failed: %s", o_stream_get_name(trace_log->output), o_stream_get_error(trace_log->output)); } o_stream_destroy(&trace_log->output); i_free(trace_log); } int sieve_trace_config_get(struct sieve_instance *svinst, struct sieve_trace_config *tr_config) { const char *tr_level = svinst->set->trace_level; i_zero(tr_config); if (*tr_level == '\0' || strcasecmp(tr_level, "none") == 0) return -1; if (strcasecmp(tr_level, "actions") == 0) tr_config->level = SIEVE_TRLVL_ACTIONS; else if (strcasecmp(tr_level, "commands") == 0) tr_config->level = SIEVE_TRLVL_COMMANDS; else if (strcasecmp(tr_level, "tests") == 0) tr_config->level = SIEVE_TRLVL_TESTS; else if (strcasecmp(tr_level, "matching") == 0) tr_config->level = SIEVE_TRLVL_MATCHING; else { e_error(svinst->event, "Unknown trace level: %s", tr_level); return -1; } if (svinst->set->trace_debug) tr_config->flags |= SIEVE_TRFLG_DEBUG; if (svinst->set->trace_addresses) tr_config->flags |= SIEVE_TRFLG_ADDRESSES; return 0; } /* * Execution exit codes */ const char *sieve_execution_exitcode_to_str(int code) { switch (code) { case SIEVE_EXEC_OK: return "ok"; case SIEVE_EXEC_FAILURE: return "failure"; case SIEVE_EXEC_TEMP_FAILURE: return "temporary_failure"; case SIEVE_EXEC_BIN_CORRUPT: return "binary_corrupt"; case SIEVE_EXEC_KEEP_FAILED: return "keep_failed"; case SIEVE_EXEC_RESOURCE_LIMIT: return "resource_limit"; } i_unreached(); } /* * User e-mail address */ const struct smtp_address *sieve_get_user_email(struct sieve_instance *svinst) { struct smtp_address *address; const char *username = svinst->username; if (svinst->user_email_implicit != NULL) return svinst->user_email_implicit; if (svinst->set->parsed.user_email != NULL) return svinst->set->parsed.user_email; if (smtp_address_parse_mailbox(svinst->pool, username, 0, &address, NULL) >= 0) { svinst->user_email_implicit = address; return svinst->user_email_implicit; } if (svinst->domainname != NULL) { svinst->user_email_implicit = smtp_address_create( svinst->pool, username, svinst->domainname); return svinst->user_email_implicit; } return NULL; } /* * Postmaster address */ const struct message_address * sieve_get_postmaster(const struct sieve_script_env *senv) { i_assert(senv->postmaster_address != NULL); return senv->postmaster_address; } const struct smtp_address * sieve_get_postmaster_smtp(const struct sieve_script_env *senv) { struct smtp_address *addr; int ret; ret = smtp_address_create_from_msg_temp( sieve_get_postmaster(senv), &addr); i_assert(ret >= 0); return addr; } const char *sieve_get_postmaster_address(const struct sieve_script_env *senv) { const struct message_address *postmaster = sieve_get_postmaster(senv); string_t *addr = t_str_new(256); message_address_write(addr, postmaster); return str_c(addr); } /* * Resource usage */ void sieve_resource_usage_init(struct sieve_resource_usage *rusage_r) { i_zero(rusage_r); } void sieve_resource_usage_add(struct sieve_resource_usage *dst, const struct sieve_resource_usage *src) { if ((UINT_MAX - dst->cpu_time_msecs) < src->cpu_time_msecs) dst->cpu_time_msecs = UINT_MAX; else dst->cpu_time_msecs += src->cpu_time_msecs; } bool sieve_resource_usage_is_high(struct sieve_instance *svinst ATTR_UNUSED, const struct sieve_resource_usage *rusage) { return (rusage->cpu_time_msecs > SIEVE_HIGH_CPU_TIME_MSECS); } bool sieve_resource_usage_is_excessive( struct sieve_instance *svinst, const struct sieve_resource_usage *rusage) { i_assert(svinst->set->max_cpu_time <= (UINT_MAX / 1000)); if (svinst->set->max_cpu_time == 0) return FALSE; return (rusage->cpu_time_msecs > (svinst->set->max_cpu_time * 1000)); } const char * sieve_resource_usage_get_summary(const struct sieve_resource_usage *rusage) { if (rusage->cpu_time_msecs == 0) return "no usage recorded"; return t_strdup_printf("cpu time = %u ms", rusage->cpu_time_msecs); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-lexer.h0000644000175100001700000000451415100335616024052 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_LEXER_H #define SIEVE_LEXER_H #include "lib.h" #include "str.h" #include "sieve-common.h" enum sieve_token_type { STT_NONE, STT_WHITESPACE, STT_EOF, STT_NUMBER, STT_IDENTIFIER, STT_TAG, STT_STRING, STT_RBRACKET, STT_LBRACKET, STT_RCURLY, STT_LCURLY, STT_RSQUARE, STT_LSQUARE, STT_SEMICOLON, STT_COMMA, /* These are currently not used in the lexical specification, but a token is assigned to these to generate proper error messages (these are technically not garbage and possibly part of mistyped but otherwise valid tokens). */ STT_SLASH, STT_COLON, /* Error tokens */ STT_GARBAGE, /* Error reporting deferred to parser */ STT_ERROR /* Lexer is responsible for error, parser won't report additional errors */ }; /* * Lexer object */ struct sieve_lexical_scanner; struct sieve_lexer { struct sieve_lexical_scanner *scanner; enum sieve_token_type token_type; string_t *token_str_value; sieve_number_t token_int_value; int token_line; }; const struct sieve_lexer * sieve_lexer_create(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r); void sieve_lexer_free(const struct sieve_lexer **lexer); /* * Scanning */ void sieve_lexer_skip_token(const struct sieve_lexer *lexer); /* * Token access */ static inline enum sieve_token_type sieve_lexer_token_type(const struct sieve_lexer *lexer) { return lexer->token_type; } static inline const string_t * sieve_lexer_token_str(const struct sieve_lexer *lexer) { i_assert(lexer->token_type == STT_STRING); return lexer->token_str_value; } static inline const char * sieve_lexer_token_ident(const struct sieve_lexer *lexer) { i_assert(lexer->token_type == STT_TAG || lexer->token_type == STT_IDENTIFIER); return str_c(lexer->token_str_value); } static inline sieve_number_t sieve_lexer_token_int(const struct sieve_lexer *lexer) { i_assert(lexer->token_type == STT_NUMBER); return lexer->token_int_value; } static inline bool sieve_lexer_eof(const struct sieve_lexer *lexer) { return lexer->token_type == STT_EOF; } static inline int sieve_lexer_token_line(const struct sieve_lexer *lexer) { return lexer->token_line; } const char *sieve_lexer_token_description(const struct sieve_lexer *lexer); void sieve_lexer_token_print(const struct sieve_lexer *lexer); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-runtime-trace.h0000644000175100001700000001112315100335616025504 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_RUNTIME_TRACE_H #define SIEVE_RUNTIME_TRACE_H #include "sieve-common.h" #include "sieve-runtime.h" /* * Runtime trace */ struct sieve_runtime_trace { struct sieve_trace_config config; struct sieve_trace_log *log; unsigned int indent; }; /* Trace configuration */ static inline bool sieve_runtime_trace_active (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level) { return ( renv->trace != NULL && trace_level <= renv->trace->config.level ); } static inline bool sieve_runtime_trace_hasflag (const struct sieve_runtime_env *renv, unsigned int flag) { return ( renv->trace != NULL && (renv->trace->config.flags & flag) != 0 ); } /* Trace indent */ static inline void sieve_runtime_trace_descend (const struct sieve_runtime_env *renv) { if ( renv->trace != NULL ) renv->trace->indent++; } static inline void sieve_runtime_trace_ascend (const struct sieve_runtime_env *renv) { if ( renv->trace != NULL ) renv->trace->indent--; } static inline void sieve_runtime_trace_toplevel (const struct sieve_runtime_env *renv) { if ( renv->trace != NULL ) renv->trace->indent = 0; } /* Trace errors */ void _sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, va_list args) ATTR_FORMAT(2, 0); void _sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, const char *fmt, va_list args) ATTR_FORMAT(3, 0); static inline void sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, ...) ATTR_FORMAT(2, 3); static inline void sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, const char *fmt, ...) ATTR_FORMAT(3, 4); static inline void ATTR_FORMAT(2, 3) sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, ...) { va_list args; va_start(args, fmt); if ( renv->trace != NULL ) _sieve_runtime_trace_error(renv, fmt, args); va_end(args); } static inline void ATTR_FORMAT(3, 4) sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, const char *fmt, ...) { va_list args; va_start(args, fmt); if ( renv->trace != NULL ) _sieve_runtime_trace_operand_error(renv, oprnd, fmt, args); va_end(args); } /* Trace info */ void _sieve_runtime_trace (const struct sieve_runtime_env *renv, const char *fmt, va_list args) ATTR_FORMAT(2, 0); static inline void sieve_runtime_trace (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level, const char *fmt, ...) ATTR_FORMAT(3, 4); static inline void ATTR_FORMAT(3, 4) sieve_runtime_trace (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level, const char *fmt, ...) { va_list args; va_start(args, fmt); if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) { _sieve_runtime_trace(renv, fmt, args); } va_end(args); } void _sieve_runtime_trace_address (const struct sieve_runtime_env *renv, sieve_size_t address, const char *fmt, va_list args) ATTR_FORMAT(3, 0); static inline void sieve_runtime_trace_address (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level, sieve_size_t address, const char *fmt, ...) ATTR_FORMAT(4, 5); static inline void ATTR_FORMAT(4, 5) sieve_runtime_trace_address (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level, sieve_size_t address, const char *fmt, ...) { va_list args; va_start(args, fmt); if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) { _sieve_runtime_trace_address(renv, address, fmt, args); } va_end(args); } static inline void ATTR_FORMAT(3, 4) sieve_runtime_trace_here (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level, const char *fmt, ...) { va_list args; va_start(args, fmt); if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) { _sieve_runtime_trace_address(renv, renv->pc, fmt, args); } va_end(args); } /* Trace boundaries */ void _sieve_runtime_trace_begin(const struct sieve_runtime_env *renv); void _sieve_runtime_trace_end(const struct sieve_runtime_env *renv); void _sieve_runtime_trace_sep(const struct sieve_runtime_env *renv); static inline void sieve_runtime_trace_begin (const struct sieve_runtime_env *renv) { if ( renv->trace != NULL ) _sieve_runtime_trace_begin(renv); } static inline void sieve_runtime_trace_end (const struct sieve_runtime_env *renv) { if ( renv->trace != NULL ) _sieve_runtime_trace_end(renv); } static inline void sieve_runtime_trace_sep (const struct sieve_runtime_env *renv) { if ( renv->trace != NULL ) _sieve_runtime_trace_sep(renv); } #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/tst-not.c0000644000175100001700000000274115100335616023225 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" /* * Not test * * Syntax: * not */ static bool tst_not_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true); static bool tst_not_validate_const (struct sieve_validator *valdtr, struct sieve_command *tst, int *const_current, int const_next); const struct sieve_command_def tst_not = { .identifier = "not", .type = SCT_TEST, .positional_args = 0, .subtests = 1, .block_allowed = FALSE, .block_required = FALSE, .validate_const = tst_not_validate_const, .control_generate = tst_not_generate }; /* * Code validation */ static bool tst_not_validate_const (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst ATTR_UNUSED, int *const_current, int const_next) { if ( const_next < 0 ) *const_current = -1; else if ( const_next > 0 ) *const_current = 0; else *const_current = 1; return TRUE; } /* * Code generation */ static bool tst_not_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true) { struct sieve_ast_node *test; /* Validator verified the existance of the single test already */ test = sieve_ast_test_first(ctx->ast_node); return sieve_generate_test(cgenv, test, jumps, !jump_true); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-generator.c0000644000175100001700000003212515100335616024713 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "mempool.h" #include "sieve-common.h" #include "sieve-script.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-binary.h" #include "sieve-generator.h" /* * Jump list */ struct sieve_jumplist * sieve_jumplist_create(pool_t pool, struct sieve_binary_block *sblock) { struct sieve_jumplist *jlist; jlist = p_new(pool, struct sieve_jumplist, 1); jlist->block = sblock; p_array_init(&jlist->jumps, pool, 4); return jlist; } void sieve_jumplist_init_temp(struct sieve_jumplist *jlist, struct sieve_binary_block *sblock) { jlist->block = sblock; t_array_init(&jlist->jumps, 4); } void sieve_jumplist_reset(struct sieve_jumplist *jlist) { array_clear(&jlist->jumps); } void sieve_jumplist_add(struct sieve_jumplist *jlist, sieve_size_t jump) { array_append(&jlist->jumps, &jump, 1); } void sieve_jumplist_resolve(struct sieve_jumplist *jlist) { unsigned int i; for (i = 0; i < array_count(&jlist->jumps); i++) { const sieve_size_t *jump = array_idx(&jlist->jumps, i); sieve_binary_resolve_offset(jlist->block, *jump); } } /* * Code Generator */ struct sieve_generator { pool_t pool; struct sieve_instance *instance; struct sieve_error_handler *ehandler; struct sieve_codegen_env genenv; struct sieve_binary_debug_writer *dwriter; ARRAY(void *) ext_contexts; }; struct sieve_generator * sieve_generator_create(struct sieve_ast *ast, struct sieve_error_handler *ehandler, enum sieve_compile_flags flags) { pool_t pool; struct sieve_generator *gentr; struct sieve_script *script; struct sieve_instance *svinst; pool = pool_alloconly_create("sieve_generator", 4096); gentr = p_new(pool, struct sieve_generator, 1); gentr->pool = pool; gentr->ehandler = ehandler; sieve_error_handler_ref(ehandler); gentr->genenv.gentr = gentr; gentr->genenv.flags = flags; gentr->genenv.ast = ast; sieve_ast_ref(ast); script = sieve_ast_script(ast); svinst = sieve_script_svinst(script); gentr->genenv.script = script; gentr->genenv.svinst = svinst; /* Setup storage for extension contexts */ p_array_init(&gentr->ext_contexts, pool, sieve_extensions_get_count(svinst)); return gentr; } void sieve_generator_free(struct sieve_generator **gentr) { sieve_ast_unref(&(*gentr)->genenv.ast); sieve_error_handler_unref(&(*gentr)->ehandler); sieve_binary_debug_writer_deinit(&(*gentr)->dwriter); sieve_binary_unref(&(*gentr)->genenv.sbin); pool_unref(&((*gentr)->pool)); *gentr = NULL; } /* * Accessors */ struct sieve_error_handler * sieve_generator_error_handler(struct sieve_generator *gentr) { return gentr->ehandler; } pool_t sieve_generator_pool(struct sieve_generator *gentr) { return gentr->pool; } struct sieve_script *sieve_generator_script(struct sieve_generator *gentr) { return gentr->genenv.script; } struct sieve_binary *sieve_generator_get_binary(struct sieve_generator *gentr) { return gentr->genenv.sbin; } struct sieve_binary_block * sieve_generator_get_block(struct sieve_generator *gentr) { return gentr->genenv.sblock; } /* * Extension support */ void sieve_generator_extension_set_context(struct sieve_generator *gentr, const struct sieve_extension *ext, void *context) { if (ext->id < 0) return; array_idx_set(&gentr->ext_contexts, (unsigned int) ext->id, &context); } const void * sieve_generator_extension_get_context(struct sieve_generator *gentr, const struct sieve_extension *ext) { void *const *ctx; if (ext->id < 0 || ext->id >= (int) array_count(&gentr->ext_contexts)) return NULL; ctx = array_idx(&gentr->ext_contexts, (unsigned int) ext->id); return *ctx; } /* * Code generation API */ static void sieve_generate_debug_from_ast_node(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *ast_node) { sieve_size_t address = sieve_binary_block_get_size(cgenv->sblock); unsigned int line = sieve_ast_node_line(ast_node); sieve_binary_debug_emit(cgenv->gentr->dwriter, address, line, 0); } static void sieve_generate_debug_from_ast_argument(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *ast_arg) { sieve_size_t address = sieve_binary_block_get_size(cgenv->sblock); unsigned int line = sieve_ast_argument_line(ast_arg); sieve_binary_debug_emit(cgenv->gentr->dwriter, address, line, 0); } bool sieve_generate_argument(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { const struct sieve_argument_def *arg_def; if (arg->argument == NULL || arg->argument->def == NULL) return FALSE; arg_def = arg->argument->def; if (arg_def->generate == NULL) return TRUE; sieve_generate_debug_from_ast_argument(cgenv, arg); return arg_def->generate(cgenv, arg, cmd); } bool sieve_generate_arguments(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_ast_argument **last_arg_r) { enum { ARG_START, ARG_OPTIONAL, ARG_POSITIONAL } state = ARG_START; struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node); /* Generate all arguments with assigned generator function */ while (arg != NULL) { const struct sieve_argument *argument; const struct sieve_argument_def *arg_def; if (arg->argument == NULL || arg->argument->def == NULL) return FALSE; argument = arg->argument; arg_def = argument->def; switch (state) { case ARG_START: if (argument->id_code == 0) state = ARG_POSITIONAL; else { /* Mark start of optional operands with 0 operand identifier */ sieve_binary_emit_byte(cgenv->sblock, SIEVE_OPERAND_OPTIONAL); /* Emit argument id for optional operand */ sieve_binary_emit_byte( cgenv->sblock, (unsigned char)argument->id_code); state = ARG_OPTIONAL; } break; case ARG_OPTIONAL: if (argument->id_code == 0) state = ARG_POSITIONAL; /* Emit argument id for optional operand (0 marks the end of the optionals) */ sieve_binary_emit_byte( cgenv->sblock, (unsigned char)argument->id_code); break; case ARG_POSITIONAL: if (argument->id_code != 0) return FALSE; break; } /* Call the generation function for the argument */ if (arg_def->generate != NULL) { sieve_generate_debug_from_ast_argument(cgenv, arg); if (!arg_def->generate(cgenv, arg, cmd)) return FALSE; } else if (state == ARG_POSITIONAL) { break; } arg = sieve_ast_argument_next(arg); } /* Mark end of optional list if it is still open */ if (state == ARG_OPTIONAL) sieve_binary_emit_byte(cgenv->sblock, 0); if (last_arg_r != NULL) *last_arg_r = arg; return TRUE; } bool sieve_generate_argument_parameters(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_ast_argument *arg) { struct sieve_ast_argument *param = arg->parameters; /* Generate all parameters with assigned generator function */ while (param != NULL) { if (param->argument != NULL && param->argument->def != NULL) { const struct sieve_argument_def *parameter = param->argument->def; /* Call the generation function for the parameter */ if (parameter->generate != NULL) { sieve_generate_debug_from_ast_argument( cgenv, param); if (!parameter->generate(cgenv, param, cmd)) return FALSE; } } param = sieve_ast_argument_next(param); } return TRUE; } bool sieve_generate_test(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *tst_node, struct sieve_jumplist *jlist, bool jump_true) { struct sieve_command *test; const struct sieve_command_def *tst_def; i_assert(tst_node->command != NULL && tst_node->command->def != NULL); test = tst_node->command; tst_def = test->def; if (tst_def->control_generate != NULL) { sieve_generate_debug_from_ast_node(cgenv, tst_node); if (tst_def->control_generate(cgenv, test, jlist, jump_true)) return TRUE; return FALSE; } if (tst_def->generate != NULL) { sieve_generate_debug_from_ast_node(cgenv, tst_node); if (tst_def->generate(cgenv, test)) { if (jump_true) { sieve_operation_emit(cgenv->sblock, NULL, &sieve_jmptrue_operation); } else { sieve_operation_emit(cgenv->sblock, NULL, &sieve_jmpfalse_operation); } sieve_jumplist_add( jlist, sieve_binary_emit_offset(cgenv->sblock, 0)); return TRUE; } return FALSE; } return TRUE; } static bool sieve_generate_command(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *cmd_node) { struct sieve_command *command; const struct sieve_command_def *cmd_def; i_assert(cmd_node->command != NULL && cmd_node->command->def != NULL); command = cmd_node->command; cmd_def = command->def; if (cmd_def->generate != NULL) { sieve_generate_debug_from_ast_node(cgenv, cmd_node); return cmd_def->generate(cgenv, command); } return TRUE; } bool sieve_generate_block(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *block) { bool result = TRUE; struct sieve_ast_node *cmd_node; T_BEGIN { cmd_node = sieve_ast_command_first(block); while (result && cmd_node != NULL) { result = sieve_generate_command(cgenv, cmd_node); cmd_node = sieve_ast_command_next(cmd_node); } } T_END; return result; } struct sieve_binary * sieve_generator_run(struct sieve_generator *gentr, struct sieve_binary_block **sblock_r) { bool topmost = (sblock_r == NULL || *sblock_r == NULL); struct sieve_binary *sbin; struct sieve_binary_block *sblock, *debug_block; const struct sieve_extension *const *extensions; unsigned int i, ext_count; bool result = TRUE; /* Initialize */ if (topmost) { sbin = sieve_binary_create_new( sieve_ast_script(gentr->genenv.ast)); sblock = sieve_binary_block_get( sbin, SBIN_SYSBLOCK_MAIN_PROGRAM); } else { sblock = *sblock_r; sbin = sieve_binary_block_get_binary(sblock); } i_assert(sbin != NULL); gentr->genenv.sbin = sbin; gentr->genenv.sblock = sblock; sieve_binary_ref(gentr->genenv.sbin); /* Create debug block */ debug_block = sieve_binary_block_create(sbin); gentr->dwriter = sieve_binary_debug_writer_init(debug_block); (void)sieve_binary_emit_unsigned( sblock, sieve_binary_block_get_id(debug_block)); /* Load extensions linked to the AST and emit a list in code */ extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count); (void) sieve_binary_emit_unsigned(sblock, ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_extension *ext = extensions[i]; bool deferred; /* Link to binary */ (void)sieve_binary_extension_link(sbin, ext); /* Emit */ sieve_binary_emit_extension(sblock, ext, 0); /* Emit deferred flag */ deferred = !sieve_ast_extension_is_required( gentr->genenv.ast, ext); sieve_binary_emit_byte(sblock, (deferred ? 1 : 0)); /* Load */ if (ext->def != NULL && ext->def->generator_load != NULL && !ext->def->generator_load(ext, &gentr->genenv)) result = FALSE; } /* Generate code */ if (result) { if (!sieve_generate_block(&gentr->genenv, sieve_ast_root(gentr->genenv.ast))) { result = FALSE; } else if (topmost) { sieve_binary_activate(sbin); } } /* Cleanup */ sieve_binary_unref(&gentr->genenv.sbin); gentr->genenv.sblock = NULL; if (!result) { if (topmost) { sieve_binary_unref(&sbin); if (sblock_r != NULL) *sblock_r = NULL; } sbin = NULL; } else { if (sblock_r != NULL) *sblock_r = sblock; } return sbin; } /* * Error handling */ #undef sieve_generator_error void sieve_generator_error(struct sieve_generator *gentr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; params.location = sieve_error_script_location(gentr->genenv.script, source_line); va_start(args, fmt); sieve_logv(gentr->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_generator_warning void sieve_generator_warning(struct sieve_generator *gentr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_WARNING, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; params.location = sieve_error_script_location(gentr->genenv.script, source_line); va_start(args, fmt); sieve_logv(gentr->ehandler, ¶ms, fmt, args); va_end(args); } #undef sieve_generator_critical void sieve_generator_critical(struct sieve_generator *gentr, const char *csrc_filename, unsigned int csrc_linenum, unsigned int source_line, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; params.location = sieve_error_script_location(gentr->genenv.script, source_line); va_start(args, fmt); sieve_criticalv(gentr->genenv.svinst, gentr->ehandler, ¶ms, "Code generation failed", fmt, args); va_end(args); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-interpreter.h0000644000175100001700000001572315100335616025302 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_INTERPRETER_H #define SIEVE_INTERPRETER_H #include "lib.h" #include "array.h" #include "buffer.h" #include "sieve-common.h" #include "sieve-runtime.h" /* * Interpreter */ struct sieve_interpreter * sieve_interpreter_create(struct sieve_binary *sbin, struct sieve_interpreter *parent, const struct sieve_execute_env *eenv, struct sieve_error_handler *ehandler) ATTR_NULL(2); struct sieve_interpreter * sieve_interpreter_create_for_block(struct sieve_binary_block *sblock, struct sieve_script *script, struct sieve_interpreter *parent, const struct sieve_execute_env *eenv, struct sieve_error_handler *ehandler) ATTR_NULL(3); void sieve_interpreter_free(struct sieve_interpreter **_interp); /* * Accessors */ pool_t sieve_interpreter_pool(struct sieve_interpreter *interp); struct sieve_interpreter * sieve_interpreter_get_parent(struct sieve_interpreter *interp); struct sieve_script *sieve_interpreter_script(struct sieve_interpreter *interp); struct sieve_error_handler * sieve_interpreter_get_error_handler(struct sieve_interpreter *interp); struct sieve_instance * sieve_interpreter_svinst(struct sieve_interpreter *interp); /* Do not use this function for normal sieve extensions. This is intended for * the testsuite only. */ void sieve_interpreter_set_result(struct sieve_interpreter *interp, struct sieve_result *result); /* * Loop handling */ struct sieve_interpreter_loop; int sieve_interpreter_loop_start(struct sieve_interpreter *interp, sieve_size_t loop_end, const struct sieve_extension_def *ext_def, struct sieve_interpreter_loop **loop_r); struct sieve_interpreter_loop * sieve_interpreter_loop_get(struct sieve_interpreter *interp, sieve_size_t loop_end, const struct sieve_extension_def *ext_def); int sieve_interpreter_loop_next(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop, sieve_size_t loop_begin); int sieve_interpreter_loop_break(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop); struct sieve_interpreter_loop * sieve_interpreter_loop_get_local(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop, const struct sieve_extension_def *ext_def) ATTR_NULL(2, 3); struct sieve_interpreter_loop * sieve_interpreter_loop_get_global(struct sieve_interpreter *interp, struct sieve_interpreter_loop *loop, const struct sieve_extension_def *ext_def) ATTR_NULL(2, 3); pool_t sieve_interpreter_loop_get_pool(struct sieve_interpreter_loop *loop) ATTR_PURE; void *sieve_interpreter_loop_get_context(struct sieve_interpreter_loop *loop) ATTR_PURE; void sieve_interpreter_loop_set_context(struct sieve_interpreter_loop *loop, void *context); /* * Program flow */ void sieve_interpreter_reset(struct sieve_interpreter *interp); void sieve_interpreter_interrupt(struct sieve_interpreter *interp); sieve_size_t sieve_interpreter_program_counter(struct sieve_interpreter *interp); int sieve_interpreter_program_jump_to(struct sieve_interpreter *interp, sieve_size_t jmp_target, bool break_loops); int sieve_interpreter_program_jump(struct sieve_interpreter *interp, bool jump, bool break_loops); /* * Test results */ void sieve_interpreter_set_test_result(struct sieve_interpreter *interp, bool result); bool sieve_interpreter_get_test_result(struct sieve_interpreter *interp); /* * Source location */ unsigned int sieve_runtime_get_source_location(const struct sieve_runtime_env *renv, sieve_size_t code_address); unsigned int sieve_runtime_get_command_location(const struct sieve_runtime_env *renv); const char * sieve_runtime_get_full_command_location(const struct sieve_runtime_env *renv); /* * Extension support */ struct sieve_interpreter_extension { const struct sieve_extension_def *ext_def; int (*run)(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, void *context, bool deferred); void (*free)(const struct sieve_extension *ext, struct sieve_interpreter *interp, void *context); }; void sieve_interpreter_extension_register( struct sieve_interpreter *interp, const struct sieve_extension *ext, const struct sieve_interpreter_extension *intext, void *context); void sieve_interpreter_extension_set_context( struct sieve_interpreter *interp, const struct sieve_extension *ext, void *context); void *sieve_interpreter_extension_get_context( struct sieve_interpreter *interp, const struct sieve_extension *ext); int sieve_interpreter_extension_start(struct sieve_interpreter *interp, const struct sieve_extension *ext); /* * Opcodes and operands */ int sieve_interpreter_handle_optional_operands( const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_side_effects_list **list); /* * Code execute */ int sieve_interpreter_continue(struct sieve_interpreter *interp, bool *interrupted); int sieve_interpreter_start(struct sieve_interpreter *interp, struct sieve_result *result, bool *interrupted); int sieve_interpreter_run(struct sieve_interpreter *interp, struct sieve_result *result); /* * Error handling */ void sieve_runtime_error(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_runtime_error(renv, ...) \ sieve_runtime_error(renv, __FILE__, __LINE__, __VA_ARGS__) void sieve_runtime_warning(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_runtime_warning(renv, ...) \ sieve_runtime_warning(renv, __FILE__, __LINE__, __VA_ARGS__) void sieve_runtime_log(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_runtime_log(renv, ...) \ sieve_runtime_log(renv, __FILE__, __LINE__, __VA_ARGS__) void sieve_runtime_debug(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_runtime_debug(renv, ...) \ sieve_runtime_debug(renv, __FILE__, __LINE__, __VA_ARGS__) void sieve_runtime_critical(const struct sieve_runtime_env *renv, const char *csrc_filename, unsigned int csrc_linenum, const char *location, const char *user_prefix, const char *fmt, ...) ATTR_FORMAT(6, 7); #define sieve_runtime_critical(renv, ...) \ sieve_runtime_critical(renv, __FILE__, __LINE__, __VA_ARGS__) int sieve_runtime_mail_error(const struct sieve_runtime_env *renv, struct mail *mail, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) ATTR_FORMAT(5, 6); #define sieve_runtime_mail_error(renv, mail, ...) \ sieve_runtime_mail_error(renv, mail, __FILE__, __LINE__, __VA_ARGS__) #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/cmd-stop.c0000644000175100001700000000324315100335616023341 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-generator.h" #include "sieve-interpreter.h" /* * Stop command * * Syntax * stop */ static bool cmd_stop_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx ATTR_UNUSED); static bool cmd_stop_validate (struct sieve_validator *valdtr, struct sieve_command *cmd); const struct sieve_command_def cmd_stop = { .identifier = "stop", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .validate = cmd_stop_validate, .generate = cmd_stop_generate }; /* * Stop operation */ static int opc_stop_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def cmd_stop_operation = { .mnemonic = "STOP", .code = SIEVE_OPERATION_STOP, .execute = opc_stop_execute }; /* * Command validation */ static bool cmd_stop_validate (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { sieve_command_exit_block_unconditionally(cmd); return TRUE; } /* * Code generation */ static bool cmd_stop_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd ATTR_UNUSED) { sieve_operation_emit(cgenv->sblock, NULL, &cmd_stop_operation); return TRUE; } /* * Code execution */ static int opc_stop_execute (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "stop command; end all script execution"); sieve_interpreter_interrupt(renv->interp); return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-commands.c0000644000175100001700000002402515100335616024526 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "rfc2822.h" #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-interpreter.h" /* * Literal arguments */ /* Forward declarations */ static bool arg_number_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); static bool arg_string_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); static bool arg_string_list_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *context); static bool arg_string_list_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *context); /* Argument objects */ const struct sieve_argument_def number_argument = { .identifier = "@number", .generate = arg_number_generate }; const struct sieve_argument_def string_argument = { .identifier = "@string", .generate = arg_string_generate }; const struct sieve_argument_def string_list_argument = { .identifier = "@string-list", .validate = arg_string_list_validate, .generate = arg_string_list_generate }; /* Argument implementations */ static bool arg_number_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { sieve_opr_number_emit(cgenv->sblock, sieve_ast_argument_number(arg)); return TRUE; } static bool arg_string_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED) { sieve_opr_string_emit(cgenv->sblock, sieve_ast_argument_str(arg)); return TRUE; } static bool arg_string_list_validate(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *stritem; stritem = sieve_ast_strlist_first(*arg); while (stritem != NULL) { if (!sieve_validator_argument_activate(valdtr, cmd, stritem, FALSE)) return FALSE; stritem = sieve_ast_strlist_next(stritem); } return TRUE; } static bool emit_string_list_operand(const struct sieve_codegen_env *cgenv, const struct sieve_ast_argument *strlist, struct sieve_command *cmd) { void *list_context; struct sieve_ast_argument *stritem; sieve_opr_stringlist_emit_start(cgenv->sblock, sieve_ast_strlist_count(strlist), &list_context); stritem = sieve_ast_strlist_first(strlist); while (stritem != NULL) { if (!sieve_generate_argument(cgenv, stritem, cmd)) return FALSE; stritem = sieve_ast_strlist_next(stritem); } sieve_opr_stringlist_emit_end(cgenv->sblock, list_context); return TRUE; } static bool arg_string_list_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { if (sieve_ast_argument_type(arg) == SAAT_STRING) { return sieve_generate_argument(cgenv, arg, cmd); } else if (sieve_ast_argument_type(arg) == SAAT_STRING_LIST) { bool result = TRUE; if (sieve_ast_strlist_count(arg) == 1) { return sieve_generate_argument( cgenv, sieve_ast_strlist_first(arg), cmd); } else T_BEGIN { result = emit_string_list_operand(cgenv, arg, cmd); } T_END; return result; } return FALSE; } /* * Abstract arguments * * (Generated by processing and not by parsing the grammar) */ /* Catenated string */ struct sieve_arg_catenated_string { struct sieve_ast_arg_list *str_parts; }; struct sieve_arg_catenated_string * sieve_arg_catenated_string_create(struct sieve_ast_argument *orig_arg) { pool_t pool = sieve_ast_pool(orig_arg->ast); struct sieve_ast_arg_list *arglist; struct sieve_arg_catenated_string *catstr; arglist = sieve_ast_arg_list_create(pool); catstr = p_new(pool, struct sieve_arg_catenated_string, 1); catstr->str_parts = arglist; (orig_arg)->argument->data = catstr; return catstr; } void sieve_arg_catenated_string_add_element( struct sieve_arg_catenated_string *catstr, struct sieve_ast_argument *element) { sieve_ast_arg_list_add(catstr->str_parts, element); } #define _cat_string_first(catstr) __AST_LIST_FIRST((catstr)->str_parts) #define _cat_string_count(catstr) __AST_LIST_COUNT((catstr)->str_parts) #define _cat_string_next(item) __AST_LIST_NEXT(item) bool sieve_arg_catenated_string_generate(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command *cmd) { struct sieve_arg_catenated_string *catstr = (struct sieve_arg_catenated_string *)arg->argument->data; struct sieve_ast_argument *strpart; if (_cat_string_count(catstr) == 1) sieve_generate_argument(cgenv, _cat_string_first(catstr), cmd); else { sieve_opr_catenated_string_emit(cgenv->sblock, _cat_string_count(catstr)); strpart = _cat_string_first(catstr); while (strpart != NULL) { if (!sieve_generate_argument(cgenv, strpart, cmd)) return FALSE; strpart = _cat_string_next(strpart); } } return TRUE; } /* * Argument creation */ struct sieve_argument * sieve_argument_create(struct sieve_ast *ast, const struct sieve_argument_def *def, const struct sieve_extension *ext, int id_code) { struct sieve_argument *arg; pool_t pool; pool = sieve_ast_pool(ast); arg = p_new(pool, struct sieve_argument, 1); arg->def = def; arg->ext = ext; arg->id_code = id_code; return arg; } /* * Core tests and commands */ const struct sieve_command_def *sieve_core_tests[] = { &tst_false, &tst_true, &tst_not, &tst_anyof, &tst_allof, &tst_address, &tst_header, &tst_exists, &tst_size }; const unsigned int sieve_core_tests_count = N_ELEMENTS(sieve_core_tests); const struct sieve_command_def *sieve_core_commands[] = { &cmd_require, &cmd_stop, &cmd_if, &cmd_elsif, &cmd_else, &cmd_keep, &cmd_discard, &cmd_redirect }; const unsigned int sieve_core_commands_count = N_ELEMENTS(sieve_core_commands); /* * Command context */ struct sieve_command *sieve_command_prev(struct sieve_command *cmd) { struct sieve_ast_node *node = sieve_ast_node_prev(cmd->ast_node); if (node != NULL) return node->command; return NULL; } struct sieve_command *sieve_command_parent(struct sieve_command *cmd) { struct sieve_ast_node *node = sieve_ast_node_parent(cmd->ast_node); return (node != NULL ? node->command : NULL); } struct sieve_command * sieve_command_create(struct sieve_ast_node *cmd_node, const struct sieve_extension *ext, const struct sieve_command_def *cmd_def, struct sieve_command_registration *cmd_reg) { struct sieve_command *cmd; cmd = p_new(sieve_ast_node_pool(cmd_node), struct sieve_command, 1); cmd->ast_node = cmd_node; cmd->def = cmd_def; cmd->ext = ext; cmd->reg = cmd_reg; cmd->block_exit_command = NULL; return cmd; } const char *sieve_command_def_type_name(const struct sieve_command_def *cmd_def) { switch (cmd_def->type) { case SCT_NONE: return "command of unspecified type (bug)"; case SCT_TEST: return "test"; case SCT_COMMAND: return "command"; case SCT_HYBRID: return "command or test"; default: break; } return "??COMMAND-TYPE??"; } const char *sieve_command_type_name(const struct sieve_command *cmd) { switch (cmd->def->type) { case SCT_NONE: return "command of unspecified type (bug)"; case SCT_TEST: return "test"; case SCT_COMMAND: return "command"; case SCT_HYBRID: if (cmd->ast_node->type == SAT_TEST) return "test"; return "command"; default: break; } return "??COMMAND-TYPE??"; } struct sieve_ast_argument * sieve_command_add_dynamic_tag(struct sieve_command *cmd, const struct sieve_extension *ext, const struct sieve_argument_def *tag, int id_code) { struct sieve_ast_argument *arg; if (cmd->first_positional != NULL) { arg = sieve_ast_argument_tag_insert(cmd->first_positional, tag->identifier, cmd->ast_node->source_line); } else { arg = sieve_ast_argument_tag_create(cmd->ast_node, tag->identifier, cmd->ast_node->source_line); } arg->argument = sieve_argument_create(cmd->ast_node->ast, tag, ext, id_code); return arg; } struct sieve_ast_argument * sieve_command_find_argument(struct sieve_command *cmd, const struct sieve_argument_def *arg_def) { struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node); /* Visit tagged and optional arguments */ while (arg != NULL) { if (arg->argument != NULL && arg->argument->def == arg_def) return arg; arg = sieve_ast_argument_next(arg); } return arg; } /* Use this function with caution. The command commits to exiting the block. When it for some reason does not, the interpretation will break later on, because exiting jumps are not generated when they would otherwise be necessary. */ void sieve_command_exit_block_unconditionally(struct sieve_command *cmd) { struct sieve_command *parent = sieve_command_parent(cmd); /* Only the first unconditional exit is of importance */ if (parent != NULL && parent->block_exit_command == NULL) parent->block_exit_command = cmd; } bool sieve_command_block_exits_unconditionally(struct sieve_command *cmd) { return ( cmd->block_exit_command != NULL ); } /* * Command utility functions */ /* NOTE: this may be moved */ static int _verify_header_name_item(void *context, struct sieve_ast_argument *header) { struct sieve_validator *valdtr = (struct sieve_validator *)context; string_t *name = sieve_ast_argument_str(header); if (sieve_argument_is_string_literal(header) && !rfc2822_header_field_name_verify(str_c(name), str_len(name))) { sieve_argument_validate_warning( valdtr, header, "specified header field name '%s' is invalid", str_sanitize(str_c(name), 80)); return 0; } return 1; } bool sieve_command_verify_headers_argument(struct sieve_validator *valdtr, struct sieve_ast_argument *headers) { return (sieve_ast_stringlist_map(&headers, valdtr, _verify_header_name_item) >= 0); } dovecot-pigeonhole-2.4.2/src/lib-sieve/cmp-i-octet.c0000644000175100001700000000367715100335616023747 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* Comparator 'i;octet': * */ #include "lib.h" #include "sieve-common.h" #include "sieve-comparators.h" #include #include /* * Forward declarations */ static int cmp_i_octet_compare(const struct sieve_comparator *cmp, const char *val1, size_t val1_size, const char *val2, size_t val2_size); static bool cmp_i_octet_char_match(const struct sieve_comparator *cmp, const char **val1, const char *val1_end, const char **val2, const char *val2_end); /* * Comparator object */ const struct sieve_comparator_def i_octet_comparator = { SIEVE_OBJECT("i;octet", &comparator_operand, SIEVE_COMPARATOR_I_OCTET), .flags = SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY | SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH, .compare = cmp_i_octet_compare, .char_match = cmp_i_octet_char_match, .char_skip = sieve_comparator_octet_skip }; /* * Comparator implementation */ static int cmp_i_octet_compare(const struct sieve_comparator *cmp ATTR_UNUSED, const char *val1, size_t val1_size, const char *val2, size_t val2_size) { int result; if (val1_size == val2_size) return memcmp(val1, val2, val1_size); if (val1_size > val2_size) { result = memcmp(val1, val2, val2_size); if (result == 0) return 1; return result; } result = memcmp(val1, val2, val1_size); if (result == 0) return -1; return result; } static bool cmp_i_octet_char_match(const struct sieve_comparator *cmp ATTR_UNUSED, const char **val, const char *val_end, const char **key, const char *key_end) { const char *val_begin = *val; const char *key_begin = *key; while (**val == **key && *val < val_end && *key < key_end) { (*val)++; (*key)++; } if (*key < key_end) { /* Reset */ *val = val_begin; *key = key_begin; return FALSE; } return TRUE; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-script.c0000644000175100001700000007764715100335616024253 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "compat.h" #include "unichar.h" #include "str.h" #include "str-sanitize.h" #include "hash.h" #include "array.h" #include "eacces-error.h" #include "mkdir-parents.h" #include "istream.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-error.h" #include "sieve-dump.h" #include "sieve-binary.h" #include "sieve-storage-private.h" #include "sieve-script-private.h" /* * Script name */ bool sieve_script_name_is_valid(const char *scriptname) { ARRAY_TYPE(unichars) uni_name; unsigned int count, i; const unichar_t *name_chars; size_t namelen = strlen(scriptname); /* Check minimum length */ if (namelen == 0) return FALSE; /* Check worst-case maximum length */ if (namelen > SIEVE_MAX_SCRIPT_NAME_LEN * 4) return FALSE; /* Intialize array for unicode characters */ t_array_init(&uni_name, namelen * 4); /* Convert UTF-8 to UCS4/UTF-32 */ if (uni_utf8_to_ucs4(scriptname, &uni_name) < 0) return FALSE; name_chars = array_get(&uni_name, &count); /* Check true maximum length */ if (count > SIEVE_MAX_SCRIPT_NAME_LEN) return FALSE; /* Scan name for invalid characters * FIXME: compliance with Net-Unicode Definition (Section 2 of * RFC 5198) is not checked fully and no normalization * is performed. */ for (i = 0; i < count; i++) { /* 0000-001F; [CONTROL CHARACTERS] */ if (name_chars[i] <= 0x001f) return FALSE; /* 002F; SLASH (not RFC-prohibited, but '/' is dangerous) */ if (name_chars[i] == 0x002f) return FALSE; /* 007F; DELETE */ if (name_chars[i] == 0x007f) return FALSE; /* 0080-009F; [CONTROL CHARACTERS] */ if (name_chars[i] >= 0x0080 && name_chars[i] <= 0x009f) return FALSE; /* 00FF */ if (name_chars[i] == 0x00ff) return FALSE; /* 2028; LINE SEPARATOR */ /* 2029; PARAGRAPH SEPARATOR */ if (name_chars[i] == 0x2028 || name_chars[i] == 0x2029) return FALSE; } return TRUE; } /* * Script instance */ static void sieve_script_update_event(struct sieve_script *script) { if (script->name == NULL) event_set_append_log_prefix(script->event, "script: "); else { event_add_str(script->event, "script_name", script->name); event_set_append_log_prefix( script->event, t_strdup_printf("script '%s': ", script->name)); } } void sieve_script_init(struct sieve_script *script, struct sieve_storage *storage, const struct sieve_script *script_class, const char *name) { i_assert(storage != NULL); script->script_class = script_class; script->refcount = 1; script->storage = storage; script->name = p_strdup_empty(script->pool, name); script->event = event_create(storage->event); sieve_script_update_event(script); sieve_storage_ref(storage); } static int sieve_script_create_common(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, bool open, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage_sequence *sseq; *script_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (sieve_storage_sequence_create(svinst, svinst->event, cause, type, &sseq, error_code_r, error_r) < 0) return -1; struct sieve_storage *storage; struct sieve_script *script; int ret; /* Find the first storage that has the script */ for (;;) { *error_code_r = SIEVE_ERROR_NONE; *error_r = NULL; ret = sieve_storage_sequence_next(sseq, &storage, error_code_r, error_r); if (ret == 0) break; if (ret < 0) { if (*error_code_r == SIEVE_ERROR_NOT_FOUND) continue; ret = -1; break; } if (sieve_storage_get_script(storage, name, &script, error_code_r) < 0) { if (*error_code_r == SIEVE_ERROR_NOT_FOUND) { sieve_storage_unref(&storage); continue; } *error_r = sieve_storage_get_last_error( storage, error_code_r); ret = -1; } else { ret = 1; } sieve_storage_unref(&storage); if (ret > 0 && open && sieve_script_open(script, error_code_r) < 0) { *error_r = sieve_script_get_last_error( script, error_code_r); sieve_script_unref(&script); if (*error_code_r == SIEVE_ERROR_NOT_FOUND) continue; ret = -1; } break; } if (ret > 0) { *script_r = script; ret = 0; } else if (ret == 0) { i_assert(*error_code_r == SIEVE_ERROR_NONE); sieve_error_create_script_not_found( name, error_code_r, error_r); ret = -1; } sieve_storage_sequence_free(&sseq); return ret; } int sieve_script_create(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r) { return sieve_script_create_common(svinst, cause, type, name, FALSE, script_r, error_code_r, error_r); } int sieve_script_create_in(struct sieve_instance *svinst, const char *cause, const char *storage_name, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage *storage; int ret; *script_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (sieve_storage_create(svinst, svinst->event, cause, storage_name, 0, &storage, error_code_r, error_r) < 0) return -1; ret = sieve_storage_get_script_direct(storage, name, script_r, NULL); if (ret < 0) *error_r = sieve_storage_get_last_error(storage, error_code_r); sieve_storage_unref(&storage); return ret; } void sieve_script_ref(struct sieve_script *script) { script->refcount++; } void sieve_script_unref(struct sieve_script **_script) { struct sieve_script *script = *_script; if (script == NULL) return; *_script = NULL; i_assert(script->refcount > 0); if (--script->refcount != 0) return; if (script->stream != NULL) { struct event_passthrough *e = event_create_passthrough(script->event)-> set_name("sieve_script_closed"); e_debug(e->event(), "Closed script"); } i_stream_unref(&script->stream); if (script->v.destroy != NULL) script->v.destroy(script); sieve_storage_unref(&script->storage); event_unref(&script->event); pool_unref(&script->pool); } int sieve_script_open(struct sieve_script *script, enum sieve_error *error_code_r) { struct sieve_storage *storage = script->storage; int ret; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (script->open) return 0; ret = script->v.open(script); i_assert(ret <= 0); if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = storage->error_code; return -1; } i_assert(script->name != NULL); script->open = TRUE; sieve_script_update_event(script); e_debug(script->event, "Opened from '%s'", storage->name); return 0; } int sieve_script_open_as(struct sieve_script *script, const char *name, enum sieve_error *error_code_r) { if (sieve_script_open(script, error_code_r) < 0) return -1; /* override name */ i_assert(name != NULL && *name != '\0'); script->name = p_strdup(script->pool, name); sieve_script_update_event(script); return 0; } int sieve_script_create_open(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r) { return sieve_script_create_common(svinst, cause, type, name, TRUE, script_r, error_code_r, error_r); } int sieve_script_create_open_in(struct sieve_instance *svinst, const char *cause, const char *storage_name, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_script *script; *script_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (sieve_script_create_in(svinst, cause, storage_name, name, &script, error_code_r, error_r) < 0) return -1; if (sieve_script_open(script, NULL) < 0) { *error_r = sieve_script_get_last_error(script, error_code_r); sieve_script_unref(&script); return -1; } *script_r = script; return 0; } int sieve_script_check(struct sieve_instance *svinst, const char *cause, const char *type, const char *name, enum sieve_error *error_code_r, const char **error_r) { struct sieve_script *script; enum sieve_error error_code; sieve_error_args_init(&error_code_r, &error_r); if (sieve_script_create_open(svinst, cause, type, name, &script, &error_code, error_r) < 0) return (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1); sieve_script_unref(&script); return 1; } /* * Properties */ const char *sieve_script_name(const struct sieve_script *script) { return script->name; } const char *sieve_script_label(const struct sieve_script *script) { if (*script->name == '\0') return script->storage->name; return t_strconcat(script->storage->name, "/", script->name, NULL); } const char *sieve_script_storage_type(const struct sieve_script *script) { return script->storage->type; } const char *sieve_script_cause(const struct sieve_script *script) { return script->storage->cause; } struct sieve_instance *sieve_script_svinst(const struct sieve_script *script) { return script->storage->svinst; } int sieve_script_get_size(struct sieve_script *script, uoff_t *size_r) { struct istream *stream; int ret; if (script->v.get_size != NULL) { if ((ret = script->v.get_size(script, size_r)) != 0) return ret; } /* Try getting size from the stream */ if (script->stream == NULL && sieve_script_get_stream(script, &stream, NULL) < 0) return -1; if (i_stream_get_size(script->stream, TRUE, size_r) < 0) { sieve_storage_set_critical(script->storage, "i_stream_get_size(%s) failed: %s", i_stream_get_name(script->stream), i_stream_get_error(script->stream)); return -1; } return 0; } bool sieve_script_is_open(const struct sieve_script *script) { return script->open; } bool sieve_script_is_default(const struct sieve_script *script) { return script->storage->is_default; } /* * Stream management */ int sieve_script_get_stream(struct sieve_script *script, struct istream **stream_r, enum sieve_error *error_code_r) { struct sieve_storage *storage = script->storage; int ret; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (script->stream != NULL) { *stream_r = script->stream; return 0; } // FIXME: necessary? i_assert(script->open); T_BEGIN { ret = script->v.get_stream(script, &script->stream); } T_END; if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = storage->error_code; struct event_passthrough *e = event_create_passthrough(script->event)-> add_str("error", storage->error)-> set_name("sieve_script_opened"); e_debug(e->event(), "Failed to open script for reading: %s", storage->error); return -1; } struct event_passthrough *e = event_create_passthrough(script->event)-> set_name("sieve_script_opened"); e_debug(e->event(), "Opened script for reading"); *stream_r = script->stream; return 0; } /* * Comparison */ int sieve_script_cmp(const struct sieve_script *script1, const struct sieve_script *script2) { int ret; if (script1 == script2) return 0; if (script1 == NULL || script2 == NULL) return (script1 == NULL ? -1 : 1); if (script1->script_class != script2->script_class) return (script1->script_class > script2->script_class ? 1 : -1); if (script1->v.cmp == NULL) { ret = sieve_storage_cmp(script1->storage, script2->storage); if (ret != 0) return (ret < 0 ? -1 : 1); return null_strcmp(script1->name, script2->name); } return script1->v.cmp(script1, script2); } unsigned int sieve_script_hash(const struct sieve_script *script) { if (script == NULL) return 0; unsigned int hash = 0; hash ^= POINTER_CAST_TO(script->script_class, unsigned int); hash ^= sieve_storage_hash(script->storage); hash ^= str_hash(script->name); return hash; } /* * Binary */ int sieve_script_binary_read_metadata(struct sieve_script *script, struct sieve_binary_block *sblock, sieve_size_t *offset) { struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); string_t *storage_class, *storage_name, *name; unsigned int version; if ((sieve_binary_block_get_size(sblock) - *offset) == 0) return 0; /* storage class */ if (!sieve_binary_read_string(sblock, offset, &storage_class)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid storage class", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } if (strcmp(str_c(storage_class), script->driver_name) != 0) { e_debug(script->event, "Binary '%s' reports unexpected driver name for script '%s' " "('%s' rather than '%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(storage_class), script->driver_name); return 0; } /* version */ if (!sieve_binary_read_unsigned(sblock, offset, &version)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid version", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } if (script->storage->version != version) { e_debug(script->event, "Binary '%s' was compiled with " "a different version of the '%s' script storage class " "(compiled v%d, expected v%d; " "automatically fixed when re-compiled)", sieve_binary_path(sbin), script->driver_name, version, script->storage->version); return 0; } /* storage */ if (!sieve_binary_read_string(sblock, offset, &storage_name)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid storage name", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } if (str_len(storage_name) > 0 && strcmp(str_c(storage_name), script->storage->name) != 0) { e_debug(script->event, "Binary '%s' reports different storage " "for script '%s' (binary points to '%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(storage_name)); return 0; } /* name */ if (!sieve_binary_read_string(sblock, offset, &name)) { e_error(script->event, "Binary '%s' has invalid metadata for script '%s': " "Invalid script name", sieve_binary_path(sbin), sieve_script_label(script)); return -1; } if (str_len(name) > 0 && strcmp(str_c(name), script->name) != 0) { e_debug(script->event, "Binary '%s' reports different script name " "for script '%s' (binary points to '%s/%s')", sieve_binary_path(sbin), sieve_script_label(script), str_c(storage_name), str_c(name)); return 0; } if (script->v.binary_read_metadata == NULL) return 1; return script->v.binary_read_metadata(script, sblock, offset); } void sieve_script_binary_write_metadata(struct sieve_script *script, struct sieve_binary_block *sblock) { struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); struct sieve_instance *svinst = sieve_binary_svinst(sbin); sieve_binary_emit_cstring(sblock, script->driver_name); sieve_binary_emit_unsigned(sblock, script->storage->version); if (HAS_ALL_BITS(svinst->flags, SIEVE_FLAG_COMMAND_LINE)) { sieve_binary_emit_cstring(sblock, ""); sieve_binary_emit_cstring(sblock, ""); } else { sieve_binary_emit_cstring(sblock, script->storage->name); sieve_binary_emit_cstring(sblock, script->name); } if (script->v.binary_write_metadata == NULL) return; script->v.binary_write_metadata(script, sblock); } bool sieve_script_binary_dump_metadata(struct sieve_script *script, struct sieve_dumptime_env *denv, struct sieve_binary_block *sblock, sieve_size_t *offset) { struct sieve_binary *sbin = sieve_binary_block_get_binary(sblock); struct sieve_instance *svinst = sieve_binary_svinst(sbin); string_t *storage_class, *storage_name, *name; struct sieve_script *adhoc_script = NULL; unsigned int version; bool result = TRUE; /* storage class */ if (!sieve_binary_read_string(sblock, offset, &storage_class)) return FALSE; sieve_binary_dumpf(denv, "class = %s\n", str_c(storage_class)); /* version */ if (!sieve_binary_read_unsigned(sblock, offset, &version)) return FALSE; sieve_binary_dumpf(denv, "class.version = %d\n", version); /* storage */ if (!sieve_binary_read_string(sblock, offset, &storage_name)) return FALSE; if (str_len(storage_name) == 0) sieve_binary_dumpf(denv, "storage = (unavailable)\n"); else sieve_binary_dumpf(denv, "storage = %s\n", str_c(storage_name)); /* name */ if (!sieve_binary_read_string(sblock, offset, &name)) return FALSE; if (str_len(name) == 0) sieve_binary_dumpf(denv, "name = (unavailable)\n"); else sieve_binary_dumpf(denv, "name = %s\n", str_c(name)); if (script == NULL) { adhoc_script = NULL; if (sieve_script_create_in(svinst, SIEVE_SCRIPT_CAUSE_ANY, str_c(storage_name), str_c(name), &script, NULL, NULL) == 0) adhoc_script = script; } if (script != NULL && script->v.binary_dump_metadata != NULL) { result = script->v.binary_dump_metadata( script, denv, sblock, offset); } sieve_script_unref(&adhoc_script); return result; } int sieve_script_binary_load_default(struct sieve_script *script, const char *path, struct sieve_binary **sbin_r) { struct sieve_instance *svinst = script->storage->svinst; enum sieve_error error_code; if (path == NULL) { sieve_script_set_error( script, SIEVE_ERROR_NOT_POSSIBLE, "Cannot load script binary for this storage"); return -1; } if (sieve_binary_open(svinst, path, script, sbin_r, &error_code) < 0) { sieve_script_set_error(script, error_code, "Failed to load script binary"); return -1; } return 0; } int sieve_script_binary_load(struct sieve_script *script, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { struct sieve_storage *storage = script->storage; int ret; *sbin_r = NULL; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (script->v.binary_load == NULL) { sieve_script_set_error( script, SIEVE_ERROR_NOT_POSSIBLE, "Cannot load script binary for this storage type"); ret = -1; } else { ret = script->v.binary_load(script, sbin_r); i_assert(ret <= 0); i_assert(ret < 0 || *sbin_r != NULL); } if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = script->storage->error_code; return -1; } return 0; } int sieve_script_binary_save_default(struct sieve_script *script ATTR_UNUSED, struct sieve_binary *sbin, const char *path, bool update, mode_t save_mode) { struct sieve_storage *storage = script->storage; enum sieve_error error_code; int ret; if (path == NULL) { e_debug(script->event, "No path to save Sieve script"); sieve_script_set_error( script, SIEVE_ERROR_NOT_POSSIBLE, "Cannot save script binary for this storage"); return -1; } if (storage->bin_path != NULL && str_begins_with(path, storage->bin_path) && sieve_storage_setup_bin_path( script->storage, mkdir_get_executable_mode(save_mode)) < 0) return -1; e_debug(script->event, "Saving binary to '%s'", path); ret = sieve_binary_save(sbin, path, update, save_mode, &error_code); if (ret < 0) { sieve_script_set_error(script, error_code, "Failed to save script binary"); return -1; } return 0; } int sieve_script_binary_save(struct sieve_script *script, struct sieve_binary *sbin, bool update, enum sieve_error *error_code_r) { struct sieve_storage *storage = script->storage; struct sieve_script *bin_script = sieve_binary_script(sbin); int ret; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); i_assert(bin_script == NULL || sieve_script_equals(bin_script, script)); if (script->v.binary_save == NULL) { sieve_script_set_error( script, SIEVE_ERROR_NOT_POSSIBLE, "Cannot save script binary for this storage type"); ret = -1; } else { ret = script->v.binary_save(script, sbin, update); } if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = script->storage->error_code; return -1; } return 0; } const char *sieve_script_binary_get_prefix(struct sieve_script *script) { struct sieve_storage *storage = script->storage; if (storage->bin_path != NULL && sieve_storage_setup_bin_path(storage, 0700) >= 0) return t_strconcat(storage->bin_path, "/", script->name, NULL); if (script->v.binary_get_prefix == NULL) return NULL; return script->v.binary_get_prefix(script); } /* * Management */ static int sieve_script_copy_from_default(struct sieve_script *script, const char *newname) { struct sieve_storage *storage = script->storage; struct istream *input; int ret; /* copy from default */ if ((ret = sieve_script_open(script, NULL)) < 0 || (ret = sieve_script_get_stream(script, &input, NULL)) < 0) { sieve_storage_copy_error(storage->default_storage_for, storage); return ret; } ret = sieve_storage_save_as(storage->default_storage_for, input, newname); if (ret < 0) { sieve_storage_copy_error(storage, storage->default_storage_for); } else if (sieve_script_is_active(script) > 0) { struct sieve_script *newscript; enum sieve_error error_code; if (sieve_storage_open_script(storage->default_storage_for, newname, &newscript, &error_code) < 0) { /* Somehow not actually saved */ ret = (error_code == SIEVE_ERROR_NOT_FOUND ? 0 : -1); } else if (sieve_script_activate(newscript, (time_t)-1) < 0) { /* Failed to activate; roll back */ ret = -1; (void)sieve_script_delete(newscript, TRUE); } sieve_script_unref(&newscript); if (ret < 0) { e_error(storage->event, "Failed to implicitly activate script '%s' " "after rename", newname); sieve_storage_copy_error(storage->default_storage_for, storage); } } return ret; } int sieve_script_rename(struct sieve_script *script, const char *newname) { struct sieve_storage *storage = script->storage; const char *oldname = script->name; struct event_passthrough *event; int ret; i_assert(newname != NULL); sieve_storage_clear_error(storage); /* Check script name */ if (!sieve_script_name_is_valid(newname)) { sieve_script_set_error(script, SIEVE_ERROR_BAD_PARAMS, "Invalid new Sieve script name '%s'.", str_sanitize(newname, 80)); return -1; } i_assert(script->open); // FIXME: auto-open? if (storage->default_storage_for == NULL) { i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); /* rename script */ i_assert(script->v.rename != NULL); ret = script->v.rename(script, newname); /* rename INBOX mailbox attribute */ if (ret >= 0 && oldname != NULL) { (void)sieve_storage_sync_script_rename(storage, oldname, newname); } } else if (sieve_storage_check_script(storage->default_storage_for, newname, NULL) > 0) { sieve_script_set_error(script, SIEVE_ERROR_EXISTS, "A sieve script with that name already exists."); sieve_storage_copy_error(storage->default_storage_for, storage); ret = -1; } else { ret = sieve_script_copy_from_default(script, newname); } event = event_create_passthrough(script->event)-> clear_field("script_name")-> add_str("old_script_name", script->name)-> add_str("new_script_name", newname)-> set_name("sieve_script_renamed"); if (ret >= 0) { e_debug(event->event(), "Script renamed to '%s'", newname); sieve_script_update_event(script); } else { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); event = event->add_str("error", storage->error); e_debug(event->event(), "Failed to rename script: %s", storage->error); } return ret; } int sieve_script_delete(struct sieve_script *script, bool ignore_active) { struct sieve_storage *storage = script->storage; bool is_active = FALSE; int ret = 0; i_assert(script->open); // FIXME: auto-open? sieve_storage_clear_error(storage); /* Is the requested script active? */ if (sieve_script_is_active(script) > 0) { is_active = TRUE; if (!ignore_active) { sieve_script_set_error(script, SIEVE_ERROR_ACTIVE, "Cannot delete the active Sieve script."); if (storage->default_storage_for != NULL) { sieve_storage_copy_error( storage->default_storage_for, storage); } return -1; } } /* Trying to delete the default script? */ if (storage->is_default) { /* ignore */ return 0; } i_assert((script->storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); /* Deactivate it explicity */ if (ignore_active && is_active) (void)sieve_storage_deactivate(storage, (time_t)-1); i_assert(script->v.delete != NULL); ret = script->v.delete(script); if (ret >= 0) { struct event_passthrough *e = event_create_passthrough(script->event)-> set_name("sieve_script_deleted"); e_debug(e->event(), "Script deleted"); /* unset INBOX mailbox attribute */ (void)sieve_storage_sync_script_delete(storage, script->name); } else { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(script->event)-> add_str("error", storage->error)-> set_name("sieve_script_deleted"); e_debug(e->event(), "Failed to delete script: %s", storage->error); } return ret; } int sieve_script_is_active(struct sieve_script *script) { struct sieve_storage *storage = script->storage; int ret; sieve_storage_clear_error(storage); /* Special handling if this is a default script */ if (storage->default_storage_for != NULL) { ret = sieve_storage_active_script_is_default( storage->default_storage_for); if (ret < 0) { sieve_storage_copy_error(storage, storage->default_storage_for); i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); } return ret; } if (script->v.is_active == NULL) return 0; ret = script->v.is_active(script); i_assert(ret >= 0 || (storage->error_code != SIEVE_ERROR_NONE && storage->error != NULL)); return ret; } int sieve_script_activate(struct sieve_script *script, time_t mtime) { struct sieve_storage *storage = script->storage; int ret = 0; i_assert(script->open); // FIXME: auto-open? sieve_storage_clear_error(storage); if (storage->default_storage_for == NULL) { i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); i_assert(script->v.activate != NULL); ret = script->v.activate(script); if (ret >= 0) { struct event_passthrough *e = event_create_passthrough(script->event)-> set_name("sieve_script_activated"); e_debug(e->event(), "Script activated"); sieve_storage_set_modified(storage, mtime); (void)sieve_storage_sync_script_activate(storage); } else { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(script->event)-> add_str("error", storage->error)-> set_name("sieve_script_activated"); e_debug(e->event(), "Failed to activate script: %s", storage->error); } } else { /* Activating the default script is equal to deactivating the storage */ ret = sieve_storage_deactivate(storage->default_storage_for, (time_t)-1); if (ret < 0) { sieve_storage_copy_error(storage, storage->default_storage_for); } } return ret; } /* * Error handling */ void sieve_script_set_error(struct sieve_script *script, enum sieve_error error_code, const char *fmt, ...) { struct sieve_storage *storage = script->storage; va_list va; sieve_storage_clear_error(storage); if (fmt != NULL) { va_start(va, fmt); storage->error = i_strdup_vprintf(fmt, va); va_end(va); } storage->error_code = error_code; } void sieve_script_set_internal_error(struct sieve_script *script) { sieve_storage_set_internal_error(script->storage); } void sieve_script_set_critical(struct sieve_script *script, const char *fmt, ...) { struct sieve_storage *storage = script->storage; va_list va; if (fmt != NULL) { if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0) { va_start(va, fmt); e_error(script->event, "%s", t_strdup_vprintf(fmt, va)); va_end(va); sieve_storage_set_internal_error(storage); } else { sieve_storage_clear_error(storage); /* no user is involved while synchronizing, so do it the normal way */ va_start(va, fmt); storage->error = i_strdup_vprintf(fmt, va); va_end(va); storage->error_code = SIEVE_ERROR_TEMP_FAILURE; } } } void sieve_script_set_not_found_error(struct sieve_script *script, const char *name) { name = (name == NULL || *name == '\0' ? script->name : name); sieve_storage_set_not_found_error(script->storage, name); } const char * sieve_script_get_last_error(struct sieve_script *script, enum sieve_error *error_code_r) { return sieve_storage_get_last_error(script->storage, error_code_r); } const char *sieve_script_get_last_error_lcase(struct sieve_script *script) { return sieve_error_from_external(script->storage->error); } /* * Script sequence */ int sieve_script_sequence_create(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const char *type, struct sieve_script_sequence **sseq_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage_sequence *storage_seq; struct sieve_script_sequence *sseq; *sseq_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (sieve_storage_sequence_create(svinst, event_parent, cause, type, &storage_seq, error_code_r, error_r) < 0) return -1; sseq = i_new(struct sieve_script_sequence, 1); sseq->storage_seq = storage_seq; *sseq_r = sseq; return 0; } static int sieve_script_sequence_init_storage(struct sieve_script_sequence *sseq, enum sieve_error *error_code_r, const char **error_r) { int ret; while (sseq->storage == NULL) { ret = sieve_storage_sequence_next(sseq->storage_seq, &sseq->storage, error_code_r, error_r); if (ret == 0) return 0; if (ret < 0) { if (*error_code_r == SIEVE_ERROR_NOT_FOUND) continue; return -1; } struct sieve_storage *storage = sseq->storage; i_assert(storage->v.script_sequence_init != NULL); sieve_storage_clear_error(storage); ret = storage->v.script_sequence_init(sseq); if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = storage->error_code; *error_r = storage->error; sieve_storage_unref(&sseq->storage); if (*error_code_r != SIEVE_ERROR_NOT_FOUND) return -1; } } return 1; } static void sieve_script_sequence_deinit_storage(struct sieve_script_sequence *sseq) { struct sieve_storage *storage = sseq->storage; if (storage != NULL && storage->v.script_sequence_destroy != NULL) storage->v.script_sequence_destroy(sseq); sseq->storage_data = NULL; sieve_storage_unref(&sseq->storage); } int sieve_script_sequence_next(struct sieve_script_sequence *sseq, struct sieve_script **script_r, enum sieve_error *error_code_r, const char **error_r) { int ret; *script_r = NULL; sieve_error_args_init(&error_code_r, &error_r); while ((ret = sieve_script_sequence_init_storage( sseq, error_code_r, error_r)) > 0) { struct sieve_storage *storage = sseq->storage; i_assert(storage->v.script_sequence_next != NULL); sieve_storage_clear_error(storage); ret = storage->v.script_sequence_next(sseq, script_r); if (ret > 0) break; if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); if (storage->error_code == SIEVE_ERROR_NOT_FOUND) ret = 0; else { *error_code_r = storage->error_code; *error_r = t_strdup(storage->error); } } sieve_script_sequence_deinit_storage(sseq); if (ret < 0) break; } return ret; } void sieve_script_sequence_free(struct sieve_script_sequence **_sseq) { struct sieve_script_sequence *sseq = *_sseq; if (sseq == NULL) return; *_sseq = NULL; sieve_script_sequence_deinit_storage(sseq); sieve_storage_sequence_free(&sseq->storage_seq); i_free(sseq); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-storage.c0000644000175100001700000014772515100335616024406 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str.h" #include "str-sanitize.h" #include "hash.h" #include "home-expand.h" #include "eacces-error.h" #include "mkdir-parents.h" #include "ioloop.h" #include "settings.h" #include "sieve-common.h" #include "sieve-error-private.h" #include "sieve-script-private.h" #include "sieve-storage-private.h" #include #include #include #include #include struct event_category event_category_sieve_storage = { .parent = &event_category_sieve, .name = "sieve-storage", }; /* * Storage name */ bool sieve_storage_name_is_valid(const char *name) { return sieve_script_name_is_valid(name); } /* * Storage class */ struct sieve_storage_class_registry { ARRAY_TYPE(sieve_storage_class) storage_classes; }; void sieve_storages_init(struct sieve_instance *svinst) { svinst->storage_reg = p_new(svinst->pool, struct sieve_storage_class_registry, 1); p_array_init(&svinst->storage_reg->storage_classes, svinst->pool, 8); sieve_storage_class_register(svinst, &sieve_file_storage); sieve_storage_class_register(svinst, &sieve_dict_storage); sieve_storage_class_register(svinst, &sieve_ldap_storage); } void sieve_storages_deinit(struct sieve_instance *svinst ATTR_UNUSED) { /* nothing yet */ } void sieve_storage_class_register(struct sieve_instance *svinst, const struct sieve_storage *storage_class) { struct sieve_storage_class_registry *reg = svinst->storage_reg; const struct sieve_storage *old_class; old_class = sieve_storage_class_find(svinst, storage_class->driver_name); if (old_class != NULL) { if (old_class->v.alloc == NULL) { /* replacing a "support not compiled in" storage class */ sieve_storage_class_unregister(svinst, old_class); } else { i_panic("sieve_storage_class_register(%s): " "Already registered", storage_class->driver_name); } } array_append(®->storage_classes, &storage_class, 1); } void sieve_storage_class_unregister(struct sieve_instance *svinst, const struct sieve_storage *storage_class) { struct sieve_storage_class_registry *reg = svinst->storage_reg; const struct sieve_storage *const *classes; unsigned int i, count; classes = array_get(®->storage_classes, &count); for (i = 0; i < count; i++) { if (classes[i] == storage_class) { array_delete(®->storage_classes, i, 1); break; } } } const struct sieve_storage * sieve_storage_class_find(struct sieve_instance *svinst, const char *name) { struct sieve_storage_class_registry *reg = svinst->storage_reg; const struct sieve_storage *const *classes; unsigned int i, count; i_assert(name != NULL); classes = array_get(®->storage_classes, &count); for (i = 0; i < count; i++) { if (strcasecmp(classes[i]->driver_name, name) == 0) return classes[i]; } return NULL; } bool sieve_storage_class_exists(struct sieve_instance *svinst, const char *name) { return (sieve_storage_class_find(svinst, name) != NULL); } /* * Storage event */ static void sieve_storage_update_event_prefix(struct event *event, const char *storage_name, bool is_default) { string_t *prefix = t_str_new(128); str_append(prefix, "storage"); if (storage_name != NULL && *storage_name != '\0') { str_append_c(prefix, ' '); str_append(prefix, storage_name); } if (is_default) str_append(prefix, " (default)"); str_append(prefix, ": "); event_set_append_log_prefix(event, str_c(prefix)); } static struct event * sieve_storage_create_event(struct sieve_instance *svinst, struct event *event_parent, const char *storage_name) { struct event *event; event = event_create(event_parent == NULL ? svinst->event : event_parent); if (event_parent != svinst->event) event_add_category(event, &event_category_sieve); event_add_category(event, &event_category_sieve_storage); sieve_storage_update_event_prefix(event, storage_name, FALSE); return event; } static struct event * sieve_storage_create_driver_event(struct event *event_parent, const char *driver_name) { struct event *event; event = event_create(event_parent); event_add_str(event, "driver", driver_name); event_set_append_log_prefix(event, t_strdup_printf("%s: ", driver_name)); return event; } /* * Storage instance */ static int sieve_storage_alloc_from_class(struct sieve_instance *svinst, struct event *event, const struct sieve_storage *storage_class, const char *cause, const char *script_type, const char *storage_name, const char *script_name, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage *storage; i_assert(svinst->username != NULL); if (storage_class->v.alloc == NULL) { e_error(event, "Support not compiled in for this driver"); sieve_error_create_script_not_found( script_name, error_code_r, error_r); return -1; } if ((flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 && !storage_class->allows_synchronization) { e_error(event, "Storage does not support synchronization"); sieve_error_create_internal(error_code_r, error_r); return -1; } if ((flags & SIEVE_STORAGE_FLAG_READWRITE) != 0 && storage_class->v.save_init == NULL) { e_error(event, "Storage does not support write access"); sieve_error_create_internal(error_code_r, error_r); return -1; } storage = storage_class->v.alloc(); storage->storage_class = storage_class; storage->refcount = 1; storage->svinst = svinst; storage->cause = p_strdup(storage->pool, cause); storage->type = p_strdup(storage->pool, script_type); storage->script_name = p_strdup(storage->pool, script_name); storage->flags = flags; if (storage_name != NULL && *storage_name != '\0') storage->name = p_strdup(storage->pool, storage_name); else { storage->name = p_strconcat( storage->pool, "auto:", storage->type, NULL); } storage->event = event; event_ref(event); *storage_r = storage; return 0; } int sieve_storage_alloc(struct sieve_instance *svinst, struct event *event_parent, const struct sieve_storage *storage_class, const char *cause, const char *script_type, const char *storage_name, const char *script_name, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct event *storage_event, *event; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); storage_event = sieve_storage_create_event(svinst, event_parent, storage_name); event = sieve_storage_create_driver_event(storage_event, storage_class->driver_name); event_unref(&storage_event); ret = sieve_storage_alloc_from_class(svinst, event, storage_class, cause, script_type, storage_name, script_name, flags, storage_r, error_code_r, error_r); event_unref(&event); return ret; } int sieve_storage_alloc_with_settings(struct sieve_instance *svinst, struct event *event_parent, const struct sieve_storage *storage_class, const char *cause, const struct sieve_storage_settings *set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage *storage; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); ret = sieve_storage_alloc_from_class(svinst, event_parent, storage_class, cause, set->script_type, set->script_storage, set->script_name, flags, &storage, error_code_r, error_r); if (ret < 0) return -1; const char *bin_path = set->script_bin_path; if (sieve_storage_get_full_path(storage, bin_path, &bin_path) < 0) { sieve_storage_set_critical( storage, "Binary storage path '%s' is relative to home directory, " "but home directory is not available.", bin_path); return -1; } storage->bin_path = p_strdup_empty(storage->pool, bin_path); storage->max_storage = set->quota_storage_size; storage->max_scripts = set->quota_script_count; if (storage->bin_path != NULL) { e_debug(storage->event, "Directory for binaries: %s", storage->bin_path); } if (storage->max_storage > 0) { e_debug(storage->event, "quota: " "Storage limit: %"PRIuUOFF_T" bytes", storage->max_storage); } if (storage->max_scripts > 0) { e_debug(storage->event, "quota: " "Script count limit: %u scripts", storage->max_scripts); } *storage_r = storage; return 0; } static int sieve_storage_alloc_from_settings(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const struct sieve_storage_settings *set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { const struct sieve_storage *storage_class; struct event *event = event_parent; int ret; *storage_r = NULL; if (!sieve_storage_settings_match_script_cause(set, cause)) return 0; storage_class = sieve_storage_class_find(svinst, set->script_driver); // FIXME: add support for automatic module loading (no such modules yet) if (storage_class == NULL) { e_error(event, "Unknown storage driver: %s", set->script_driver); sieve_error_create_script_not_found(set->script_name, error_code_r, error_r); event_unref(&event); return -1; } event = sieve_storage_create_driver_event(event_parent, storage_class->driver_name); ret = sieve_storage_alloc_with_settings(svinst, event, storage_class, cause, set, flags, storage_r, error_code_r, error_r); event_unref(&event); if (ret < 0) return -1; return 1; } static int sieve_storage_autodetect(struct sieve_instance *svinst, struct event *event, const char *cause, const char *type, const struct sieve_storage_settings *set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage_class_registry *reg = svinst->storage_reg; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (!sieve_storage_settings_match_script_cause(set, cause)) return 0; if (!sieve_storage_settings_match_script_type(set, type)) return 0; const struct sieve_storage *const *classes; unsigned int i, count; classes = array_get(®->storage_classes, &count); ret = 0; for (i = 0; i < count; i++) { if (classes[i]->v.autodetect == NULL) continue; if (set->script_driver[0] != '\0' && strcasecmp(set->script_driver, classes[i]->driver_name) != 0) continue; struct event *driver_event = sieve_storage_create_driver_event( event, classes[i]->driver_name); *storage_r = NULL; ret = classes[i]->v.autodetect(svinst, driver_event, cause, set, flags, storage_r, error_code_r, error_r); event_unref(&driver_event); if (ret < 0) { i_assert(*error_code_r != SIEVE_ERROR_NONE); i_assert(*error_r != NULL); if (*error_code_r == SIEVE_ERROR_NOT_FOUND) { *error_code_r = SIEVE_ERROR_NONE; *error_r = NULL; ret = 0; } } i_assert(ret <= 0 || *storage_r != NULL); if (ret != 0) break; } if (ret == 0) e_debug(event, "Autodetection failed"); return ret; } static int sieve_storage_autodetect_any(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const char *type, const struct sieve_storage_settings *set, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct event *event; int ret; event = sieve_storage_create_event(svinst, event_parent, NULL); ret = sieve_storage_autodetect(svinst, event, cause, type, set, flags, storage_r, error_code_r, error_r); event_unref(&event); return ret; } static int sieve_storage_init_real(struct sieve_instance *svinst, struct event *event, const char *cause, const char *type, const char *storage_name, bool try, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { const struct sieve_storage_settings *set; struct sieve_storage *storage; const char *error; int ret; if (try) { ret = settings_try_get_filter( event, "sieve_script", storage_name, &sieve_storage_setting_parser_info, 0, &set, &error); if (ret == 0) return 0; } else { ret = settings_get_filter( event, "sieve_script", storage_name, &sieve_storage_setting_parser_info, 0, &set, &error); } if (ret < 0) { e_error(event, "%s", error); sieve_error_create_internal(error_code_r, error_r); return -1; } if (!sieve_storage_settings_match_script_type(set, type)) { settings_free(set); return 0; } event_add_str(event, "sieve_script", storage_name); settings_event_add_list_filter_name(event, "sieve_script", storage_name); if (set->script_driver[0] == '\0') { ret = sieve_storage_autodetect(svinst, event, cause, type, set, flags, storage_r, error_code_r, error_r); if (ret != 0) { settings_free(set); return ret; } e_error(event, "sieve_script_driver is empty"); sieve_error_create_script_not_found(set->script_name, error_code_r, error_r); settings_free(set); return -1; } ret = sieve_storage_alloc_from_settings(svinst, event, cause, set, flags, &storage, error_code_r, error_r); settings_free(set); if (ret <= 0) return ret; i_assert(storage != NULL); i_assert(storage->v.init != NULL); T_BEGIN { ret = storage->v.init(storage); i_assert(ret <= 0); } T_END; if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = storage->error_code; *error_r = t_strdup(storage->error); sieve_storage_unref(&storage); return -1; } *storage_r = storage; return 1; } static int sieve_storage_init(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const char *type, const char *storage_name, bool try, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct event *event; int ret; *storage_r = NULL; event = sieve_storage_create_event(svinst, event_parent, storage_name); ret = sieve_storage_init_real(svinst, event, cause, type, storage_name, try, flags, storage_r, error_code_r, error_r); event_unref(&event); return ret; } int sieve_storage_create(struct sieve_instance *svinst, struct event *event, const char *cause, const char *storage_name, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage *storage; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); ret = sieve_storage_init(svinst, event, cause, SIEVE_STORAGE_TYPE_ANY, storage_name, TRUE, flags, &storage, error_code_r, error_r); if (ret < 0) { if (*error_code_r != SIEVE_ERROR_NOT_FOUND) return -1; ret = 0; } if (ret == 0) { e_debug(event, "Sieve script storage '%s' not found (cause=%s)", storage_name, cause); sieve_error_create_script_not_found( NULL, error_code_r, error_r); return -1; } i_assert(storage != NULL); *storage_r = storage; return 0; } int sieve_storage_create_auto(struct sieve_instance *svinst, struct event *event, const char *cause, const char *type, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { const struct sieve_storage_settings *storage_set; const char *const *storage_names; unsigned int i, count; const char *error; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (settings_get(event, &sieve_storage_setting_parser_info, SETTINGS_GET_FLAG_SORT_FILTER_ARRAYS, &storage_set, &error) < 0) { e_error(event, "%s", error); sieve_error_create_internal(error_code_r, error_r); return -1; } if (array_is_created(&storage_set->storages)) storage_names = array_get(&storage_set->storages, &count); else { storage_names = NULL; count = 0; } struct sieve_storage *storage = NULL; int ret = 0; for (i = 0; i < count; i++) { ret = sieve_storage_init(svinst, event, cause, type, storage_names[i], FALSE, flags, &storage, error_code_r, error_r); if (ret < 0 && *error_code_r != SIEVE_ERROR_NOT_FOUND) { settings_free(storage_set); return -1; } if (ret > 0) { i_assert(storage != NULL); break; } } if (ret <= 0) { ret = sieve_storage_autodetect_any(svinst, event, cause, type, storage_set, flags, &storage, error_code_r, error_r); if (ret < 0) { settings_free(storage_set); return -1; } } settings_free(storage_set); if (ret <= 0) { e_debug(event, "storage: No matching Sieve storage configured " "(type=%s and cause=%s)", type, cause); sieve_error_create_script_not_found( NULL, error_code_r, error_r); return -1; } i_assert(storage != NULL); *storage_r = storage; return 0; } static int sieve_storage_create_default(struct sieve_instance *svinst, struct event *event, const char *cause, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_storage *storage; enum sieve_error error_code; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); ret = sieve_storage_create_auto(svinst, event, cause, SIEVE_STORAGE_TYPE_DEFAULT, flags, &storage, &error_code, error_r); if (ret >= 0) { storage->is_default = TRUE; sieve_storage_update_event_prefix( event_get_parent(storage->event), storage->name, TRUE); } else { switch (error_code) { case SIEVE_ERROR_NOT_FOUND: e_debug(event, "storage: " "Default script not found"); break; case SIEVE_ERROR_TEMP_FAILURE: e_error(event, "storage: " "Failed to access default script " "(temporary failure)"); break; default: e_error(event, "storage: " "Failed to access default script"); break; } *error_code_r = error_code; } *storage_r = storage; return ret; } static int sieve_storage_create_default_for(struct sieve_storage *storage, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (storage->default_storage != NULL) { sieve_storage_ref(storage->default_storage); *storage_r = storage->default_storage; return 0; } struct sieve_instance *svinst = storage->svinst; enum sieve_error error_code; const char *error; i_assert(storage->default_storage_for == NULL); if (sieve_storage_create_default(svinst, svinst->event, storage->cause, 0, &storage->default_storage, &error_code, &error) < 0) { sieve_storage_set_error(storage, error_code, "%s", error); *error_code_r = storage->error_code; *error_r = storage->error; return -1; } storage->default_storage->default_storage_for = storage; sieve_storage_ref(storage); *storage_r = storage->default_storage; return 0; } int sieve_storage_create_personal(struct sieve_instance *svinst, struct mail_user *user, const char *cause, enum sieve_storage_flags flags, struct sieve_storage **storage_r, enum sieve_error *error_code_r) { struct sieve_storage *storage; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, NULL); /* Check whether Sieve is disabled for this user */ if (!svinst->set->enabled) { e_debug(svinst->event, "Sieve is disabled for this user"); *error_code_r = SIEVE_ERROR_NOT_POSSIBLE; return -1; } /* Attempt to locate user's main storage */ ret = sieve_storage_create_auto(svinst, svinst->event, cause, SIEVE_STORAGE_TYPE_PERSONAL, flags, &storage, error_code_r, NULL); if (ret == 0) { (void)sieve_storage_sync_init(storage, user); } else if (*error_code_r != SIEVE_ERROR_TEMP_FAILURE && (flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 && (flags & SIEVE_STORAGE_FLAG_READWRITE) == 0) { /* Failed; try using default script location (not for temporary failures, read/write access, or dsync) */ ret = sieve_storage_create_default(svinst, svinst->event, cause, flags, &storage, error_code_r, NULL); } *storage_r = storage; return ret; } void sieve_storage_ref(struct sieve_storage *storage) { storage->refcount++; } void sieve_storage_unref(struct sieve_storage **_storage) { struct sieve_storage *storage = *_storage; if (storage == NULL) return; *_storage = NULL; i_assert(storage->refcount > 0); if (--storage->refcount != 0) return; if (storage->default_storage_for != NULL) { i_assert(storage->is_default); storage->default_storage_for->default_storage = NULL; sieve_storage_unref(&storage->default_storage_for); } sieve_storage_sync_deinit(storage); if (storage->v.destroy != NULL) storage->v.destroy(storage); i_free(storage->error); event_unref(&storage->event); pool_unref(&storage->pool); } /* * Utility */ int sieve_storage_get_full_path(struct sieve_storage *storage, const char *path, const char **path_r) { struct sieve_instance *svinst = storage->svinst; *path_r = path; if (path == NULL || *path == '\0') return 0; if ((path[0] != '~' || (path[1] != '/' && path[1] != '\0')) && ((svinst->flags & SIEVE_FLAG_HOME_RELATIVE) == 0 || path[0] == '/')) return 0; /* Home-relative path. change to absolute. */ const char *home = sieve_environment_get_homedir(svinst); if (home == NULL) return -1; if (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) *path_r = home_expand_tilde(path, home); else *path_r = t_strconcat(home, "/", path, NULL); return 0; } /* * Binary */ int sieve_storage_setup_bin_path(struct sieve_storage *storage, mode_t mode) { const char *bin_path = storage->bin_path; struct stat st; if (bin_path == NULL) { sieve_storage_set_critical( storage, "script_bin_path not configured for storage"); return -1; } if (stat(bin_path, &st) == 0) { e_debug(storage->event, "Directory for saving binary already exists"); return 0; } if (errno == EACCES) { sieve_storage_set_critical(storage, "Failed to setup directory for binaries: " "%s", eacces_error_get("stat", bin_path)); return -1; } else if (errno != ENOENT) { sieve_storage_set_critical(storage, "Failed to setup directory for binaries: " "stat(%s) failed: %m", bin_path); return -1; } if (mkdir_parents(bin_path, mode) == 0) { e_debug(storage->event, "Created directory for binaries: %s", bin_path); return 1; } switch (errno) { case EEXIST: return 0; case ENOENT: sieve_storage_set_critical(storage, "Directory for binaries was deleted while it was being created"); break; case EACCES: sieve_storage_set_critical(storage, "%s", eacces_error_get_creating("mkdir_parents_chgrp", bin_path)); break; default: sieve_storage_set_critical(storage, "mkdir_parents_chgrp(%s) failed: %m", bin_path); break; } return -1; } /* * Properties */ int sieve_storage_is_singular(struct sieve_storage *storage) { if (storage->v.is_singular == NULL) return 1; return storage->v.is_singular(storage); } int sieve_storage_get_last_change(struct sieve_storage *storage, time_t *last_change_r) { i_assert(storage->v.get_last_change != NULL); return storage->v.get_last_change(storage, last_change_r); } void sieve_storage_set_modified(struct sieve_storage *storage, time_t mtime) { if (storage->v.set_modified == NULL) return; storage->v.set_modified(storage, mtime); } /* * Comparison */ int sieve_storage_cmp(const struct sieve_storage *storage1, const struct sieve_storage *storage2) { int ret; if (storage1 == storage2) return 0; if (storage1 == NULL || storage2 == NULL) return (storage1 == NULL ? -1 : 1); if (storage1->storage_class != storage2->storage_class) { return (storage1->storage_class > storage2->storage_class ? 1 : -1); } ret = null_strcmp(storage1->type, storage2->type); if (ret != 0) return (ret > 0 ? 1 : -1); return null_strcmp(storage1->name, storage2->name); } unsigned int sieve_storage_hash(const struct sieve_storage *storage) { unsigned int hash = 0; hash ^= POINTER_CAST_TO(storage->storage_class, unsigned int); hash ^= str_hash(storage->type); hash ^= str_hash(storage->name); return hash; } /* * Script access */ int sieve_storage_get_script_direct(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r) { int ret; /* Validate script name */ if (name != NULL && !sieve_script_name_is_valid(name)) { sieve_storage_set_error(storage, SIEVE_ERROR_BAD_PARAMS, "Invalid script name '%s'.", str_sanitize(name, 80)); *error_code_r = storage->error_code; return -1; } if (name == NULL) name = storage->script_name; i_assert(storage->v.get_script != NULL); ret = storage->v.get_script(storage, name, script_r); i_assert(ret <= 0); if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); *error_code_r = storage->error_code; } return ret; } static int sieve_storage_get_default_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r) { struct sieve_storage *def_storage; int ret; if (*error_code_r != SIEVE_ERROR_NOT_FOUND || (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0 || !sieve_storage_is_personal(storage)) return -1; /* Not found; if this name maps to the default script, try to access that instead */ e_debug(storage->event, "Trying default script instead"); /* Failed; try using default script location (not for temporary failures, read/write access, or dsync) */ ret = sieve_storage_create_default_for(storage, &def_storage, error_code_r, NULL); if (ret < 0) return -1; if (strcmp(def_storage->script_name, name) != 0) { sieve_storage_set_error(storage, SIEVE_ERROR_NOT_FOUND, "Default script '%s' not found", str_sanitize(name, 80)); *error_code_r = storage->error_code; sieve_storage_unref(&def_storage); return -1; } struct sieve_script *def_script; ret = sieve_storage_get_script_direct(def_storage, name, &def_script, error_code_r); if (ret < 0) sieve_storage_copy_error(storage, def_storage); sieve_storage_unref(&def_storage); if (ret < 0) return -1; i_assert(def_script != NULL); *script_r = def_script; return 0; } int sieve_storage_get_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r) { *script_r = NULL; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (sieve_storage_get_script_direct(storage, name, script_r, error_code_r) >= 0) return 0; /* Try default instead if appropriate */ return sieve_storage_get_default_script(storage, name, script_r, error_code_r); } int sieve_storage_open_script(struct sieve_storage *storage, const char *name, struct sieve_script **script_r, enum sieve_error *error_code_r) { struct sieve_script *script; *script_r = NULL; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (sieve_storage_get_script(storage, name, &script, error_code_r) < 0) return -1; if (sieve_script_open(script, error_code_r) == 0) { *script_r = script; return 0; } sieve_script_unref(&script); /* Try default instead if appropriate */ if (sieve_storage_get_default_script(storage, name, &script, error_code_r) < 0) return -1; if (sieve_script_open(script, error_code_r) < 0) { sieve_script_unref(&script); return -1; } *script_r = script; return 0; } static int sieve_storage_check_script_direct(struct sieve_storage *storage, const char *name, enum sieve_error *error_code_r) { struct sieve_script *script; int ret; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (sieve_storage_get_script_direct(storage, name, &script, error_code_r) < 0) return (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1); ret = sieve_script_open(script, error_code_r); sieve_script_unref(&script); return (ret >= 0 ? 1 : (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1)); } int sieve_storage_check_script(struct sieve_storage *storage, const char *name, enum sieve_error *error_code_r) { struct sieve_script *script; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); if (sieve_storage_open_script(storage, name, &script, error_code_r) < 0) return (*error_code_r == SIEVE_ERROR_NOT_FOUND ? 0 : -1); sieve_script_unref(&script); return 1; } /* * Active script */ static int sieve_storage_active_script_do_get_name(struct sieve_storage *storage, const char **name_r, bool *default_r) ATTR_NULL(3) { int ret; if (default_r != NULL) *default_r = FALSE; i_assert(storage->v.active_script_get_name != NULL); ret = storage->v.active_script_get_name(storage, name_r); if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); if (storage->error_code == SIEVE_ERROR_NOT_FOUND) { sieve_storage_clear_error(storage); ret = 0; } } if (ret != 0 || (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) return ret; struct sieve_storage *def_storage; /* Failed; try using default script location (not for temporary failures, read/write access, or dsync) */ ret = sieve_storage_create_default_for(storage, &def_storage, NULL, NULL); if (ret < 0) return -1; *name_r = def_storage->script_name; ret = sieve_storage_check_script(def_storage, def_storage->script_name, NULL); if (ret < 0) { sieve_storage_copy_error(storage, def_storage); i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); } sieve_storage_unref(&def_storage); if (ret <= 0) return ret; if (default_r != NULL) *default_r = TRUE; return 1; } int sieve_storage_active_script_get_name(struct sieve_storage *storage, const char **name_r) { return sieve_storage_active_script_do_get_name(storage, name_r, NULL); } int sieve_storage_active_script_is_default(struct sieve_storage *storage) { const char *name; bool is_default = FALSE; int ret; ret = sieve_storage_active_script_do_get_name(storage, &name, &is_default); return (ret < 0 ? -1 : (is_default ? 1 : 0)); } int sieve_storage_active_script_open(struct sieve_storage *storage, struct sieve_script **script_r, enum sieve_error *error_code_r) { struct sieve_script *script = NULL; int ret; *script_r = NULL; sieve_error_args_init(&error_code_r, NULL); sieve_storage_clear_error(storage); i_assert(storage->v.active_script_open != NULL); ret = storage->v.active_script_open(storage, &script); i_assert(ret <= 0); i_assert(ret == 0 || (storage->error_code != SIEVE_ERROR_NONE && storage->error != NULL)); if (ret == 0 || storage->error_code != SIEVE_ERROR_NOT_FOUND || (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) { if (ret < 0) *error_code_r = storage->error_code; *script_r = script; return ret; } struct sieve_storage *def_storage; /* Try default script location */ ret = sieve_storage_create_default_for(storage, &def_storage, error_code_r, NULL); if (ret < 0) return -1; ret = sieve_storage_open_script(def_storage, NULL, script_r, error_code_r); if (ret < 0) sieve_storage_copy_error(storage, def_storage); sieve_storage_unref(&def_storage); return ret; } int sieve_storage_deactivate(struct sieve_storage *storage, time_t mtime) { int ret; i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); sieve_storage_clear_error(storage); i_assert(storage->v.deactivate != NULL); ret = storage->v.deactivate(storage); if (ret >= 0) { struct event_passthrough *e = event_create_passthrough(storage->event)-> set_name("sieve_storage_deactivated"); e_debug(e->event(), "Storage deactivated"); sieve_storage_set_modified(storage, mtime); (void)sieve_storage_sync_deactivate(storage); } else { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(storage->event)-> add_str("error", storage->error)-> set_name("sieve_storage_deactivated"); e_debug(e->event(), "Failed to deactivate storage: %s", storage->error); } return ret; } int sieve_storage_active_script_get_last_change(struct sieve_storage *storage, time_t *last_change_r) { i_assert(storage->v.active_script_get_last_change != NULL); return storage->v.active_script_get_last_change(storage, last_change_r); } /* * Listing scripts */ int sieve_storage_list_init(struct sieve_storage *storage, struct sieve_storage_list_context **lctx_r) { struct sieve_storage_list_context *lctx; *lctx_r = NULL; sieve_storage_clear_error(storage); i_assert(storage->v.list_init != NULL); if (storage->v.list_init(storage, &lctx) < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); return -1; } lctx->storage = storage; sieve_storage_ref(storage); if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) { /* No default script involved; return right away */ *lctx_r = lctx; return 0; } /* May need to list default script as well */ enum sieve_error error_code; if (sieve_storage_create_default_for(storage, &lctx->def_storage, &error_code, NULL) < 0 && error_code != SIEVE_ERROR_NOT_FOUND) return -1; *lctx_r = lctx; return 0; } const char * sieve_storage_list_next(struct sieve_storage_list_context *lctx, bool *active_r) { struct sieve_storage *storage = lctx->storage; const char *scriptname; bool script_active = FALSE; sieve_storage_clear_error(storage); i_assert(storage->v.list_next != NULL); scriptname = storage->v.list_next(lctx, &script_active); i_assert(!script_active || !lctx->seen_active); if (script_active) lctx->seen_active = TRUE; struct sieve_storage *def_storage = lctx->def_storage; bool have_default = (def_storage != NULL && def_storage->script_name != NULL); if (scriptname != NULL) { /* Remember when we see that the storage has its own script for default */ if (have_default && strcmp(scriptname, def_storage->script_name) == 0) lctx->seen_default = TRUE; } else if (have_default && !lctx->seen_default && sieve_storage_check_script(def_storage, NULL, NULL) > 0) { /* Return default script at the end if it was not listed thus far (storage backend has no script under default name) */ scriptname = def_storage->script_name; lctx->seen_default = TRUE; /* Mark default as active if no normal script is active */ if (!lctx->seen_active) { script_active = TRUE; lctx->seen_active = TRUE; } } if (active_r != NULL) *active_r = script_active; return scriptname; } int sieve_storage_list_deinit(struct sieve_storage_list_context **_lctx) { struct sieve_storage_list_context *lctx = *_lctx; if (lctx == NULL) return 0; *_lctx = NULL; struct sieve_storage *storage = lctx->storage; struct sieve_storage *def_storage = lctx->def_storage; int ret; i_assert(storage->v.list_deinit != NULL); ret = storage->v.list_deinit(lctx); i_assert(ret >= 0 || (storage->error_code != SIEVE_ERROR_NONE && storage->error != NULL)); sieve_storage_unref(&def_storage); sieve_storage_unref(&storage); return ret; } /* * Saving scripts */ static struct event * sieve_storage_save_create_event(struct sieve_storage *storage, const char *scriptname) ATTR_NULL(2) { struct event *event; event = event_create(storage->event); event_add_str(event, "script_name", scriptname); if (scriptname == NULL) { event_set_append_log_prefix(event, "save: "); } else { event_set_append_log_prefix( event, t_strdup_printf("script '%s': save: ", scriptname)); } return event; } static void sieve_storage_save_cleanup(struct sieve_storage_save_context *sctx) { sieve_script_unref(&sctx->scriptobject); } static void sieve_storage_save_deinit(struct sieve_storage_save_context **_sctx) { struct sieve_storage_save_context *sctx = *_sctx; *_sctx = NULL; if (sctx == NULL) return; sieve_storage_save_cleanup(sctx); event_unref(&sctx->event); pool_unref(&sctx->pool); } struct sieve_storage_save_context * sieve_storage_save_init(struct sieve_storage *storage, const char *scriptname, struct istream *input) { struct sieve_storage_save_context *sctx; sieve_storage_clear_error(storage); if (scriptname != NULL) { /* Validate script name */ if (!sieve_script_name_is_valid(scriptname)) { sieve_storage_set_error(storage, SIEVE_ERROR_BAD_PARAMS, "Invalid Sieve script name '%s'.", str_sanitize(scriptname, 80)); return NULL; } } i_assert((storage->flags & SIEVE_STORAGE_FLAG_READWRITE) != 0); i_assert(storage->v.save_alloc != NULL); sctx = storage->v.save_alloc(storage); sctx->storage = storage; sctx->event = sieve_storage_save_create_event(storage, scriptname); struct event_passthrough *e = event_create_passthrough(sctx->event)-> set_name("sieve_storage_save_started"); e_debug(e->event(), "Started saving script"); i_assert(storage->v.save_init != NULL); if ((storage->v.save_init(sctx, scriptname, input)) < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(sctx->event)-> add_str("error", storage->error)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Failed to save script: %s", storage->error); sieve_storage_save_deinit(&sctx); return NULL; } sctx->mtime = (time_t)-1; i_assert(sctx->input != NULL); return sctx; } int sieve_storage_save_continue(struct sieve_storage_save_context *sctx) { struct sieve_storage *storage = sctx->storage; int ret; sieve_storage_clear_error(storage); i_assert(storage->v.save_continue != NULL); ret = storage->v.save_continue(sctx); if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); sctx->failed = TRUE; } return ret; } int sieve_storage_save_finish(struct sieve_storage_save_context *sctx) { struct sieve_storage *storage = sctx->storage; int ret; sieve_storage_clear_error(storage); i_assert(!sctx->finished); sctx->finished = TRUE; i_assert(storage->v.save_finish != NULL); ret = storage->v.save_finish(sctx); if (ret < 0) { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(sctx->event)-> add_str("error", storage->error)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Failed to upload script: %s", storage->error); sctx->failed = TRUE; } return ret; } void sieve_storage_save_set_mtime(struct sieve_storage_save_context *sctx, time_t mtime) { sctx->mtime = mtime; } struct sieve_script * sieve_storage_save_get_tempscript(struct sieve_storage_save_context *sctx) { struct sieve_storage *storage = sctx->storage; if (sctx->failed) return NULL; if (sctx->scriptobject != NULL) return sctx->scriptobject; sieve_storage_clear_error(storage); i_assert(storage->v.save_get_tempscript != NULL); sctx->scriptobject = storage->v.save_get_tempscript(sctx); i_assert(sctx->scriptobject != NULL || (storage->error_code != SIEVE_ERROR_NONE && storage->error != NULL)); return sctx->scriptobject; } bool sieve_storage_save_will_activate(struct sieve_storage_save_context *sctx) { struct sieve_storage *storage = sctx->storage; if (sctx->scriptname == NULL) return FALSE; sieve_storage_clear_error(storage); if (sctx->active_scriptname == NULL) { const char *scriptname; if (sieve_storage_active_script_get_name(sctx->storage, &scriptname) > 0) { sctx->active_scriptname = p_strdup(sctx->pool, scriptname); } } /* Is the requested script active? */ return (sctx->active_scriptname != NULL && strcmp(sctx->scriptname, sctx->active_scriptname) == 0); } static int sieve_storage_save_is_activating_default( struct sieve_storage_save_context *sctx) { struct sieve_storage *storage = sctx->storage; if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) != 0) return 0; if (!sieve_storage_save_will_activate(sctx)) return 0; struct sieve_storage *def_storage; enum sieve_error error_code; int ret = 0; if (sieve_storage_create_default_for(storage, &def_storage, &error_code, NULL) < 0) { if (error_code == SIEVE_ERROR_NOT_FOUND) return 0; return -1; } if (strcmp(sctx->scriptname, def_storage->script_name) == 0) { ret = sieve_storage_check_script_direct( storage, def_storage->script_name, &error_code); if (ret == 0 || (ret < 0 && error_code == SIEVE_ERROR_NOT_FOUND)) ret = 1; else if (ret > 0) ret = 0; } sieve_storage_unref(&def_storage); return ret; } int sieve_storage_save_commit(struct sieve_storage_save_context **_sctx) { struct sieve_storage_save_context *sctx = *_sctx; struct sieve_storage *storage; const char *scriptname; bool default_activate = FALSE; int ret; *_sctx = NULL; if (sctx == NULL) return 0; storage = sctx->storage; scriptname = sctx->scriptname; sieve_storage_clear_error(storage); i_assert(!sctx->failed); i_assert(sctx->finished); i_assert(sctx->scriptname != NULL); /* Check whether we're replacing the default active script */ ret = sieve_storage_save_is_activating_default(sctx); if (ret < 0) return -1; default_activate = (ret > 0); sieve_storage_save_cleanup(sctx); i_assert(storage->v.save_commit != NULL); ret = storage->v.save_commit(sctx); i_assert(ret >= 0 || (storage->error_code != SIEVE_ERROR_NONE && storage->error != NULL)); /* Implicitly activate it when we're replacing the default active script */ if (ret >= 0 && default_activate) { struct sieve_script *script; enum sieve_error error_code; if (sieve_storage_open_script(storage, scriptname, &script, &error_code) < 0) { /* Somehow not actually saved */ ret = (error_code == SIEVE_ERROR_NOT_FOUND ? 0 : -1); } else if (sieve_script_activate(script, (time_t)-1) < 0) { /* Failed to activate; roll back */ ret = -1; (void)sieve_script_delete(script, TRUE); } sieve_script_unref(&script); if (ret < 0) { e_error(sctx->event, "Failed to implicitly activate script '%s' " "while replacing the default active script", scriptname); } } if (ret >= 0) { struct event_passthrough *e = event_create_passthrough(sctx->event)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Finished saving script"); /* set INBOX mailbox attribute */ (void)sieve_storage_sync_script_save(storage, scriptname); } else { struct event_passthrough *e = event_create_passthrough(sctx->event)-> add_str("error", storage->error)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Failed to save script: %s", storage->error); } sieve_storage_save_deinit(&sctx); return ret; } void sieve_storage_save_cancel(struct sieve_storage_save_context **_sctx) { struct sieve_storage_save_context *sctx = *_sctx; struct sieve_storage *storage; *_sctx = NULL; if (sctx == NULL) return; storage = sctx->storage; sctx->failed = TRUE; sieve_storage_save_cleanup(sctx); if (!sctx->finished) (void)sieve_storage_save_finish(sctx); struct event_passthrough *e = event_create_passthrough(sctx->event)-> add_str("error", "Canceled")-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Canceled saving script"); i_assert(storage->v.save_cancel != NULL); storage->v.save_cancel(sctx); sieve_storage_save_deinit(&sctx); } int sieve_storage_save_as_active(struct sieve_storage *storage, struct istream *input, time_t mtime) { struct event *event; int ret; sieve_storage_clear_error(storage); event = event_create(storage->event); event_set_append_log_prefix(event, "active script: save: "); struct event_passthrough *e = event_create_passthrough(event)-> set_name("sieve_storage_save_started"); e_debug(e->event(), "Started saving active script"); i_assert(storage->v.save_as_active != NULL); ret = storage->v.save_as_active(storage, input, mtime); if (ret >= 0) { struct event_passthrough *e = event_create_passthrough(event)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Finished saving active script"); } else { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(event)-> add_str("error", storage->error)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Failed to save active script: %s", storage->error); } event_unref(&event); return ret; } int sieve_storage_save_as(struct sieve_storage *storage, struct istream *input, const char *name) { struct event *event; int ret; sieve_storage_clear_error(storage); event = sieve_storage_save_create_event(storage, name); struct event_passthrough *e = event_create_passthrough(event)-> set_name("sieve_storage_save_started"); e_debug(e->event(), "Started saving script"); i_assert(storage->v.save_as != NULL); ret = storage->v.save_as(storage, input, name); if (ret >= 0) { struct event_passthrough *e = event_create_passthrough(event)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Finished saving sieve script"); } else { i_assert(storage->error_code != SIEVE_ERROR_NONE); i_assert(storage->error != NULL); struct event_passthrough *e = event_create_passthrough(event)-> add_str("error", storage->error)-> set_name("sieve_storage_save_finished"); e_debug(e->event(), "Failed to save script: %s", storage->error); } event_unref(&event); return ret; } /* * Checking quota */ bool sieve_storage_quota_validsize(struct sieve_storage *storage, size_t size, uint64_t *limit_r) { uint64_t max_size; max_size = sieve_max_script_size(storage->svinst); if (max_size > 0 && size > max_size) { *limit_r = max_size; return FALSE; } return TRUE; } uint64_t sieve_storage_quota_max_script_size(struct sieve_storage *storage) { return sieve_max_script_size(storage->svinst); } int sieve_storage_quota_havespace(struct sieve_storage *storage, const char *scriptname, size_t size, enum sieve_storage_quota *quota_r, uint64_t *limit_r) { *quota_r = SIEVE_STORAGE_QUOTA_NONE; *limit_r = 0; /* Check the script size */ if (!sieve_storage_quota_validsize(storage, size, limit_r)) { *quota_r = SIEVE_STORAGE_QUOTA_MAXSIZE; return 0; } /* Do we need to scan the storage (quota enabled) ? */ if (storage->max_scripts == 0 && storage->max_storage == 0) return 1; if (storage->v.quota_havespace == NULL) return 1; return storage->v.quota_havespace(storage, scriptname, size, quota_r, limit_r); } /* * Properties */ const char *sieve_storage_name(const struct sieve_storage *storage) { return storage->name; } bool sieve_storage_is_default(const struct sieve_storage *storage) { return storage->is_default; } bool sieve_storage_is_personal(struct sieve_storage *storage) { return (strcasecmp(storage->type, SIEVE_STORAGE_TYPE_PERSONAL) == 0); } /* * Error handling */ void sieve_storage_clear_error(struct sieve_storage *storage) { i_free(storage->error); storage->error_code = SIEVE_ERROR_NONE; storage->error = NULL; } void sieve_storage_set_error(struct sieve_storage *storage, enum sieve_error error_code, const char *fmt, ...) { va_list va; sieve_storage_clear_error(storage); if (fmt != NULL) { va_start(va, fmt); storage->error = i_strdup_vprintf(fmt, va); va_end(va); } storage->error_code = error_code; } void sieve_storage_copy_error(struct sieve_storage *storage, const struct sieve_storage *source) { sieve_storage_clear_error(storage); storage->error = i_strdup(source->error); storage->error_code = source->error_code; } void sieve_storage_set_internal_error(struct sieve_storage *storage) { const char *error; sieve_storage_clear_error(storage); sieve_error_create_internal(&storage->error_code, &error); storage->error = i_strdup(error); } void sieve_storage_set_critical(struct sieve_storage *storage, const char *fmt, ...) { va_list va; if (fmt != NULL) { if ((storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0) { va_start(va, fmt); e_error(storage->svinst->event, "%s storage: %s", storage->driver_name, t_strdup_vprintf(fmt, va)); va_end(va); sieve_storage_set_internal_error(storage); } else { sieve_storage_clear_error(storage); /* no user is involved while synchronizing, so do it the normal way */ va_start(va, fmt); storage->error = i_strdup_vprintf(fmt, va); va_end(va); storage->error_code = SIEVE_ERROR_TEMP_FAILURE; } } } void sieve_storage_set_not_found_error(struct sieve_storage *storage, const char *name) { enum sieve_error error_code; const char *error; sieve_storage_clear_error(storage); name = (name == NULL || *name == '\0' ? storage->script_name : name); sieve_error_create_script_not_found(name, &error_code, &error); storage->error_code = error_code; storage->error = i_strdup(error); } const char * sieve_storage_get_last_error(struct sieve_storage *storage, enum sieve_error *error_code_r) { /* We get here only in error situations, so we have to return some error. If storage->error is NULL, it means we forgot to set it at some point.. */ if (error_code_r != NULL) *error_code_r = storage->error_code; return storage->error != NULL ? storage->error : "Unknown error"; } /* * Storage sequence */ int sieve_storage_sequence_create(struct sieve_instance *svinst, struct event *event_parent, const char *cause, const char *type, struct sieve_storage_sequence **sseq_r, enum sieve_error *error_code_r, const char **error_r) { const struct sieve_storage_settings *storage_set; const char *const *storage_names; unsigned int storage_count; const char *error; *sseq_r = NULL; sieve_error_args_init(&error_code_r, &error_r); if (settings_get(event_parent, &sieve_storage_setting_parser_info, SETTINGS_GET_FLAG_SORT_FILTER_ARRAYS, &storage_set, &error) < 0) { e_error(event_parent, "%s", error); sieve_error_create_internal(error_code_r, error_r); return -1; } if (array_is_created(&storage_set->storages)) storage_names = array_get(&storage_set->storages, &storage_count); else { storage_names = empty_str_array; storage_count = 0; } struct sieve_storage_sequence *sseq; sseq = i_new(struct sieve_storage_sequence, 1); sseq->svinst = svinst; sseq->cause = i_strdup(cause); sseq->type = i_strdup(type); sseq->storage_set = storage_set; sseq->storage_names = p_strarray_dup(default_pool, storage_names); sseq->storage_count = storage_count; sseq->event_parent = event_parent; event_ref(event_parent); *sseq_r = sseq; return 0; } int sieve_storage_sequence_next(struct sieve_storage_sequence *sseq, struct sieve_storage **storage_r, enum sieve_error *error_code_r, const char **error_r) { struct sieve_instance *svinst = sseq->svinst; int ret; *storage_r = NULL; sieve_error_args_init(&error_code_r, &error_r); while (sseq->storage_index < sseq->storage_count) { unsigned int index = sseq->storage_index++; ret = sieve_storage_init(svinst, sseq->event_parent, sseq->cause, sseq->type, sseq->storage_names[index], TRUE, 0, storage_r, error_code_r, error_r); if (ret < 0) { if (*error_code_r == SIEVE_ERROR_NOT_FOUND) { *error_code_r = SIEVE_ERROR_NONE; *error_r = NULL; continue; } return -1; } if (ret > 0) { i_assert(*storage_r != NULL); return 1; } } return 0; } void sieve_storage_sequence_free(struct sieve_storage_sequence **_sseq) { struct sieve_storage_sequence *sseq = *_sseq; if (sseq == NULL) return; *_sseq = NULL; event_unref(&sseq->event_parent); i_free(sseq->cause); i_free(sseq->type); settings_free(sseq->storage_set); i_free(sseq->storage_names); i_free(sseq); } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-parser.c0000644000175100001700000004111215100335616024215 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "istream.h" #include "failures.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-script.h" #include "sieve-lexer.h" #include "sieve-parser.h" #include "sieve-error.h" #include "sieve-ast.h" /* * Forward declarations */ static int sieve_parser_recover(struct sieve_parser *parser, enum sieve_token_type end_token); /* * Parser object */ struct sieve_parser { pool_t pool; bool valid; struct sieve_script *script; struct sieve_error_handler *ehandler; const struct sieve_lexer *lexer; struct sieve_ast *ast; }; struct sieve_parser * sieve_parser_create(struct sieve_script *script, struct sieve_error_handler *ehandler, enum sieve_error *error_code_r) { struct sieve_parser *parser; const struct sieve_lexer *lexer; lexer = sieve_lexer_create(script, ehandler, error_code_r); if (lexer != NULL) { pool_t pool = pool_alloconly_create("sieve_parser", 4096); parser = p_new(pool, struct sieve_parser, 1); parser->pool = pool; parser->valid = TRUE; parser->ehandler = ehandler; sieve_error_handler_ref(ehandler); parser->script = script; sieve_script_ref(script); parser->lexer = lexer; parser->ast = NULL; return parser; } return NULL; } void sieve_parser_free(struct sieve_parser **parser) { if ((*parser)->ast != NULL) sieve_ast_unref(&(*parser)->ast); sieve_lexer_free(&(*parser)->lexer); sieve_script_unref(&(*parser)->script); sieve_error_handler_unref(&(*parser)->ehandler); pool_unref(&(*parser)->pool); *parser = NULL; } /* * Internal error handling */ inline static void ATTR_FORMAT(4, 5) sieve_parser_error(struct sieve_parser *parser, const char *csrc_filename, unsigned int csrc_linenum, const char *fmt, ...) { struct sieve_error_params params = { .log_type = LOG_TYPE_ERROR, .csrc = { .filename = csrc_filename, .linenum = csrc_linenum, }, }; va_list args; va_start(args, fmt); /* Don't report a parse error if the lexer complained already */ if (sieve_lexer_token_type(parser->lexer) != STT_ERROR) { T_BEGIN { params.location = sieve_error_script_location( parser->script, sieve_lexer_token_line(parser->lexer)); sieve_logv(parser->ehandler, ¶ms, fmt, args); } T_END; } parser->valid = FALSE; va_end(args); } #define sieve_parser_error(parser, ...) \ sieve_parser_error(parser, __FILE__, __LINE__, __VA_ARGS__) /* * Sieve grammar parsing */ /* sieve_parse_arguments(): Parses both command arguments and sub-tests: arguments = *argument [test / test-list] argument = string-list / number / tag string = quoted-string / multi-line [[implicitly handled in lexer]] string-list = "[" string *("," string) "]" / string ;; if there is only a single string, the brackets are optional test-list = "(" test *("," test) ")" test = identifier arguments */ static int sieve_parse_arguments(struct sieve_parser *parser, struct sieve_ast_node *node, unsigned int depth) { const struct sieve_lexer *lexer = parser->lexer; struct sieve_ast_node *test = NULL; bool test_present = TRUE; bool arg_present = TRUE; int result = 1; /* Indicates whether the parser is in a defined, not necessarily error-free state */ /* Parse arguments */ while (arg_present && result > 0) { struct sieve_ast_argument *arg; if (!parser->valid && !sieve_errors_more_allowed(parser->ehandler)) { result = 0; break; } switch (sieve_lexer_token_type(lexer)) { /* String list */ case STT_LSQUARE: /* Create stinglist object */ arg = sieve_ast_argument_stringlist_create( node, sieve_lexer_token_line(parser->lexer)); if (arg == NULL) break; sieve_lexer_skip_token(lexer); if (sieve_lexer_token_type(lexer) == STT_STRING) { bool add_failed = FALSE; /* Add the string to the list */ if (!sieve_ast_stringlist_add( arg, sieve_lexer_token_str(lexer), sieve_lexer_token_line(parser->lexer))) add_failed = TRUE; sieve_lexer_skip_token(lexer); while (!add_failed && sieve_lexer_token_type(lexer) == STT_COMMA) { sieve_lexer_skip_token(lexer); /* Check parser status */ if (!parser->valid && !sieve_errors_more_allowed(parser->ehandler)) { result = sieve_parser_recover(parser, STT_RSQUARE); break; } if (sieve_lexer_token_type(lexer) == STT_STRING) { /* Add the string to the list */ if (!sieve_ast_stringlist_add( arg, sieve_lexer_token_str(lexer), sieve_lexer_token_line(parser->lexer))) add_failed = TRUE; sieve_lexer_skip_token(lexer); } else { sieve_parser_error(parser, "expecting string after ',' in string list, " "but found %s", sieve_lexer_token_description(lexer)); result = sieve_parser_recover(parser, STT_RSQUARE); break; } } if (add_failed) { sieve_parser_error(parser, "failed to accept more items in string list"); return -1; } } else { sieve_parser_error(parser, "expecting string after '[' in string list, " "but found %s", sieve_lexer_token_description(lexer)); result = sieve_parser_recover(parser, STT_RSQUARE); } /* Finish the string list */ if (sieve_lexer_token_type(lexer) == STT_RSQUARE) { sieve_lexer_skip_token(lexer); } else { sieve_parser_error(parser, "expecting ',' or end of string list ']', " "but found %s", sieve_lexer_token_description(lexer)); if ((result = sieve_parser_recover(parser, STT_RSQUARE)) > 0) sieve_lexer_skip_token(lexer); } break; /* Single string */ case STT_STRING: arg = sieve_ast_argument_string_create( node, sieve_lexer_token_str(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); break; /* Number */ case STT_NUMBER: arg = sieve_ast_argument_number_create( node, sieve_lexer_token_int(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); break; /* Tag */ case STT_TAG: arg = sieve_ast_argument_tag_create( node, sieve_lexer_token_ident(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); break; /* End of argument list, continue with tests */ default: arg_present = FALSE; break; } if (arg_present && arg == NULL) { sieve_parser_error(parser, "failed to accept more arguments for command '%s'", node->identifier); return -1; } if (sieve_ast_argument_count(node) > SIEVE_MAX_COMMAND_ARGUMENTS) { sieve_parser_error(parser, "too many arguments for command '%s'", node->identifier); return 0; } } if (result <= 0) return result; /* Defer recovery to caller */ /* --> [ test / test-list ] test-list = "(" test *("," test) ")" test = identifier arguments */ switch (sieve_lexer_token_type(lexer)) { /* Single test */ case STT_IDENTIFIER: if ((depth + 1) > SIEVE_MAX_TEST_NESTING) { sieve_parser_error(parser, "cannot nest tests deeper than %u levels", SIEVE_MAX_TEST_NESTING); return 0; } test = sieve_ast_test_create( node, sieve_lexer_token_ident(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); /* Theoretically, test can be NULL */ if (test == NULL) break; /* Parse test arguments, which may include more tests (recurse) */ if (sieve_parse_arguments(parser, test, depth + 1) <= 0) { return 0; /* Defer recovery to caller */ } break; /* Test list */ case STT_LBRACKET: sieve_lexer_skip_token(lexer); if (depth+1 > SIEVE_MAX_TEST_NESTING) { sieve_parser_error(parser, "cannot nest tests deeper than %u levels", SIEVE_MAX_TEST_NESTING); result = sieve_parser_recover(parser, STT_RBRACKET); if (result > 0) sieve_lexer_skip_token(lexer); return result; } node->test_list = TRUE; /* Test starts with identifier */ if (sieve_lexer_token_type(lexer) == STT_IDENTIFIER) { test = sieve_ast_test_create( node, sieve_lexer_token_ident(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); if (test == NULL) break; /* Parse test arguments, which may include more tests (recurse) */ if ((result = sieve_parse_arguments(parser, test, depth+1)) > 0) { /* More tests ? */ while (sieve_lexer_token_type(lexer) == STT_COMMA) { sieve_lexer_skip_token(lexer); /* Check parser status */ if (!parser->valid && !sieve_errors_more_allowed(parser->ehandler)) { result = sieve_parser_recover(parser, STT_RBRACKET); break; } /* Test starts with identifier */ if (sieve_lexer_token_type(lexer) == STT_IDENTIFIER) { test = sieve_ast_test_create( node, sieve_lexer_token_ident(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); if (test == NULL) break; /* Parse test arguments, which may include more tests (recurse) */ if ((result = sieve_parse_arguments(parser, test, depth+1)) <= 0) { if (result < 0) return result; result = sieve_parser_recover(parser, STT_RBRACKET); break; } } else { sieve_parser_error(parser, "expecting test identifier after ',' in test list, " "but found %s", sieve_lexer_token_description(lexer)); result = sieve_parser_recover(parser, STT_RBRACKET); break; } } if (test == NULL) break; } else { if (result < 0) return result; result = sieve_parser_recover(parser, STT_RBRACKET); } } else { sieve_parser_error(parser, "expecting test identifier after '(' in test list, " "but found %s", sieve_lexer_token_description(lexer)); result = sieve_parser_recover(parser, STT_RBRACKET); } /* The next token should be a ')', indicating the end of the test list --> previous sieve_parser_recover calls try to restore this situation after parse errors. */ if (sieve_lexer_token_type(lexer) == STT_RBRACKET) { sieve_lexer_skip_token(lexer); } else { sieve_parser_error(parser, "expecting ',' or end of test list ')', " "but found %s", sieve_lexer_token_description(lexer)); /* Recover function tries to make next token equal to ')'. If it succeeds we need to skip it. */ if ((result = sieve_parser_recover(parser, STT_RBRACKET)) > 0) sieve_lexer_skip_token(lexer); } break; default: /* Not an error: test / test-list is optional --> any errors are detected by the caller */ test_present = FALSE; break; } if (test_present && test == NULL) { sieve_parser_error(parser, "failed to accept more tests for command '%s'", node->identifier); return -1; } return result; } /* commands = *command command = identifier arguments ( ";" / block ) block = "{" commands "}" */ static int sieve_parse_commands(struct sieve_parser *parser, struct sieve_ast_node *block, unsigned int depth) { const struct sieve_lexer *lexer = parser->lexer; int result = 1; while (result > 0 && sieve_lexer_token_type(lexer) == STT_IDENTIFIER) { struct sieve_ast_node *command; /* Check parser status */ if (!parser->valid && !sieve_errors_more_allowed(parser->ehandler)) { result = sieve_parser_recover(parser, STT_SEMICOLON); break; } /* Create command node */ command = sieve_ast_command_create( block, sieve_lexer_token_ident(lexer), sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); if (command == NULL) { sieve_parser_error(parser, "failed to accept more commands inside the block of command '%s'", block->identifier); return -1; } result = sieve_parse_arguments(parser, command, 1); /* Check whether the command is properly terminated (i.e. with ; or a new block) */ if (result > 0 && sieve_lexer_token_type(lexer) != STT_SEMICOLON && sieve_lexer_token_type(lexer) != STT_LCURLY) { sieve_parser_error(parser, "expected end of command ';' or the beginning of a compound block '{', " "but found %s", sieve_lexer_token_description(lexer)); result = 0; } /* Try to recover from parse errors to reacquire a defined state */ if (result == 0) result = sieve_parser_recover(parser, STT_SEMICOLON); /* Don't bother to continue if we are not in a defined state */ if (result <= 0) return result; switch (sieve_lexer_token_type(lexer)) { /* End of the command */ case STT_SEMICOLON: sieve_lexer_skip_token(lexer); break; /* Command has a block {...} */ case STT_LCURLY: sieve_lexer_skip_token(lexer); /* Check current depth first */ if ((depth + 1) > SIEVE_MAX_BLOCK_NESTING) { sieve_parser_error(parser, "cannot nest command blocks deeper than %u levels", SIEVE_MAX_BLOCK_NESTING); result = sieve_parser_recover(parser, STT_RCURLY); if (result > 0) sieve_lexer_skip_token(lexer); break; } command->block = TRUE; if ((result = sieve_parse_commands(parser, command, depth + 1)) > 0) { if (sieve_lexer_token_type(lexer) != STT_RCURLY) { sieve_parser_error(parser, "expected end of compound block '}', " "but found %s", sieve_lexer_token_description(lexer)); result = sieve_parser_recover(parser, STT_RCURLY); } else { sieve_lexer_skip_token(lexer); } } else { if (result < 0) return result; if ((result = sieve_parser_recover(parser, STT_RCURLY)) > 0) sieve_lexer_skip_token(lexer); } break; default: /* Recovered previously, so this cannot happen */ i_unreached(); } } return result; } bool sieve_parser_run(struct sieve_parser *parser, struct sieve_ast **ast) { if (parser->ast != NULL) sieve_ast_unref(&parser->ast); /* Create AST object if none is provided */ if (*ast == NULL) *ast = sieve_ast_create(parser->script); else sieve_ast_ref(*ast); parser->ast = *ast; /* Scan first token */ sieve_lexer_skip_token(parser->lexer); /* Parse */ if (sieve_parse_commands(parser, sieve_ast_root(parser->ast), 1) > 0 && parser->valid) { /* Parsed right to EOF ? */ if (sieve_lexer_token_type(parser->lexer) != STT_EOF) { sieve_parser_error(parser, "unexpected %s found at (the presumed) end of file", sieve_lexer_token_description(parser->lexer)); parser->valid = FALSE; } } else { parser->valid = FALSE; } /* Clean up AST if parse failed */ if (!parser->valid) { parser->ast = NULL; sieve_ast_unref(ast); } return parser->valid; } /* Error recovery: To continue parsing after an error it is important to find the next parsible item in the stream. The recover function skips over the remaining garbage after an error. It tries to find the end of the failed syntax structure and takes nesting of structures into account. */ /* Assign useful names to priorities for readability */ enum sieve_grammatical_prio { SGP_BLOCK = 3, SGP_COMMAND = 2, SGP_TEST_LIST = 1, SGP_STRING_LIST = 0, SGP_OTHER = -1 }; static inline enum sieve_grammatical_prio __get_token_priority(enum sieve_token_type token) { switch (token) { case STT_LCURLY: case STT_RCURLY: return SGP_BLOCK; case STT_SEMICOLON: return SGP_COMMAND; case STT_LBRACKET: case STT_RBRACKET: return SGP_TEST_LIST; case STT_LSQUARE: case STT_RSQUARE: return SGP_STRING_LIST; default: break; } return SGP_OTHER; } static int sieve_parser_recover(struct sieve_parser *parser, enum sieve_token_type end_token) { /* The tokens that begin/end a specific block/command/list in order of ascending grammatical priority. */ static const enum sieve_token_type begin_tokens[4] = { STT_LSQUARE, STT_LBRACKET, STT_NONE, STT_LCURLY }; static const enum sieve_token_type end_tokens[4] = { STT_RSQUARE, STT_RBRACKET, STT_SEMICOLON, STT_RCURLY}; const struct sieve_lexer *lexer = parser->lexer; int nesting = 1; enum sieve_grammatical_prio end_priority = __get_token_priority(end_token); i_assert(end_priority != SGP_OTHER); while (sieve_lexer_token_type(lexer) != STT_EOF && __get_token_priority(sieve_lexer_token_type(lexer)) <= end_priority) { if (sieve_lexer_token_type(lexer) == begin_tokens[end_priority]) { nesting++; sieve_lexer_skip_token(lexer); continue; } if (sieve_lexer_token_type(lexer) == end_tokens[end_priority]) { nesting--; if (nesting == 0) { /* Next character is the end */ return 1; } } sieve_lexer_skip_token(lexer); } /* Special case: COMMAND */ if (end_token == STT_SEMICOLON && sieve_lexer_token_type(lexer) == STT_LCURLY) { return 1; } /* End not found before eof or end of surrounding grammatical structure */ return 0; } dovecot-pigeonhole-2.4.2/src/lib-sieve/cmd-keep.c0000644000175100001700000000442315100335616023301 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-dump.h" #include "sieve-message.h" #include "sieve-actions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-result.h" /* * Keep command * * Syntax: * keep */ static bool cmd_keep_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); const struct sieve_command_def cmd_keep = { .identifier = "keep", .type = SCT_COMMAND, .positional_args = 0, .subtests = 0, .block_allowed = FALSE, .block_required = FALSE, .generate = cmd_keep_generate }; /* * Keep operation */ static bool cmd_keep_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_keep_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation_def cmd_keep_operation = { .mnemonic = "KEEP", .code = SIEVE_OPERATION_KEEP, .dump = cmd_keep_operation_dump, .execute = cmd_keep_operation_execute }; /* * Code generation */ static bool cmd_keep_generate (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { /* Emit opcode */ sieve_operation_emit(cgenv->sblock, NULL, &cmd_keep_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, cmd, NULL); } /* * Code dump */ static bool cmd_keep_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "KEEP"); sieve_code_descend(denv); return ( sieve_action_opr_optional_dump(denv, address, NULL) == 0 ); } /* * Interpretation */ static int cmd_keep_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_side_effects_list *slist = NULL; int ret = 0; /* * Read data */ /* Optional operands (side effects only) */ if ( sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0 ) return ret; /* * Perform operation */ sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "keep action; store message in default mailbox"); /* Add keep action to result. */ if ( sieve_result_add_keep(renv, slist) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-binary-file.c0000644000175100001700000006344015100335616025132 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "mempool.h" #include "buffer.h" #include "hash.h" #include "array.h" #include "ostream.h" #include "eacces-error.h" #include "safe-mkstemp.h" #include "file-lock.h" #include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-script.h" #include "sieve-binary-private.h" #include #include #include #include /* * Macros */ #define SIEVE_BINARY_MAGIC 0xcafebabe #define SIEVE_BINARY_MAGIC_OTHER_ENDIAN 0xbebafeca #define SIEVE_BINARY_ALIGN(offset) \ (((offset) + 3) & ~3U) #define SIEVE_BINARY_ALIGN_PTR(ptr) \ ((void *)SIEVE_BINARY_ALIGN(((size_t) ptr))) #define SIEVE_BINARY_PRE_HDR_SIZE_MAJOR 1 #define SIEVE_BINARY_PRE_HDR_SIZE_MINOR 4 #define SIEVE_BINARY_PRE_HDR_SIZE_HDR_SIZE 12 /* * Header and record structures of the binary on disk */ struct sieve_binary_block_index { uint32_t id; uint32_t size; uint32_t offset; uint32_t ext_id; }; struct sieve_binary_block_header { uint32_t id; uint32_t size; }; /* * Utility */ static bool sieve_binary_can_update(struct sieve_binary *sbin) { const char *dirpath, *p; p = strrchr(sbin->path, '/'); if (p == NULL) dirpath = "."; else dirpath = t_strdup_until(sbin->path, p); return (access(dirpath, W_OK | X_OK) == 0); } /* * Header manipulation */ static int sieve_binary_file_read_header(struct sieve_binary *sbin, int fd, struct sieve_binary_header *header_r, enum sieve_error *error_code_r) { struct sieve_binary_header header; ssize_t rret; sieve_error_args_init(&error_code_r, NULL); rret = pread(fd, &header, sizeof(header), 0); if (rret == 0) { e_error(sbin->event, "read: " "file is not large enough to contain the header"); *error_code_r = SIEVE_ERROR_NOT_VALID; return -1; } else if (rret < 0) { e_error(sbin->event, "read: " "failed to read from binary: %m"); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } else if (rret != sizeof(header)) { e_error(sbin->event, "read: " "header read only partially %zd/%zu", rret, sizeof(header)); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } /* Check header validity */ if (header.magic != SIEVE_BINARY_MAGIC) { if (header.magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN) { e_error(sbin->event, "read: " "binary has corrupted header " "(0x%08x) or it is not a Sieve binary", header.magic); } else { e_error(sbin->event, "read: " "binary stored with in different endian format " "(automatically fixed when re-compiled)"); } *error_code_r = SIEVE_ERROR_NOT_VALID; return -1; } /* Check binary version */ if (header.version_major == SIEVE_BINARY_PRE_HDR_SIZE_MAJOR && header.version_minor == SIEVE_BINARY_PRE_HDR_SIZE_MINOR) { /* Old header without hdr_size; clear new fields */ static const size_t old_header_size = SIEVE_BINARY_PRE_HDR_SIZE_HDR_SIZE; memset(PTR_OFFSET(&header, old_header_size), 0, (sizeof(header) - old_header_size)); header.hdr_size = old_header_size; } else if (header.version_major != SIEVE_BINARY_VERSION_MAJOR) { /* Binary is of different major version. Caller will have to recompile */ bool important = (sbin->script == NULL || !sieve_binary_can_update(sbin)); enum log_type log_type = (important ? LOG_TYPE_ERROR : LOG_TYPE_DEBUG); e_log(sbin->event, log_type, "read: " "binary stored with different major version %d.%d " "(!= %d.%d; automatically fixed when re-compiled)", (int)header.version_major, (int)header.version_minor, SIEVE_BINARY_VERSION_MAJOR, SIEVE_BINARY_VERSION_MINOR); *error_code_r = SIEVE_ERROR_NOT_VALID; return -1; } else if (header.hdr_size < SIEVE_BINARY_BASE_HEADER_SIZE) { /* Header size is smaller than base size */ e_error(sbin->event, "read: " "binary is corrupt: header size is too small"); *error_code_r = SIEVE_ERROR_NOT_VALID; return -1; } /* Check block content */ if (header.blocks == 0) { e_error(sbin->event, "read: " "binary is corrupt: it contains no blocks"); *error_code_r = SIEVE_ERROR_NOT_VALID; return -1; } /* Valid */ *header_r = header; return 0; } static int sieve_binary_file_write_header(struct sieve_binary *sbin, int fd, struct sieve_binary_header *header, enum sieve_error *error_code_r) { ssize_t wret; wret = pwrite(fd, header, sizeof(*header), 0); if (wret < 0) { e_error(sbin->event, "update: " "failed to write to binary: %m"); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } else if (wret != sizeof(*header)) { e_error(sbin->event, "update: " "header written partially %zd/%zu", wret, sizeof(*header)); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } return 0; } static void sieve_binary_file_update_header(struct sieve_binary *sbin) { struct sieve_binary_header *header = &sbin->header; struct sieve_resource_usage rusage; sieve_binary_get_resource_usage(sbin, &rusage); i_zero(&header->resource_usage); if (HAS_ALL_BITS(header->flags, SIEVE_BINARY_FLAG_RESOURCE_LIMIT) || sieve_resource_usage_is_high(sbin->svinst, &rusage)) { header->resource_usage.update_time = ioloop_time; header->resource_usage.cpu_time_msecs = rusage.cpu_time_msecs; } sieve_resource_usage_init(&sbin->rusage); sbin->rusage_updated = FALSE; (void)sieve_binary_check_resource_usage(sbin); } /* * Saving the binary to a file. */ static inline bool _save_skip(struct sieve_binary *sbin, struct ostream *stream, size_t size) { if ((o_stream_seek(stream, stream->offset + size)) <= 0) { e_error(sbin->event, "save: " "failed to skip output stream to position " "%"PRIuUOFF_T": %s", stream->offset + size, strerror(stream->stream_errno)); return FALSE; } return TRUE; } static inline bool _save_skip_aligned(struct sieve_binary *sbin, struct ostream *stream, size_t size, uoff_t *offset) { uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset); if ((o_stream_seek(stream, aligned_offset + size)) <= 0) { e_error(sbin->event, "save: " "failed to skip output stream to position " "%"PRIuUOFF_T": %s", aligned_offset + size, strerror(stream->stream_errno)); return FALSE; } if (offset != NULL) *offset = aligned_offset; return TRUE; } /* FIXME: Is this even necessary for a file? */ static bool _save_full(struct sieve_binary *sbin, struct ostream *stream, const void *data, size_t size) { size_t bytes_left = size; const void *pdata = data; while (bytes_left > 0) { ssize_t ret; ret = o_stream_send(stream, pdata, bytes_left); if (ret <= 0) { e_error(sbin->event, "save: " "failed to write %zu bytes " "to output stream: %s", bytes_left, strerror(stream->stream_errno)); return FALSE; } pdata = PTR_OFFSET(pdata, ret); bytes_left -= ret; } return TRUE; } static bool _save_aligned(struct sieve_binary *sbin, struct ostream *stream, const void *data, size_t size, uoff_t *offset) { uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset); o_stream_cork(stream); /* Align the data by adding zeroes to the output stream */ if (stream->offset < aligned_offset) { if (!_save_skip(sbin, stream, (aligned_offset - stream->offset))) return FALSE; } if (!_save_full(sbin, stream, data, size)) return FALSE; o_stream_uncork(stream); if (offset != NULL) *offset = aligned_offset; return TRUE; } static bool _save_block(struct sieve_binary *sbin, struct ostream *stream, unsigned int id) { struct sieve_binary_block_header block_header; struct sieve_binary_block *block; const void *data; size_t size; block = sieve_binary_block_get(sbin, id); if (block == NULL) return FALSE; data = buffer_get_data(block->data, &size); block_header.id = id; block_header.size = size; if (!_save_aligned(sbin, stream, &block_header, sizeof(block_header), &block->offset)) return FALSE; return _save_aligned(sbin, stream, data, size, NULL); } static bool _save_block_index_record(struct sieve_binary *sbin, struct ostream *stream, unsigned int id) { struct sieve_binary_block *block; struct sieve_binary_block_index header; block = sieve_binary_block_get(sbin, id); if (block == NULL) return FALSE; header.id = id; header.size = buffer_get_used_size(block->data); header.ext_id = block->ext_index; header.offset = block->offset; if (!_save_full(sbin, stream, &header, sizeof(header))) { e_error(sbin->event, "save: " "failed to save block index header %d", id); return FALSE; } return TRUE; } static bool sieve_binary_save_to_stream(struct sieve_binary *sbin, struct ostream *stream) { struct sieve_binary_header *header = &sbin->header; struct sieve_binary_block *ext_block; unsigned int ext_count, blk_count, i; uoff_t block_index; blk_count = sieve_binary_block_count(sbin); /* Create header */ header->magic = SIEVE_BINARY_MAGIC; header->version_major = SIEVE_BINARY_VERSION_MAJOR; header->version_minor = SIEVE_BINARY_VERSION_MINOR; header->blocks = blk_count; header->hdr_size = sizeof(*header); header->flags &= ENUM_NEGATE(SIEVE_BINARY_FLAG_RESOURCE_LIMIT); sieve_binary_file_update_header(sbin); if (!_save_aligned(sbin, stream, header, sizeof(*header), NULL)) { e_error(sbin->event, "save: failed to save header"); return FALSE; } /* Skip block index for now */ if (!_save_skip_aligned( sbin, stream, (sizeof(struct sieve_binary_block_index) * blk_count), &block_index)) return FALSE; /* Create block containing all used extensions */ ext_block = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_EXTENSIONS); i_assert(ext_block != NULL); sieve_binary_block_clear(ext_block); ext_count = array_count(&sbin->linked_extensions); sieve_binary_emit_unsigned(ext_block, ext_count); for (i = 0; i < ext_count; i++) { struct sieve_binary_extension_reg *const *ext = array_idx(&sbin->linked_extensions, i); sieve_binary_emit_cstring( ext_block, sieve_extension_name((*ext)->extension)); sieve_binary_emit_unsigned( ext_block, sieve_extension_version((*ext)->extension)); sieve_binary_emit_unsigned(ext_block, (*ext)->block_id); } /* Save all blocks into the binary */ for (i = 0; i < blk_count; i++) { if (!_save_block(sbin, stream, i)) return FALSE; } /* Create the block index */ o_stream_seek(stream, block_index); for (i = 0; i < blk_count; i++) { if (!_save_block_index_record(sbin, stream, i)) return FALSE; } if (o_stream_finish(stream) <= 0) { e_error(sbin->event, "save: " "failed to finish output stream: %s", o_stream_get_error(stream)); return FALSE; } return TRUE; } static int sieve_binary_do_save(struct sieve_binary *sbin, const char *path, bool update, mode_t save_mode, enum sieve_error *error_code_r) { int result, fd; string_t *temp_path; struct ostream *stream; struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; sieve_error_args_init(&error_code_r, NULL); /* Check whether saving is necessary */ if (!update && sbin->path != NULL && strcmp(sbin->path, path) == 0) { e_debug(sbin->event, "save: " "not saving binary, because it is already stored"); return 0; } /* Open it as temp file first, as not to overwrite an existing just yet */ temp_path = t_str_new(256); str_append(temp_path, path); str_append_c(temp_path, '.'); fd = safe_mkstemp_hostpid(temp_path, save_mode, (uid_t)-1, (gid_t)-1); if (fd < 0) { if (errno == EACCES) { e_error(sbin->event, "save: " "failed to create temporary file: %s", eacces_error_get_creating("open", str_c(temp_path))); *error_code_r = SIEVE_ERROR_NO_PERMISSION; } else { e_error(sbin->event, "save: " "failed to create temporary file: " "open(%s) failed: %m", str_c(temp_path)); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; } return -1; } /* Signal all extensions that we're about to save the binary */ regs = array_get(&sbin->extensions, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_binary_extension *binext = regs[i]->binext; if (binext != NULL && binext->binary_pre_save != NULL && !binext->binary_pre_save(regs[i]->extension, sbin, regs[i]->context, error_code_r)) { i_assert(*error_code_r != SIEVE_ERROR_NONE); return -1; } } /* Save binary */ result = 1; stream = o_stream_create_fd(fd, 0); if (!sieve_binary_save_to_stream(sbin, stream)) { result = -1; *error_code_r = SIEVE_ERROR_TEMP_FAILURE; o_stream_ignore_last_errors(stream); } o_stream_destroy(&stream); /* Close saved binary */ if (close(fd) < 0) { e_error(sbin->event, "save: " "failed to close temporary file: " "close(fd=%s) failed: %m", str_c(temp_path)); } /* Replace any original binary atomically */ if (result > 0 && (rename(str_c(temp_path), path) < 0)) { if (errno == EACCES) { e_error(sbin->event, "save: " "failed to save binary: %s", eacces_error_get_creating("rename", path)); *error_code_r = SIEVE_ERROR_NO_PERMISSION; } else { e_error(sbin->event, "save: " "failed to save binary: " "rename(%s, %s) failed: %m", str_c(temp_path), path); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; } result = -1; } if (result < 0) { /* Get rid of temp output (if any) */ if (unlink(str_c(temp_path)) < 0 && errno != ENOENT) { e_error(sbin->event, "save: " "failed to clean up after error: " "unlink(%s) failed: %m", str_c(temp_path)); } } else { if (sbin->path == NULL) sbin->path = p_strdup(sbin->pool, path); /* Signal all extensions that we successfully saved the binary. */ regs = array_get(&sbin->extensions, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_binary_extension *binext = regs[i]->binext; if (binext != NULL && binext->binary_post_save != NULL && !binext->binary_post_save(regs[i]->extension, sbin, regs[i]->context, error_code_r)) { i_assert(*error_code_r != SIEVE_ERROR_NONE); result = -1; break; } } if (result < 0 && unlink(path) < 0 && errno != ENOENT) { e_error(sbin->event, "failed to clean up after error: " "unlink(%s) failed: %m", path); } } return result; } int sieve_binary_save(struct sieve_binary *sbin, const char *path, bool update, mode_t save_mode, enum sieve_error *error_code_r) { int ret; sieve_binary_update_event(sbin, path); ret = sieve_binary_do_save(sbin, path, update, save_mode, error_code_r); sieve_binary_update_event(sbin, NULL); return ret; } /* * Binary file management */ static int sieve_binary_fd_open(struct sieve_binary *sbin, const char *path, int open_flags, enum sieve_error *error_code_r) { int fd; fd = open(path, open_flags); if (fd < 0) { switch (errno) { case ENOENT: *error_code_r = SIEVE_ERROR_NOT_FOUND; break; case EACCES: e_error(sbin->event, "open: " "failed to open: %s", eacces_error_get("open", path)); *error_code_r = SIEVE_ERROR_NO_PERMISSION; break; default: e_error(sbin->event, "open: " "failed to open: open(%s) failed: %m", path); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; break; } return -1; } return fd; } static int sieve_binary_file_open(struct sieve_binary *sbin, const char *path, struct sieve_binary_file **file_r, enum sieve_error *error_code_r) { int fd, ret = 0; struct stat st; sieve_error_args_init(&error_code_r, NULL); fd = sieve_binary_fd_open(sbin, path, O_RDONLY, error_code_r); if (fd < 0) return -1; if (fstat(fd, &st) < 0) { if (errno == ENOENT) *error_code_r = SIEVE_ERROR_NOT_FOUND; else { e_error(sbin->event, "open: fstat(%s) failed: %m", path); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; } ret = -1; } if (ret == 0 && !S_ISREG(st.st_mode)) { e_error(sbin->event, "open: " "binary is not a regular file"); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; ret = -1; } if (ret < 0) { if (close(fd) < 0) { e_error(sbin->event, "open: " "close() failed after error: %m"); } return -1; } pool_t pool; struct sieve_binary_file *file; pool = pool_alloconly_create("sieve_binary_file", 4096); file = p_new(pool, struct sieve_binary_file, 1); file->pool = pool; file->path = p_strdup(pool, path); file->fd = fd; file->st = st; file->sbin = sbin; *file_r = file; return 0; } void sieve_binary_file_close(struct sieve_binary_file **_file) { struct sieve_binary_file *file = *_file; *_file = NULL; if (file == NULL) return; if (file->fd != -1) { if (close(file->fd) < 0) { e_error(file->sbin->event, "close: " "failed to close: close() failed: %m"); } } pool_unref(&file->pool); } static int sieve_binary_file_read(struct sieve_binary_file *file, off_t *offset, void *buffer, size_t size) { struct sieve_binary *sbin = file->sbin; int ret; void *indata = buffer; size_t insize = size; *offset = SIEVE_BINARY_ALIGN(*offset); /* Seek to the correct position */ if (*offset != file->offset && lseek(file->fd, *offset, SEEK_SET) == (off_t)-1) { e_error(sbin->event, "read: " "failed to seek(fd, %lld, SEEK_SET): %m", (long long) *offset); return -1; } /* Read record into memory */ while (insize > 0) { ret = read(file->fd, indata, insize); if (ret <= 0) { if (ret == 0) { e_error(sbin->event, "read: " "binary is truncated " "(more data expected)"); } else { e_error(sbin->event, "read: " "failed to read from binary: %m"); } break; } indata = PTR_OFFSET(indata, ret); insize -= ret; } if (insize != 0) { /* Failed to read the whole requested record */ return 0; } *offset += size; file->offset = *offset; return 1; } static const void * sieve_binary_file_load_data(struct sieve_binary_file *file, off_t *offset, size_t size) { void *data = t_malloc_no0(size); if (sieve_binary_file_read(file, offset, data, size) > 0) return data; return NULL; } static buffer_t * sieve_binary_file_load_buffer(struct sieve_binary_file *file, off_t *offset, size_t size) { buffer_t *buffer = buffer_create_dynamic(file->pool, size); if (sieve_binary_file_read(file, offset, buffer_get_space_unsafe(buffer, 0, size), size) > 0) return buffer; return NULL; } /* * Load binary from a file */ #define LOAD_HEADER(sbin, offset, header) \ (header *)sieve_binary_file_load_data(sbin->file, offset, \ sizeof(header)) bool sieve_binary_load_block(struct sieve_binary_block *sblock) { struct sieve_binary *sbin = sblock->sbin; unsigned int id = sblock->id; off_t offset = sblock->offset; const struct sieve_binary_block_header *header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_block_header); if (header == NULL) { e_error(sbin->event, "load: binary is corrupt: " "failed to read header of block %d", id); return FALSE; } if (header->id != id) { e_error(sbin->event, "load: binary is corrupt: " "header of block %d has non-matching id %d", id, header->id); return FALSE; } sblock->data = sieve_binary_file_load_buffer(sbin->file, &offset, header->size); if (sblock->data == NULL) { e_error(sbin->event, "load: " "failed to read block %d of binary (size=%d)", id, header->size); return FALSE; } return TRUE; } static bool _read_block_index_record(struct sieve_binary *sbin, off_t *offset, unsigned int id) { const struct sieve_binary_block_index *record = LOAD_HEADER(sbin, offset, const struct sieve_binary_block_index); struct sieve_binary_block *block; if (record == NULL) { e_error(sbin->event, "open: binary is corrupt: " "failed to load block index record %d", id); return FALSE; } if (record->id != id) { e_error(sbin->event, "open: binary is corrupt: " "block index record %d has unexpected id %d", id, record->id); return FALSE; } block = sieve_binary_block_create_id(sbin, id); block->ext_index = record->ext_id; block->offset = record->offset; return TRUE; } static int _read_extensions(struct sieve_binary_block *sblock) { struct sieve_binary *sbin = sblock->sbin; sieve_size_t offset = 0; unsigned int i, count; int result = 1; if (!sieve_binary_read_unsigned(sblock, &offset, &count)) return -1; for (i = 0; result > 0 && i < count; i++) { T_BEGIN { string_t *extension; const struct sieve_extension *ext; unsigned int version; if (sieve_binary_read_string(sblock, &offset, &extension)) { ext = sieve_extension_get_by_name( sbin->svinst, str_c(extension)); if (ext == NULL) { e_error(sbin->event, "open: " "binary requires unknown extension '%s'", str_sanitize(str_c(extension), 128)); result = 0; } else { struct sieve_binary_extension_reg *ereg = NULL; (void)sieve_binary_extension_register(sbin, ext, &ereg); if (!sieve_binary_read_unsigned(sblock, &offset, &version) || !sieve_binary_read_unsigned(sblock, &offset, &ereg->block_id)) { result = -1; } else if (!sieve_extension_version_is(ext, version)) { e_debug(sbin->event, "open: " "binary was compiled with different version " "of the '%s' extension (compiled v%d, expected v%d;" "automatically fixed when re-compiled)", sieve_extension_name(ext), version, sieve_extension_version(ext)); result = 0; } } } else { result = -1; } } T_END; } return result; } static bool _sieve_binary_open(struct sieve_binary *sbin, enum sieve_error *error_code_r) { bool result = TRUE; off_t offset = 0; struct sieve_binary_block *ext_block; unsigned int i; int ret; /* Read header */ ret = sieve_binary_file_read_header(sbin, sbin->file->fd, &sbin->header, error_code_r); if (ret < 0) return FALSE; offset = sbin->header.hdr_size; /* Load block index */ for (i = 0; i < sbin->header.blocks && result; i++) { T_BEGIN { if (!_read_block_index_record(sbin, &offset, i)) result = FALSE; } T_END; } if (!result) { *error_code_r = SIEVE_ERROR_NOT_VALID; return FALSE; } /* Load extensions used by this binary */ T_BEGIN { ext_block = sieve_binary_block_get( sbin, SBIN_SYSBLOCK_EXTENSIONS); if (ext_block == NULL) { result = FALSE; } else if ((ret = _read_extensions(ext_block)) <= 0) { if (ret < 0) { e_error(sbin->event, "open: binary is corrupt: " "failed to load extension block"); } result = FALSE; } } T_END; if (!result) { *error_code_r = SIEVE_ERROR_NOT_VALID; return FALSE; } return TRUE; } int sieve_binary_open(struct sieve_instance *svinst, const char *path, struct sieve_script *script, struct sieve_binary **sbin_r, enum sieve_error *error_code_r) { struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; struct sieve_binary *sbin; struct sieve_binary_file *file; i_assert(script == NULL || sieve_script_svinst(script) == svinst); *sbin_r = NULL; sieve_error_args_init(&error_code_r, NULL); /* Create binary object */ sbin = sieve_binary_create(svinst, script); sbin->path = p_strdup(sbin->pool, path); if (sieve_binary_file_open(sbin, path, &file, error_code_r) < 0) { sieve_binary_unref(&sbin); return -1; } sbin->file = file; event_set_append_log_prefix( sbin->event, t_strdup_printf("binary %s: ", path)); if (!_sieve_binary_open(sbin, error_code_r)) { sieve_binary_unref(&sbin); return -1; } sieve_binary_activate(sbin); /* Signal open event to extensions */ regs = array_get(&sbin->extensions, &ext_count); for (i = 0; i < ext_count; i++) { const struct sieve_binary_extension *binext = regs[i]->binext; if (binext != NULL && binext->binary_open != NULL && !binext->binary_open(regs[i]->extension, sbin, regs[i]->context)) { /* Extension thinks its corrupt */ *error_code_r = SIEVE_ERROR_NOT_VALID; sieve_binary_unref(&sbin); return -1; } } *sbin_r = sbin; return 0; } int sieve_binary_check_executable(struct sieve_binary *sbin, enum sieve_error *error_code_r, const char **client_error_r) { *client_error_r = NULL; sieve_error_args_init(&error_code_r, NULL); if (HAS_ALL_BITS(sbin->header.flags, SIEVE_BINARY_FLAG_RESOURCE_LIMIT)) { e_debug(sbin->event, "Binary execution is blocked: " "Cumulative resource usage limit exceeded " "(resource limit flag is set)"); *error_code_r = SIEVE_ERROR_RESOURCE_LIMIT; *client_error_r = "cumulative resource usage limit exceeded"; return 0; } return 1; } /* * Resource usage */ static int sieve_binary_file_do_update_resource_usage( struct sieve_binary *sbin, int fd, enum sieve_error *error_code_r) { struct sieve_binary_header *header = &sbin->header; struct file_lock *lock; const char *error; int ret; struct file_lock_settings lock_set = { .lock_method = FILE_LOCK_METHOD_FCNTL, }; ret = file_wait_lock(fd, sbin->path, F_WRLCK, &lock_set, SIEVE_BINARY_FILE_LOCK_TIMEOUT, &lock, &error); if (ret <= 0) { e_error(sbin->event, "%s", error); *error_code_r = SIEVE_ERROR_TEMP_FAILURE; return -1; } ret = sieve_binary_file_read_header(sbin, fd, header, error_code_r); if (ret == 0) { sieve_binary_file_update_header(sbin); ret = sieve_binary_file_write_header(sbin, fd, header, error_code_r); } file_lock_free(&lock); return ret; } int sieve_binary_file_update_resource_usage(struct sieve_binary *sbin, enum sieve_error *error_code_r) { int fd, ret = 0; sieve_error_args_init(&error_code_r, NULL); sieve_binary_file_close(&sbin->file); if (sbin->path == NULL) return 0; if (sbin->header.version_major != SIEVE_BINARY_VERSION_MAJOR) { return sieve_binary_save(sbin, sbin->path, TRUE, 0600, error_code_r); } fd = sieve_binary_fd_open(sbin, sbin->path, O_RDWR, error_code_r); if (fd < 0) { i_assert(*error_code_r != SIEVE_ERROR_NONE); return -1; } ret = sieve_binary_file_do_update_resource_usage(sbin, fd, error_code_r); i_assert(ret == 0 || *error_code_r != SIEVE_ERROR_NONE); if (close(fd) < 0) { e_error(sbin->event, "update: " "failed to close: close() failed: %m"); } return ret; } dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-ast.h0000644000175100001700000002637115100335616023527 0ustar00buildbotbuildbot00000000000000#ifndef SIEVE_AST_H #define SIEVE_AST_H #include "lib.h" #include "str.h" #include "sieve-common.h" #include "sieve-error.h" /* Abstract Syntax Tree (AST) structure: sieve_ast (root) [*command] | +-- command: | .... +-- command: | [identifier *argument *test *command] | +-- argument: | \--> as from root | | .... | | +-- argument: V (continued below) | | [number | tag | *string] | . . *test +-- test: | .... +-- test: | [identifier *argument *test] | +-- argument: \--> as from the top . | .... of this tree +-- argument: | [number | tag | *string] . Tests and commands are defined using the same structure: sieve_ast_node. However, arguments and string-lists are described using sieve_ast_argument. */ /* IMPORTANT NOTICE: Do not decorate the AST with objects other than those allocated on the ast's pool or static const objects. Otherwise it is possible that pointers in the tree become dangling which is highly undesirable. */ /* * Forward declarations */ struct sieve_ast_list; struct sieve_ast_arg_list; /* * Types */ enum sieve_ast_argument_type { SAAT_NONE, SAAT_NUMBER, SAAT_STRING, SAAT_STRING_LIST, SAAT_TAG, }; enum sieve_ast_type { SAT_NONE, SAT_ROOT, SAT_COMMAND, SAT_TEST, }; /* * AST Nodes */ /* Argument node */ struct sieve_ast_argument { enum sieve_ast_argument_type type; /* Back reference to the AST object */ struct sieve_ast *ast; /* List related */ struct sieve_ast_arg_list *list; struct sieve_ast_argument *next; struct sieve_ast_argument *prev; /* Parser-assigned data */ union { string_t *str; struct sieve_ast_arg_list *strlist; const char *tag; sieve_number_t number; } _value; unsigned int source_line; /* Assigned during validation */ /* Argument associated with this ast element */ struct sieve_argument *argument; /* Parameters to this (tag) argument */ struct sieve_ast_argument *parameters; }; struct sieve_ast_node { enum sieve_ast_type type; /* Back reference to the AST object */ struct sieve_ast *ast; /* Back reference to this node's parent */ struct sieve_ast_node *parent; /* Linked list references */ struct sieve_ast_list *list; struct sieve_ast_node *next; struct sieve_ast_node *prev; /* Commands (NULL if not allocated) */ bool block; struct sieve_ast_list *commands; /* Tests (NULL if not allocated)*/ bool test_list; struct sieve_ast_list *tests; /* Arguments (NULL if not allocated) */ struct sieve_ast_arg_list *arguments; /* Identifier of command or test */ const char *identifier; /* The location in the file where this command was started */ unsigned int source_line; /* Assigned during validation */ /* Context */ struct sieve_command *command; }; /* * AST node lists */ struct sieve_ast_list { struct sieve_ast_node *head; struct sieve_ast_node *tail; unsigned int len; }; struct sieve_ast_arg_list { struct sieve_ast_argument *head; struct sieve_ast_argument *tail; unsigned int len; }; /* * AST object */ struct sieve_ast; struct sieve_ast *sieve_ast_create(struct sieve_script *script); void sieve_ast_ref(struct sieve_ast *ast); void sieve_ast_unref(struct sieve_ast **ast); struct sieve_ast_node *sieve_ast_root(struct sieve_ast *ast); pool_t sieve_ast_pool(struct sieve_ast *ast); struct sieve_script *sieve_ast_script(struct sieve_ast *ast); /* Extension support */ struct sieve_ast_extension { const struct sieve_extension_def *ext; void (*free)(const struct sieve_extension *ext, struct sieve_ast *ast, void *context); }; void sieve_ast_extension_link(struct sieve_ast *ast, const struct sieve_extension *ext, bool required); const struct sieve_extension *const * sieve_ast_extensions_get(struct sieve_ast *ast, unsigned int *count_r); void sieve_ast_extension_register(struct sieve_ast *ast, const struct sieve_extension *ext, const struct sieve_ast_extension *ast_ext, void *context); void sieve_ast_extension_set_context(struct sieve_ast *ast, const struct sieve_extension *ext, void *context); void *sieve_ast_extension_get_context(struct sieve_ast *ast, const struct sieve_extension *ext); bool sieve_ast_extension_is_required(struct sieve_ast *ast, const struct sieve_extension *ext); /* * AST node manipulation */ /* Command nodes */ struct sieve_ast_node * sieve_ast_test_create(struct sieve_ast_node *parent, const char *identifier, unsigned int source_line); struct sieve_ast_node * sieve_ast_command_create(struct sieve_ast_node *parent, const char *identifier, unsigned int source_line); struct sieve_ast_node * sieve_ast_node_detach(struct sieve_ast_node *first); const char *sieve_ast_type_name(enum sieve_ast_type ast_type); /* Argument nodes */ struct sieve_ast_argument * sieve_ast_argument_create(struct sieve_ast *ast, unsigned int source_line); struct sieve_ast_arg_list *sieve_ast_arg_list_create(pool_t pool); bool sieve_ast_arg_list_add(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument); bool sieve_ast_arg_list_insert(struct sieve_ast_arg_list *list, struct sieve_ast_argument *before, struct sieve_ast_argument *argument); void sieve_ast_arg_list_substitute(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument, struct sieve_ast_argument *replacement); struct sieve_ast_argument * sieve_ast_argument_string_create_raw(struct sieve_ast *ast, string_t *str, unsigned int source_line); struct sieve_ast_argument * sieve_ast_argument_string_create(struct sieve_ast_node *node, const string_t *str, unsigned int source_line); struct sieve_ast_argument * sieve_ast_argument_cstring_create(struct sieve_ast_node *node, const char *str, unsigned int source_line); struct sieve_ast_argument * sieve_ast_argument_tag_create(struct sieve_ast_node *node, const char *tag, unsigned int source_line); struct sieve_ast_argument * sieve_ast_argument_number_create(struct sieve_ast_node *node, sieve_number_t number, unsigned int source_line); void sieve_ast_argument_string_set(struct sieve_ast_argument *argument, string_t *newstr); void sieve_ast_argument_string_setc(struct sieve_ast_argument *argument, const char *newstr); void sieve_ast_argument_number_set(struct sieve_ast_argument *argument, sieve_number_t newnum); void sieve_ast_argument_number_substitute(struct sieve_ast_argument *argument, sieve_number_t number); struct sieve_ast_argument * sieve_ast_argument_tag_insert(struct sieve_ast_argument *before, const char *tag, unsigned int source_line); struct sieve_ast_argument * sieve_ast_argument_stringlist_create(struct sieve_ast_node *node, unsigned int source_line); struct sieve_ast_argument * sieve_ast_argument_stringlist_substitute(struct sieve_ast_node *node, struct sieve_ast_argument *arg); struct sieve_ast_argument * sieve_ast_arguments_detach(struct sieve_ast_argument *first, unsigned int count); bool sieve_ast_argument_attach(struct sieve_ast_node *node, struct sieve_ast_argument *argument); const char *sieve_ast_argument_type_name(enum sieve_ast_argument_type arg_type); #define sieve_ast_argument_name(argument) \ sieve_ast_argument_type_name((argument)->type) bool sieve_ast_stringlist_add(struct sieve_ast_argument *list, const string_t *str, unsigned int source_line); bool sieve_ast_stringlist_add_strc(struct sieve_ast_argument *list, const char *str, unsigned int source_line); /* * Utility */ int sieve_ast_stringlist_map( struct sieve_ast_argument **listitem, void *context, int (*map_function)(void *context, struct sieve_ast_argument *arg)); struct sieve_ast_argument * sieve_ast_stringlist_join(struct sieve_ast_argument *list, struct sieve_ast_argument *items); /* * AST access macros */ /* Generic list access macros */ #define __AST_LIST_FIRST(list) \ ((list) == NULL ? NULL : (list)->head) #define __AST_LIST_LAST(list) \ ((list) == NULL ? NULL : (list)->tail) #define __AST_LIST_COUNT(list) \ ((list) == NULL || (list)->head == NULL ? 0 : (list)->len) #define __AST_LIST_NEXT(item) ((item)->next) #define __AST_LIST_PREV(item) ((item)->prev) #define __AST_NODE_LIST_FIRST(node, list) __AST_LIST_FIRST((node)->list) #define __AST_NODE_LIST_LAST(node, list) __AST_LIST_LAST((node)->list) #define __AST_NODE_LIST_COUNT(node, list) __AST_LIST_COUNT((node)->list) /* AST macros */ /* AST node macros */ #define sieve_ast_node_pool(node) (sieve_ast_pool((node)->ast)) #define sieve_ast_node_parent(node) ((node)->parent) #define sieve_ast_node_prev(node) __AST_LIST_PREV(node) #define sieve_ast_node_next(node) __AST_LIST_NEXT(node) #define sieve_ast_node_type(node) ((node) == NULL ? SAT_NONE : (node)->type) #define sieve_ast_node_line(node) ((node) == NULL ? 0 : (node)->source_line) /* AST command node macros */ #define sieve_ast_command_first(node) __AST_NODE_LIST_FIRST(node, commands) #define sieve_ast_command_count(node) __AST_NODE_LIST_COUNT(node, commands) #define sieve_ast_command_prev(command) __AST_LIST_PREV(command) #define sieve_ast_command_next(command) __AST_LIST_NEXT(command) /* Compare the identifier of the previous command */ #define sieve_ast_prev_cmd_is(cmd, id) \ ((cmd)->prev != NULL && \ str_begins_icase_with((cmd)->prev->identifier, id)) /* AST test macros */ #define sieve_ast_test_count(node) __AST_NODE_LIST_COUNT(node, tests) #define sieve_ast_test_first(node) __AST_NODE_LIST_FIRST(node, tests) #define sieve_ast_test_next(test) __AST_LIST_NEXT(test) /* AST argument macros */ #define sieve_ast_argument_pool(node) (sieve_ast_pool((node)->ast)) #define sieve_ast_argument_first(node) __AST_NODE_LIST_FIRST(node, arguments) #define sieve_ast_argument_last(node) __AST_NODE_LIST_LAST(node, arguments) #define sieve_ast_argument_count(node) __AST_NODE_LIST_COUNT(node, arguments) #define sieve_ast_argument_prev(argument) __AST_LIST_PREV(argument) #define sieve_ast_argument_next(argument) __AST_LIST_NEXT(argument) #define sieve_ast_argument_type(argument) (argument)->type #define sieve_ast_argument_line(argument) (argument)->source_line #define sieve_ast_argument_str(argument) ((argument)->_value.str) #define sieve_ast_argument_strc(argument) (str_c((argument)->_value.str)) #define sieve_ast_argument_tag(argument) ((argument)->_value.tag) #define sieve_ast_argument_number(argument) ((argument)->_value.number) /* AST string list macros */ // @UNSAFE: should check whether we are actually accessing a string list #define sieve_ast_strlist_first(list) \ __AST_NODE_LIST_FIRST(list, _value.strlist) #define sieve_ast_strlist_last(list) \ __AST_NODE_LIST_LAST(list, _value.strlist) #define sieve_ast_strlist_count(list) \ __AST_NODE_LIST_COUNT(list, _value.strlist) #define sieve_ast_strlist_next(str) __AST_LIST_NEXT(str) #define sieve_ast_strlist_prev(str) __AST_LIST_PREV(str) #define sieve_ast_strlist_str(str) sieve_ast_argument_str(str) #define sieve_ast_strlist_strc(str) sieve_ast_argument_strc(str) /* * Debug */ void sieve_ast_unparse(struct sieve_ast *ast); #endif dovecot-pigeonhole-2.4.2/src/lib-sieve/sieve-code.c0000644000175100001700000007344215100335616023646 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "str-sanitize.h" #include "sieve-common.h" #include "sieve-limits.h" #include "sieve-extensions.h" #include "sieve-stringlist.h" #include "sieve-actions.h" #include "sieve-binary.h" #include "sieve-generator.h" #include "sieve-interpreter.h" #include "sieve-dump.h" #include "sieve-code.h" #include /* * Code stringlist */ /* Forward declarations */ static int sieve_code_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r); static void sieve_code_stringlist_reset(struct sieve_stringlist *_strlist); static int sieve_code_stringlist_get_length(struct sieve_stringlist *_strlist); /* Coded stringlist object */ struct sieve_code_stringlist { struct sieve_stringlist strlist; sieve_size_t start_address; sieve_size_t end_address; sieve_size_t current_offset; int length; int index; }; static struct sieve_stringlist * sieve_code_stringlist_create(const struct sieve_runtime_env *renv, sieve_size_t start_address, unsigned int length, sieve_size_t end) { struct sieve_code_stringlist *strlist; if (end > sieve_binary_block_get_size(renv->sblock)) return NULL; strlist = t_new(struct sieve_code_stringlist, 1); strlist->strlist.runenv = renv; strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = sieve_code_stringlist_next_item; strlist->strlist.reset = sieve_code_stringlist_reset; strlist->strlist.get_length = sieve_code_stringlist_get_length; strlist->start_address = start_address; strlist->current_offset = start_address; strlist->end_address = end; strlist->length = length; strlist->index = 0; return &strlist->strlist; } /* Stringlist implementation */ static int sieve_code_stringlist_next_item(struct sieve_stringlist *_strlist, string_t **str_r) { struct sieve_code_stringlist *strlist = (struct sieve_code_stringlist *)_strlist; sieve_size_t address; *str_r = NULL; int ret; /* Check for end of list */ if (strlist->index >= strlist->length) return 0; /* Read next item */ address = strlist->current_offset; if ((ret = sieve_opr_string_read(_strlist->runenv, &address, NULL, str_r)) == SIEVE_EXEC_OK) { strlist->index++; strlist->current_offset = address; return 1; } _strlist->exec_status = ret; return -1; } static void sieve_code_stringlist_reset(struct sieve_stringlist *_strlist) { struct sieve_code_stringlist *strlist = (struct sieve_code_stringlist *)_strlist; strlist->current_offset = strlist->start_address; strlist->index = 0; } static int sieve_code_stringlist_get_length(struct sieve_stringlist *_strlist) { struct sieve_code_stringlist *strlist = (struct sieve_code_stringlist *)_strlist; return strlist->length; } static bool sieve_code_stringlist_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, unsigned int length, sieve_size_t end, const char *field_name) { unsigned int i; if (end > sieve_binary_block_get_size(denv->sblock)) return FALSE; if (field_name != NULL) { sieve_code_dumpf(denv, "%s: STRLIST [%u] (end: %08llx)", field_name, length, (unsigned long long)end); } else { sieve_code_dumpf(denv, "STRLIST [%u] (end: %08llx)", length, (unsigned long long)end); } sieve_code_descend(denv); for (i = 0; i < length; i++) { bool success = TRUE; T_BEGIN { success = sieve_opr_string_dump(denv, address, NULL); } T_END; if (!success || *address > end) return FALSE; } if (*address != end) return FALSE; sieve_code_ascend(denv); return TRUE; } /* * Core operands */ extern const struct sieve_operand_def comparator_operand; extern const struct sieve_operand_def match_type_operand; extern const struct sieve_operand_def address_part_operand; const struct sieve_operand_def *sieve_operands[] = { &omitted_operand, /* SIEVE_OPERAND_OPTIONAL */ &number_operand, &string_operand, &stringlist_operand, &comparator_operand, &match_type_operand, &address_part_operand, &catenated_string_operand }; const unsigned int sieve_operand_count = N_ELEMENTS(sieve_operands); /* * Operand functions */ sieve_size_t sieve_operand_emit(struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_operand_def *opr_def) { sieve_size_t address; if (ext != NULL) { address = sieve_binary_emit_extension( sblock, ext, sieve_operand_count); sieve_binary_emit_extension_object( sblock, &opr_def->ext_def->operands, opr_def->code); return address; } return sieve_binary_emit_byte(sblock, opr_def->code); } bool sieve_operand_read(struct sieve_binary_block *sblock, sieve_size_t *address, const char *field_name, struct sieve_operand *operand) { unsigned int code = sieve_operand_count; operand->address = *address; operand->field_name = field_name; operand->ext = NULL; operand->def = NULL; if (!sieve_binary_read_extension(sblock, address, &code, &operand->ext)) return FALSE; if (operand->ext == NULL) { if (code < sieve_operand_count) operand->def = sieve_operands[code]; return (operand->def != NULL); } if (operand->ext->def == NULL) return FALSE; operand->def = (const struct sieve_operand_def *) sieve_binary_read_extension_object( sblock, address, &operand->ext->def->operands); return (operand->def != NULL); } /* * Optional operand */ int sieve_opr_optional_next(struct sieve_binary_block *sblock, sieve_size_t *address, signed int *opt_code) { /* Start of optional operand block */ if (*opt_code == 0) { sieve_size_t tmp_addr = *address; unsigned int op; if (!sieve_binary_read_byte(sblock, &tmp_addr, &op) || op != SIEVE_OPERAND_OPTIONAL) return 0; *address = tmp_addr; } /* Read optional operand code */ if (!sieve_binary_read_code(sblock, address, opt_code)) return -1; /* Return 0 at end of list */ return (*opt_code != 0 ? 1 : 0); } /* * Operand definitions */ /* Omitted */ const struct sieve_operand_class omitted_class = { "OMITTED" }; const struct sieve_operand_def omitted_operand = { .name = "@OMITTED", .code = SIEVE_OPERAND_OPTIONAL, .class = &omitted_class }; /* Number */ static bool opr_number_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); static int opr_number_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, sieve_number_t *number_r); const struct sieve_opr_number_interface number_interface = { opr_number_dump, opr_number_read }; const struct sieve_operand_class number_class = { "number" }; const struct sieve_operand_def number_operand = { .name = "@number", .code = SIEVE_OPERAND_NUMBER, .class = &number_class, .interface = &number_interface }; /* String */ static bool opr_string_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); static int opr_string_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface string_interface ={ opr_string_dump, opr_string_read }; const struct sieve_operand_class string_class = { "string" }; const struct sieve_operand_def string_operand = { .name = "@string", .code = SIEVE_OPERAND_STRING, .class = &string_class, .interface = &string_interface }; /* String List */ static bool opr_stringlist_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address); static int opr_stringlist_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, struct sieve_stringlist **strlist_r); const struct sieve_opr_stringlist_interface stringlist_interface = { opr_stringlist_dump, opr_stringlist_read }; const struct sieve_operand_class stringlist_class = { "string-list" }; const struct sieve_operand_def stringlist_operand = { .name = "@string-list", .code = SIEVE_OPERAND_STRING_LIST, .class = &stringlist_class, .interface = &stringlist_interface }; /* Catenated String */ static bool opr_catenated_string_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, sieve_size_t *address); static int opr_catenated_string_read(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, sieve_size_t *address, string_t **str); const struct sieve_opr_string_interface catenated_string_interface = { opr_catenated_string_dump, opr_catenated_string_read }; const struct sieve_operand_def catenated_string_operand = { .name = "@catenated-string", .code = SIEVE_OPERAND_CATENATED_STRING, .class = &string_class, .interface = &catenated_string_interface }; /* * Operand implementations */ /* Omitted */ void sieve_opr_omitted_emit(struct sieve_binary_block *sblock) { (void)sieve_operand_emit(sblock, NULL, &omitted_operand); } /* Number */ void sieve_opr_number_emit(struct sieve_binary_block *sblock, sieve_number_t number) { (void)sieve_operand_emit(sblock, NULL, &number_operand); (void)sieve_binary_emit_integer(sblock, number); } bool sieve_opr_number_dump_data(const struct sieve_dumptime_env *denv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name) { const struct sieve_opr_number_interface *intf; oprnd->field_name = field_name; if (!sieve_operand_is_number(oprnd)) return FALSE; intf = (const struct sieve_opr_number_interface *)oprnd->def->interface; if (intf->dump == NULL) return FALSE; return intf->dump(denv, oprnd, address); } bool sieve_opr_number_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { struct sieve_operand operand; sieve_code_mark(denv); if (!sieve_operand_read(denv->sblock, address, field_name, &operand)) return FALSE; return sieve_opr_number_dump_data(denv, &operand, address, field_name); } int sieve_opr_number_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, sieve_number_t *number_r) { const struct sieve_opr_number_interface *intf; oprnd->field_name = field_name; if (!sieve_operand_is_number(oprnd)) { sieve_runtime_trace_operand_error( renv, oprnd, "expected number operand but found %s", sieve_operand_name(oprnd)); return SIEVE_EXEC_BIN_CORRUPT; } intf = (const struct sieve_opr_number_interface *)oprnd->def->interface; if (intf->read == NULL) { sieve_runtime_trace_operand_error( renv, oprnd, "number operand not implemented"); return SIEVE_EXEC_FAILURE; } return intf->read(renv, oprnd, address, number_r); } int sieve_opr_number_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, sieve_number_t *number_r) { struct sieve_operand operand; int ret; if ((ret = sieve_operand_runtime_read(renv, address, field_name, &operand)) <= 0) return ret; return sieve_opr_number_read_data(renv, &operand, address, field_name, number_r); } static bool opr_number_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { sieve_number_t number = 0; if (sieve_binary_read_integer(denv->sblock, address, &number)) { if (oprnd->field_name != NULL) { sieve_code_dumpf(denv, "%s: NUM %llu", oprnd->field_name, (unsigned long long)number); } else { sieve_code_dumpf(denv, "NUM %llu", (unsigned long long)number); } return TRUE; } return FALSE; } static int opr_number_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, sieve_number_t *number_r) { if (!sieve_binary_read_integer(renv->sblock, address, number_r)) { sieve_runtime_trace_operand_error( renv, oprnd, "invalid number operand"); return SIEVE_EXEC_BIN_CORRUPT; } return SIEVE_EXEC_OK; } /* String */ void sieve_opr_string_emit(struct sieve_binary_block *sblock, string_t *str) { (void)sieve_operand_emit(sblock, NULL, &string_operand); (void)sieve_binary_emit_string(sblock, str); } bool sieve_opr_string_dump_data(const struct sieve_dumptime_env *denv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name) { const struct sieve_opr_string_interface *intf; oprnd->field_name = field_name; if (!sieve_operand_is_string(oprnd)) { sieve_code_dumpf(denv, "ERROR: INVALID STRING OPERAND %s", sieve_operand_name(oprnd)); return FALSE; } intf = (const struct sieve_opr_string_interface *)oprnd->def->interface; if (intf->dump == NULL) { sieve_code_dumpf(denv, "ERROR: DUMP STRING OPERAND"); return FALSE; } return intf->dump(denv, oprnd, address); } bool sieve_opr_string_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { struct sieve_operand operand; sieve_code_mark(denv); if (!sieve_operand_read(denv->sblock, address, field_name, &operand)) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } return sieve_opr_string_dump_data(denv, &operand, address, field_name); } bool sieve_opr_string_dump_ex(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name, const char *omitted_value) { struct sieve_operand operand; sieve_code_mark(denv); if (!sieve_operand_read(denv->sblock, address, field_name, &operand)) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } if (omitted_value != NULL && sieve_operand_is_omitted(&operand)) { if (*omitted_value != '\0') { sieve_code_dumpf(denv, "%s: %s", field_name, omitted_value); } return TRUE; } return sieve_opr_string_dump_data(denv, &operand, address, field_name); } int sieve_opr_string_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, string_t **str_r) { const struct sieve_opr_string_interface *intf; oprnd->field_name = field_name; if (!sieve_operand_is_string(oprnd)) { sieve_runtime_trace_operand_error( renv, oprnd, "expected string operand but found %s", sieve_operand_name(oprnd)); return SIEVE_EXEC_BIN_CORRUPT; } intf = (const struct sieve_opr_string_interface *)oprnd->def->interface; if (intf->read == NULL) { sieve_runtime_trace_operand_error(renv, oprnd, "string operand not implemented"); return SIEVE_EXEC_FAILURE; } return intf->read(renv, oprnd, address, str_r); } int sieve_opr_string_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, string_t **str_r) { struct sieve_operand operand; int ret; if ((ret = sieve_operand_runtime_read(renv, address, field_name, &operand)) <= 0) return ret; return sieve_opr_string_read_data(renv, &operand, address, field_name, str_r); } int sieve_opr_string_read_ex(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, bool optional, string_t **str_r, bool *literal_r) { struct sieve_operand operand; int ret; if ((ret = sieve_operand_runtime_read(renv, address, field_name, &operand)) <= 0) return ret; if (optional && sieve_operand_is_omitted(&operand)) { *str_r = NULL; return 1; } if (literal_r != NULL) *literal_r = sieve_operand_is_string_literal(&operand); return sieve_opr_string_read_data(renv, &operand, address, field_name, str_r); } static void _dump_string(const struct sieve_dumptime_env *denv, string_t *str, const char *field_name) { if (str_len(str) > 80) { if (field_name != NULL) { sieve_code_dumpf(denv, "%s: STR[%ld] \"%s", field_name, (long)str_len(str), str_sanitize(str_c(str), 80)); } else { sieve_code_dumpf(denv, "STR[%ld] \"%s", (long)str_len(str), str_sanitize(str_c(str), 80)); } } else { if (field_name != NULL) { sieve_code_dumpf(denv, "%s: STR[%ld] \"%s\"", field_name, (long)str_len(str), str_sanitize(str_c(str), 80)); } else { sieve_code_dumpf(denv, "STR[%ld] \"%s\"", (long)str_len(str), str_sanitize(str_c(str), 80)); } } } bool opr_string_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { string_t *str; if (sieve_binary_read_string(denv->sblock, address, &str)) { _dump_string(denv, str, oprnd->field_name); return TRUE; } return FALSE; } static int opr_string_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r) { if (!sieve_binary_read_string(renv->sblock, address, str_r)) { sieve_runtime_trace_operand_error( renv, oprnd, "invalid string operand"); return SIEVE_EXEC_BIN_CORRUPT; } return SIEVE_EXEC_OK; } /* String list */ void sieve_opr_stringlist_emit_start(struct sieve_binary_block *sblock, unsigned int listlen, void **context) { sieve_size_t *end_offset = t_new(sieve_size_t, 1); /* Emit byte identifying the type of operand */ (void)sieve_operand_emit(sblock, NULL, &stringlist_operand); /* Give the interpreter an easy way to skip over this string list */ *end_offset = sieve_binary_emit_offset(sblock, 0); *context = end_offset; /* Emit the length of the list */ (void)sieve_binary_emit_unsigned(sblock, listlen); } void sieve_opr_stringlist_emit_item(struct sieve_binary_block *sblock, void *context ATTR_UNUSED, string_t *item) { (void)sieve_opr_string_emit(sblock, item); } void sieve_opr_stringlist_emit_end(struct sieve_binary_block *sblock, void *context) { sieve_size_t *end_offset = (sieve_size_t *)context; (void)sieve_binary_resolve_offset(sblock, *end_offset); } bool sieve_opr_stringlist_dump_data(const struct sieve_dumptime_env *denv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name) { if (oprnd == NULL || oprnd->def == NULL) return FALSE; oprnd->field_name = field_name; if (oprnd->def->class == &stringlist_class) { const struct sieve_opr_stringlist_interface *intf = (const struct sieve_opr_stringlist_interface *) oprnd->def->interface; if (intf->dump == NULL) return FALSE; return intf->dump(denv, oprnd, address); } else if (oprnd->def->class == &string_class) { const struct sieve_opr_string_interface *intf = (const struct sieve_opr_string_interface *) oprnd->def->interface; if (intf->dump == NULL) return FALSE; return intf->dump(denv, oprnd, address); } return FALSE; } bool sieve_opr_stringlist_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { struct sieve_operand operand; sieve_code_mark(denv); if (!sieve_operand_read(denv->sblock, address, field_name, &operand)) { return FALSE; } return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); } bool sieve_opr_stringlist_dump_ex(const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name, const char *omitted_value) { struct sieve_operand operand; sieve_code_mark(denv); if (!sieve_operand_read(denv->sblock, address, field_name, &operand)) return FALSE; if (omitted_value != NULL && sieve_operand_is_omitted(&operand)) { if (*omitted_value != '\0') { sieve_code_dumpf(denv, "%s: %s", field_name, omitted_value); } return TRUE; } return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); } int sieve_opr_stringlist_read_data(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, struct sieve_stringlist **strlist_r) { if (oprnd == NULL || oprnd->def == NULL) return SIEVE_EXEC_FAILURE; oprnd->field_name = field_name; if (oprnd->def->class == &stringlist_class) { const struct sieve_opr_stringlist_interface *intf = (const struct sieve_opr_stringlist_interface *) oprnd->def->interface; int ret; if (intf->read == NULL) { sieve_runtime_trace_operand_error( renv, oprnd, "stringlist operand not implemented"); return SIEVE_EXEC_FAILURE; } if ((ret = intf->read(renv, oprnd, address, strlist_r)) <= 0) return ret; return SIEVE_EXEC_OK; } else if (oprnd->def->class == &string_class) { /* Special case, accept single string as string list as well. */ const struct sieve_opr_string_interface *intf = (const struct sieve_opr_string_interface *) oprnd->def->interface; int ret; if (intf->read == NULL) { sieve_runtime_trace_operand_error( renv, oprnd, "stringlist string operand not implemented"); return SIEVE_EXEC_FAILURE; } if (strlist_r == NULL) { if ((ret = intf->read(renv, oprnd, address, NULL)) <= 0) return ret; } else { string_t *stritem; if ((ret = intf->read(renv, oprnd, address, &stritem)) <= 0) return ret; *strlist_r = sieve_single_stringlist_create( renv, stritem, FALSE); } return SIEVE_EXEC_OK; } sieve_runtime_trace_operand_error( renv, oprnd, "expected stringlist or string operand but found %s", sieve_operand_name(oprnd)); return SIEVE_EXEC_BIN_CORRUPT; } int sieve_opr_stringlist_read(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_stringlist **strlist_r) { struct sieve_operand operand; int ret; if ((ret = sieve_operand_runtime_read(renv, address, field_name, &operand)) <= 0) return ret; return sieve_opr_stringlist_read_data(renv, &operand, address, field_name, strlist_r); } int sieve_opr_stringlist_read_ex(const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, bool optional, struct sieve_stringlist **strlist_r) { struct sieve_operand operand; int ret; if ((ret = sieve_operand_runtime_read(renv, address, field_name, &operand)) <= 0) return ret; if (optional && sieve_operand_is_omitted(&operand)) { *strlist_r = NULL; return 1; } return sieve_opr_stringlist_read_data(renv, &operand, address, field_name, strlist_r); } static bool opr_stringlist_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { sieve_size_t pc = *address; sieve_size_t end; unsigned int length = 0; sieve_offset_t end_offset; if (!sieve_binary_read_offset(denv->sblock, address, &end_offset)) return FALSE; end = pc + end_offset; if (!sieve_binary_read_unsigned(denv->sblock, address, &length)) return FALSE; return sieve_code_stringlist_dump(denv, address, length, end, oprnd->field_name); } static int opr_stringlist_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, struct sieve_stringlist **strlist_r) { sieve_size_t pc = *address; sieve_size_t end; unsigned int length = 0; sieve_offset_t end_offset; if (!sieve_binary_read_offset(renv->sblock, address, &end_offset)) { sieve_runtime_trace_operand_error( renv, oprnd, "stringlist corrupt: invalid end offset"); return SIEVE_EXEC_BIN_CORRUPT; } end = pc + end_offset; if (!sieve_binary_read_unsigned(renv->sblock, address, &length)) { sieve_runtime_trace_operand_error( renv, oprnd, "stringlist corrupt: invalid length data"); return SIEVE_EXEC_BIN_CORRUPT; } if (strlist_r != NULL) { *strlist_r = sieve_code_stringlist_create( renv, *address, (unsigned int)length, end); } /* Skip over the string list for now */ *address = end; return SIEVE_EXEC_OK; } /* Catenated String */ void sieve_opr_catenated_string_emit(struct sieve_binary_block *sblock, unsigned int elements) { (void)sieve_operand_emit(sblock, NULL, &catenated_string_operand); (void)sieve_binary_emit_unsigned(sblock, elements); } static bool opr_catenated_string_dump(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) { unsigned int elements = 0; unsigned int i; if (!sieve_binary_read_unsigned(denv->sblock, address, &elements)) return FALSE; if (oprnd->field_name != NULL) { sieve_code_dumpf(denv, "%s: CAT-STR [%ld]:", oprnd->field_name, (long)elements); } else { sieve_code_dumpf(denv, "CAT-STR [%ld]:", (long)elements); } sieve_code_descend(denv); for (i = 0; i < (unsigned int)elements; i++) { if (!sieve_opr_string_dump(denv, address, NULL)) return FALSE; } sieve_code_ascend(denv); return TRUE; } static int opr_catenated_string_read(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str) { unsigned int elements = 0; unsigned int i; int ret; if (!sieve_binary_read_unsigned(renv->sblock, address, &elements)) { sieve_runtime_trace_operand_error( renv, oprnd, "catenated string corrupt: " "invalid element count data"); return SIEVE_EXEC_BIN_CORRUPT; } /* Parameter str can be NULL if we are requested to only skip and not actually read the argument. */ if (str == NULL) { for (i = 0; i < (unsigned int)elements; i++) { if ((ret = sieve_opr_string_read( renv, address, NULL, NULL)) <= 0) return ret; } } else { string_t *strelm; string_t **elm = &strelm; *str = t_str_new(128); for (i = 0; i < (unsigned int)elements; i++) { if ((ret = sieve_opr_string_read( renv, address, NULL, elm)) <= 0) return ret; if (elm != NULL) { str_append_str(*str, strelm); if (str_len(*str) > SIEVE_MAX_STRING_LEN) { str_truncate(*str, SIEVE_MAX_STRING_LEN); elm = NULL; } } } } return SIEVE_EXEC_OK; } /* * Core operations */ /* Forward declarations */ static bool opc_jmp_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address); static int opc_jmp_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); static int opc_jmptrue_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); static int opc_jmpfalse_execute(const struct sieve_runtime_env *renv, sieve_size_t *address); /* Operation objects defined in this file */ const struct sieve_operation_def sieve_jmp_operation = { .mnemonic = "JMP", .code = SIEVE_OPERATION_JMP, .dump = opc_jmp_dump, .execute = opc_jmp_execute }; const struct sieve_operation_def sieve_jmptrue_operation = { .mnemonic = "JMPTRUE", .code = SIEVE_OPERATION_JMPTRUE, .dump = opc_jmp_dump, .execute = opc_jmptrue_execute }; const struct sieve_operation_def sieve_jmpfalse_operation = { .mnemonic = "JMPFALSE", .code = SIEVE_OPERATION_JMPFALSE, .dump = opc_jmp_dump, .execute = opc_jmpfalse_execute }; /* Operation objects defined in other files */ extern const struct sieve_operation_def cmd_stop_operation; extern const struct sieve_operation_def cmd_keep_operation; extern const struct sieve_operation_def cmd_discard_operation; extern const struct sieve_operation_def cmd_redirect_operation; extern const struct sieve_operation_def tst_address_operation; extern const struct sieve_operation_def tst_header_operation; extern const struct sieve_operation_def tst_exists_operation; extern const struct sieve_operation_def tst_size_over_operation; extern const struct sieve_operation_def tst_size_under_operation; const struct sieve_operation_def *sieve_operations[] = { NULL, &sieve_jmp_operation, &sieve_jmptrue_operation, &sieve_jmpfalse_operation, &cmd_stop_operation, &cmd_keep_operation, &cmd_discard_operation, &cmd_redirect_operation, &tst_address_operation, &tst_header_operation, &tst_exists_operation, &tst_size_over_operation, &tst_size_under_operation }; const unsigned int sieve_operation_count = N_ELEMENTS(sieve_operations); /* * Operation functions */ sieve_size_t sieve_operation_emit(struct sieve_binary_block *sblock, const struct sieve_extension *ext, const struct sieve_operation_def *op_def) { sieve_size_t address; if (ext != NULL) { i_assert(op_def->ext_def != NULL); address = sieve_binary_emit_extension( sblock, ext, sieve_operation_count); sieve_binary_emit_extension_object( sblock, &op_def->ext_def->operations, op_def->code); return address; } i_assert(op_def->ext_def == NULL); return sieve_binary_emit_byte(sblock, op_def->code); } bool sieve_operation_read(struct sieve_binary_block *sblock, sieve_size_t *address, struct sieve_operation *oprtn) { unsigned int code = sieve_operation_count; oprtn->address = *address; oprtn->def = NULL; oprtn->ext = NULL; if (!sieve_binary_read_extension(sblock, address, &code, &oprtn->ext)) return FALSE; if (oprtn->ext == NULL) { if (code < sieve_operation_count) oprtn->def = sieve_operations[code]; return (oprtn->def != NULL); } oprtn->def = (const struct sieve_operation_def *) sieve_binary_read_extension_object( sblock, address, &oprtn->ext->def->operations); return (oprtn->def != NULL); } /* * Jump operations */ /* Code dump */ static bool opc_jmp_dump(const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct sieve_operation *oprtn = denv->oprtn; unsigned int pc = *address; sieve_offset_t offset; if (sieve_binary_read_offset(denv->sblock, address, &offset)) { sieve_code_dumpf(denv, "%s %d [%08x]", sieve_operation_mnemonic(oprtn), offset, pc + offset); } else { return FALSE; } return TRUE; } /* Code execution */ static int opc_jmp_execute(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { return sieve_interpreter_program_jump(renv->interp, TRUE, FALSE); } static int opc_jmptrue_execute(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { bool result = sieve_interpreter_get_test_result(renv->interp); sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is true"); sieve_runtime_trace_descend(renv); return sieve_interpreter_program_jump(renv->interp, result, FALSE); } static int opc_jmpfalse_execute(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { bool result = sieve_interpreter_get_test_result(renv->interp); sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is false"); sieve_runtime_trace_descend(renv); return sieve_interpreter_program_jump(renv->interp, !result, FALSE); } dovecot-pigeonhole-2.4.2/src/Makefile.am0000644000175100001700000000042515100335616021623 0ustar00buildbotbuildbot00000000000000 sieve_subdirs = \ lib-sieve \ lib-managesieve \ plugins \ lib-sieve-tool \ sieve-tools \ testsuite if BUILD_MANAGESIEVE managesieve_subdirs = \ managesieve \ managesieve-login else managesieve_subdirs = endif SUBDIRS = \ $(sieve_subdirs) \ $(managesieve_subdirs) dovecot-pigeonhole-2.4.2/src/managesieve/0000755000175100001700000000000015100335671022053 5ustar00buildbotbuildbot00000000000000dovecot-pigeonhole-2.4.2/src/managesieve/cmd-getscript.c0000644000175100001700000001000215100335616024754 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "ostream.h" #include "istream.h" #include "iostream.h" #include "sieve-script.h" #include "sieve-storage.h" #include "managesieve-common.h" #include "managesieve-commands.h" struct cmd_getscript_context { struct client *client; struct client_command_context *cmd; struct sieve_storage *storage; uoff_t script_size; const char *scriptname; struct sieve_script *script; struct istream *script_stream; bool failed:1; }; static bool cmd_getscript_finish(struct cmd_getscript_context *ctx) { struct client_command_context *cmd = ctx->cmd; struct client *client = ctx->client; sieve_script_unref(&ctx->script); if (ctx->failed) { if (client->output->closed) { client_disconnect(client, NULL); return TRUE; } client_command_storage_error( cmd, "Failed to retrieve script '%s'", ctx->scriptname); return TRUE; } client->get_count++; client->get_bytes += ctx->script_size; struct event_passthrough *e = client_command_create_finish_event(cmd)-> add_int("script_size", ctx->script_size); e_debug(e->event(), "Retrieved script '%s'", ctx->scriptname); client_send_line(client, ""); client_send_ok(client, "Getscript completed."); return TRUE; } static bool cmd_getscript_continue(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_getscript_context *ctx = cmd->context; switch (o_stream_send_istream(client->output, ctx->script_stream)) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: if (ctx->script_stream->v_offset != ctx->script_size && !ctx->failed) { /* Input stream gave less data than expected */ sieve_storage_set_critical( ctx->storage, "GETSCRIPT for script '%s' " "got too little data: " "%"PRIuUOFF_T" vs %"PRIuUOFF_T, sieve_script_label(ctx->script), ctx->script_stream->v_offset, ctx->script_size); client_disconnect(ctx->client, "GETSCRIPT failed"); ctx->failed = TRUE; } break; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: i_unreached(); case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: return FALSE; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: sieve_storage_set_critical(ctx->storage, "o_stream_send_istream() failed for script '%s': " "%s", sieve_script_label(ctx->script), i_stream_get_error(ctx->script_stream)); ctx->failed = TRUE; break; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: client_disconnect(ctx->client, NULL); ctx->failed = TRUE; break; } return cmd_getscript_finish(ctx); } bool cmd_getscript(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_getscript_context *ctx; const char *scriptname; enum sieve_error error_code; /* */ if (!client_read_string_args(cmd, TRUE, 1, &scriptname)) return FALSE; event_add_str(cmd->event, "script_name", scriptname); ctx = p_new(cmd->pool, struct cmd_getscript_context, 1); ctx->cmd = cmd; ctx->client = client; ctx->scriptname = p_strdup(cmd->pool, scriptname); ctx->storage = client->storage; ctx->failed = FALSE; if (sieve_storage_open_script(client->storage, scriptname, &ctx->script, NULL) < 0) { ctx->failed = TRUE; return cmd_getscript_finish(ctx); } if (sieve_script_get_stream(ctx->script, &ctx->script_stream, &error_code) < 0) { if (error_code == SIEVE_ERROR_NOT_FOUND) { sieve_storage_set_error(client->storage, error_code, "Script does not exist."); } ctx->failed = TRUE; return cmd_getscript_finish(ctx); } if (sieve_script_get_size(ctx->script, &ctx->script_size) <= 0) { sieve_storage_set_critical(ctx->storage, "failed to obtain script size for script '%s'", sieve_script_label(ctx->script)); ctx->failed = TRUE; return cmd_getscript_finish(ctx); } i_assert(ctx->script_stream->v_offset == 0); client_send_line(client, t_strdup_printf("{%"PRIuUOFF_T"}", ctx->script_size)); client->command_pending = TRUE; cmd->func = cmd_getscript_continue; cmd->context = ctx; return cmd_getscript_continue(cmd); } dovecot-pigeonhole-2.4.2/src/managesieve/managesieve-settings.h0000644000175100001700000000126515100335616026351 0ustar00buildbotbuildbot00000000000000#ifndef MANAGESIEVE_SETTINGS_H #define MANAGESIEVE_SETTINGS_H struct mail_user_settings; /* */ enum managesieve_client_workarounds { WORKAROUND_NONE = 0x00 }; /* */ struct managesieve_settings { pool_t pool; bool verbose_proctitle; const char *rawlog_dir; /* managesieve: */ uoff_t managesieve_max_line_length; const char *managesieve_implementation_string; ARRAY_TYPE(const_string) managesieve_client_workarounds; const char *managesieve_logout_format; unsigned int managesieve_max_compile_errors; enum managesieve_client_workarounds parsed_workarounds; }; extern const struct setting_parser_info managesieve_setting_parser_info; #endif dovecot-pigeonhole-2.4.2/src/managesieve/managesieve-commands.c0000644000175100001700000000503315100335616026302 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "managesieve-common.h" #include "managesieve-commands.h" /* May want to combine this somewhere in a commands-common.c to avoid duplicate code */ static const struct command managesieve_base_commands[] = { { "CAPABILITY", cmd_capability }, { "LOGOUT", cmd_logout }, { "PUTSCRIPT", cmd_putscript }, { "CHECKSCRIPT", cmd_checkscript }, { "GETSCRIPT", cmd_getscript }, { "SETACTIVE", cmd_setactive }, { "DELETESCRIPT", cmd_deletescript }, { "LISTSCRIPTS", cmd_listscripts }, { "HAVESPACE", cmd_havespace }, { "RENAMESCRIPT", cmd_renamescript }, { "NOOP", cmd_noop } }; #define MANAGESIEVE_COMMANDS_COUNT N_ELEMENTS(managesieve_base_commands) static ARRAY(struct command) managesieve_commands; static bool commands_unsorted; void command_register(const char *name, command_func_t *func) { struct command cmd; i_zero(&cmd); cmd.name = name; cmd.func = func; array_append(&managesieve_commands, &cmd, 1); commands_unsorted = TRUE; } void command_unregister(const char *name) { const struct command *cmd; unsigned int i, count; cmd = array_get(&managesieve_commands, &count); for (i = 0; i < count; i++) { if (strcasecmp(cmd[i].name, name) == 0) { array_delete(&managesieve_commands, i, 1); return; } } i_error("Trying to unregister unknown command '%s'", name); } void command_register_array(const struct command *cmdarr, unsigned int count) { commands_unsorted = TRUE; array_append(&managesieve_commands, cmdarr, count); } void command_unregister_array(const struct command *cmdarr, unsigned int count) { while (count > 0) { command_unregister(cmdarr->name); count--; cmdarr++; } } static int command_cmp(const struct command *c1, const struct command *c2) { return strcasecmp(c1->name, c2->name); } static int command_search(const char *name, const struct command *cmd) { return strcasecmp(name, cmd->name); } const struct command *command_find(const char *name) { if (commands_unsorted) { array_sort(&managesieve_commands, command_cmp); commands_unsorted = FALSE; } return array_bsearch_modifiable(&managesieve_commands, name, command_search); } void commands_init(void) { i_array_init(&managesieve_commands, 16); commands_unsorted = FALSE; command_register_array(managesieve_base_commands, MANAGESIEVE_COMMANDS_COUNT); } void commands_deinit(void) { command_unregister_array(managesieve_base_commands, MANAGESIEVE_COMMANDS_COUNT); array_free(&managesieve_commands); } dovecot-pigeonhole-2.4.2/src/managesieve/Makefile.am0000644000175100001700000000254615100335616024115 0ustar00buildbotbuildbot00000000000000settingsdir = $(dovecot_moduledir)/settings dovecot_pkglibexec_PROGRAMS = managesieve AM_CPPFLAGS = \ $(LIBDOVECOT_INCLUDE) \ $(LIBDOVECOT_SERVICE_INCLUDE) \ -DMODULEDIR=\""$(dovecot_moduledir)"\" \ -I$(top_srcdir) \ -I$(top_srcdir)/src/lib-sieve \ -I$(top_srcdir)/src/lib-managesieve libmanagesieve_settings_la_LDFLAGS = -module -avoid-version settings_LTLIBRARIES = \ libmanagesieve_settings.la libmanagesieve_settings_la_SOURCES = \ managesieve-settings.c libs = \ managesieve-settings.lo \ $(top_builddir)/src/lib-managesieve/libdovecot-managesieve.la \ $(top_builddir)/src/lib-sieve/libdovecot-sieve.la managesieve_CPPFLAGS = $(AM_CPPFLAGS) $(BINARY_CFLAGS) managesieve_LDFLAGS = -export-dynamic $(BINARY_LDFLAGS) managesieve_LDADD = $(libs) $(LIBDOVECOT_STORAGE) $(LIBDOVECOT_LDA) $(LIBDOVECOT) managesieve_DEPENDENCIES = $(libs) $(LIBDOVECOT_STORAGE_DEPS) $(LIBDOVECOT_LDA_DEPS) $(LIBDOVECOT_DEPS) cmds = \ cmd-capability.c \ cmd-logout.c \ cmd-putscript.c \ cmd-getscript.c \ cmd-setactive.c \ cmd-deletescript.c \ cmd-listscripts.c \ cmd-havespace.c \ cmd-renamescript.c \ cmd-noop.c managesieve_SOURCES = \ $(cmds) \ managesieve-quota.c \ managesieve-client.c \ managesieve-commands.c \ main.c noinst_HEADERS = \ managesieve-quota.h \ managesieve-client.h \ managesieve-commands.h \ managesieve-settings.h \ managesieve-common.h dovecot-pigeonhole-2.4.2/src/managesieve/managesieve-commands.h0000644000175100001700000000303515100335616026307 0ustar00buildbotbuildbot00000000000000#ifndef MANAGESIEVE_COMMANDS_H #define MANAGESIEVE_COMMANDS_H struct client_command_context; #include "managesieve-parser.h" typedef bool command_func_t(struct client_command_context *cmd); struct command { const char *name; command_func_t *func; }; /* Register command. Given name parameter must be permanently stored until command is unregistered. */ void command_register(const char *name, command_func_t *func); void command_unregister(const char *name); /* Register array of commands. */ void command_register_array(const struct command *cmdarr, unsigned int count); void command_unregister_array(const struct command *cmdarr, unsigned int count); const struct command *command_find(const char *name); void commands_init(void); void commands_deinit(void); /* MANAGESIEVE commands: */ /* Non-Authenticated State */ extern bool cmd_logout(struct client_command_context *cmd); extern bool cmd_capability(struct client_command_context *cmd); extern bool cmd_noop(struct client_command_context *cmd); /* Authenticated State */ extern bool cmd_putscript(struct client_command_context *cmd); extern bool cmd_checkscript(struct client_command_context *cmd); extern bool cmd_getscript(struct client_command_context *cmd); extern bool cmd_setactive(struct client_command_context *cmd); extern bool cmd_deletescript(struct client_command_context *cmd); extern bool cmd_listscripts(struct client_command_context *cmd); extern bool cmd_havespace(struct client_command_context *cmd); extern bool cmd_renamescript(struct client_command_context *cmd); #endif dovecot-pigeonhole-2.4.2/src/managesieve/cmd-putscript.c0000644000175100001700000003563515100335616025030 0ustar00buildbotbuildbot00000000000000/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file */ /* NOTE: this file also contains the checkscript command due to its obvious similarities. */ #include "lib.h" #include "ioloop.h" #include "istream.h" #include "ostream.h" #include "iostream.h" #include "str.h" #include "sieve.h" #include "sieve-script.h" #include "sieve-storage.h" #include "managesieve-parser.h" #include "managesieve-common.h" #include "managesieve-client.h" #include "managesieve-commands.h" #include "managesieve-quota.h" #include struct cmd_putscript_context { struct client *client; struct client_command_context *cmd; struct sieve_storage *storage; struct istream *input; const char *scriptname; uoff_t script_size, max_script_size; struct managesieve_parser *save_parser; struct sieve_storage_save_context *save_ctx; bool script_size_valid:1; }; static void cmd_putscript_finish(struct cmd_putscript_context *ctx); static bool cmd_putscript_continue_script(struct client_command_context *cmd); static void client_input_putscript(struct client *client) { struct client_command_context *cmd = &client->cmd; i_assert(!client->destroyed); client->last_input = ioloop_time; timeout_reset(client->to_idle); switch (i_stream_read(client->input)) { case -1: /* Disconnected */ cmd_putscript_finish(cmd->context); /* Reset command so that client_destroy() doesn't try to call cmd_putscript_continue_script() anymore. */ _client_reset_command(client); client_destroy(client, "Disconnected in PUTSCRIPT/CHECKSCRIPT"); return; case -2: cmd_putscript_finish(cmd->context); if (client->command_pending) { /* Uploaded script data, this is handled internally by mailbox_save_continue() */ break; } /* Parameter word is longer than max. input buffer size. This is most likely an error, so skip the new data until newline is found. */ client->input_skip_line = TRUE; client_send_command_error(cmd, "Too long argument."); cmd->param_error = TRUE; _client_reset_command(client); return; } if (cmd->func(cmd)) { /* Command execution was finished. Note that if cmd_sync() didn't finish, we didn't get here but the input handler has already been moved. So don't do anything important here.. Reset command once again to reset cmd_sync()'s changes. */ _client_reset_command(client); if (client->input_pending) client_input(client); } } static void cmd_putscript_finish(struct cmd_putscript_context *ctx) { managesieve_parser_destroy(&ctx->save_parser); io_remove(&ctx->client->io); o_stream_set_flush_callback(ctx->client->output, client_output, ctx->client); if (ctx->save_ctx != NULL) { ctx->client->input_skip_line = TRUE; sieve_storage_save_cancel(&ctx->save_ctx); } } static bool cmd_putscript_continue_cancel(struct client_command_context *cmd) { struct cmd_putscript_context *ctx = cmd->context; size_t size; (void)i_stream_read(ctx->input); (void)i_stream_get_data(ctx->input, &size); i_stream_skip(ctx->input, size); if (cmd->client->input->closed || ctx->input->eof || ctx->input->v_offset == ctx->script_size) { cmd_putscript_finish(ctx); return TRUE; } return FALSE; } static bool cmd_putscript_cancel(struct cmd_putscript_context *ctx, bool skip) { ctx->client->input_skip_line = TRUE; if (!skip) { cmd_putscript_finish(ctx); return TRUE; } /* We have to read the nonsynced literal so we don't treat the uploaded script as commands. */ ctx->client->command_pending = TRUE; ctx->cmd->func = cmd_putscript_continue_cancel; ctx->cmd->context = ctx; return cmd_putscript_continue_cancel(ctx->cmd); } static void cmd_putscript_storage_error(struct cmd_putscript_context *ctx) { struct client_command_context *cmd = ctx->cmd; if (ctx->scriptname == NULL) client_command_storage_error(cmd, "Failed to check script"); else { client_command_storage_error(cmd, "Failed to store script '%s'", ctx->scriptname); } } static bool cmd_putscript_save(struct cmd_putscript_context *ctx) { /* Commit to save only when this is a putscript command */ if (ctx->scriptname == NULL) return TRUE; /* Check commit */ if (sieve_storage_save_commit(&ctx->save_ctx) < 0) { cmd_putscript_storage_error(ctx); return FALSE; } return TRUE; } static void cmd_putscript_finish_script(struct cmd_putscript_context *ctx, struct sieve_script *script) { struct client *client = ctx->client; struct client_command_context *cmd = ctx->cmd; struct sieve_error_handler *ehandler; enum sieve_compile_flags cpflags = SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_UPLOADED; struct sieve_binary *sbin; bool success = TRUE; enum sieve_error error_code; string_t *errors; /* Mark this as an activation when we are replacing the active script */ if (sieve_storage_save_will_activate(ctx->save_ctx)) cpflags |= SIEVE_COMPILE_FLAG_ACTIVATED; /* Prepare error handler */ errors = str_new(default_pool, 1024); ehandler = sieve_strbuf_ehandler_create( client->svinst, errors, TRUE, client->set->managesieve_max_compile_errors); /* Compile */ if (sieve_compile_script(script, ehandler, cpflags, &sbin, &error_code) < 0) { const char *errormsg = NULL, *action; if (error_code != SIEVE_ERROR_NOT_VALID) { errormsg = sieve_script_get_last_error( script, &error_code); if (error_code == SIEVE_ERROR_NONE) errormsg = NULL; } action = (ctx->scriptname != NULL ? t_strdup_printf("store script '%s'", ctx->scriptname) : "check script"); if (errormsg == NULL) { struct event_passthrough *e = client_command_create_finish_event(cmd)-> add_str("error", "Compilation failed")-> add_int("compile_errors", sieve_get_errors(ehandler))-> add_int("compile_warnings", sieve_get_warnings(ehandler)); e_debug(e->event(), "Failed to %s: " "Compilation failed (%u errors, %u warnings)", action, sieve_get_errors(ehandler), sieve_get_warnings(ehandler)); client_send_no(client, str_c(errors)); } else { struct event_passthrough *e = client_command_create_finish_event(cmd)-> add_str("error", errormsg); e_debug(e->event(), "Failed to %s: %s", action, errormsg); client_send_no(client, errormsg); } success = FALSE; } else { sieve_close(&sbin); if (!cmd_putscript_save(ctx)) success = FALSE; } /* Finish up */ cmd_putscript_finish(ctx); /* Report result to user */ if (success) { if (ctx->scriptname != NULL) { client->put_count++; client->put_bytes += ctx->script_size; } else { client->check_count++; client->check_bytes += ctx->script_size; } struct event_passthrough *e = client_command_create_finish_event(cmd)-> add_int("script_size", ctx->script_size)-> add_int("compile_warnings", sieve_get_warnings(ehandler)); if (ctx->scriptname != NULL) { e_debug(e->event(), "Stored script '%s' successfully " "(%u warnings)", ctx->scriptname, sieve_get_warnings(ehandler)); } else { e_debug(e->event(), "Checked script successfully " "(%u warnings)", sieve_get_warnings(ehandler)); } if (sieve_get_warnings(ehandler) > 0) client_send_okresp(client, "WARNINGS", str_c(errors)); else if (ctx->scriptname != NULL) client_send_ok(client, "PUTSCRIPT completed."); else client_send_ok(client, "Script checked successfully."); } sieve_error_handler_unref(&ehandler); str_free(&errors); } static void cmd_putscript_handle_script(struct cmd_putscript_context *ctx) { struct client_command_context *cmd = ctx->cmd; struct sieve_script *script; /* Obtain script object for uploaded script */ script = sieve_storage_save_get_tempscript(ctx->save_ctx); /* Check result */ if (script == NULL) { cmd_putscript_storage_error(ctx); cmd_putscript_finish(ctx); return; } /* If quoted string, the size was not known until now */ if (!ctx->script_size_valid) { if (sieve_script_get_size(script, &ctx->script_size) < 0) { cmd_putscript_storage_error(ctx); cmd_putscript_finish(ctx); return; } ctx->script_size_valid = TRUE; /* Check quota; max size is already checked */ if (ctx->scriptname != NULL && !managesieve_quota_check_all(cmd, ctx->scriptname, ctx->script_size)) { cmd_putscript_finish(ctx); return; } } /* Try to compile and store the script */ T_BEGIN { cmd_putscript_finish_script(ctx, script); } T_END; } static bool cmd_putscript_finish_parsing(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_putscript_context *ctx = cmd->context; const struct managesieve_arg *args; int ret; /* if error occurs, the CRLF is already read. */ client->input_skip_line = FALSE; /*