Hello community, here is the log from the commit of package kopano for openSUSE:Factory checked in at 2018-07-12 09:20:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kopano (Old) and /work/SRC/openSUSE:Factory/.kopano.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kopano" Thu Jul 12 09:20:01 2018 rev:14 rq:622046 version:8.6.2.25 Changes: -------- --- /work/SRC/openSUSE:Factory/kopano/kopano.changes 2018-05-30 12:29:58.432554434 +0200 +++ /work/SRC/openSUSE:Factory/.kopano.new/kopano.changes 2018-07-12 09:21:42.202631556 +0200 @@ -1,0 +2,14 @@ +Tue Jul 3 11:52:45 UTC 2018 - jeng...@inai.de + +- Update to new upstream snapshot 8.6.2.25 + * Fixes: + * ical: handle double quotes in Content-Type header + * Enhancements: + * client: now emits warnings about own incomplete PR_RULES_DATA + processing + * inetmapi: now emits a warning when runtime vmime is too old + * server: fewer stat calls to the attachment backend + * Changes: + * dagent: default for log_timestamp changed to "yes" + +------------------------------------------------------------------- Old: ---- kopanocore-8.6.1.99.tar.xz New: ---- kopanocore-8.6.2.25.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kopano.spec ++++++ --- /var/tmp/diff_new_pack.wxeKmr/_old 2018-07-12 09:21:44.710635065 +0200 +++ /var/tmp/diff_new_pack.wxeKmr/_new 2018-07-12 09:21:44.710635065 +0200 @@ -17,10 +17,10 @@ # -%define version_unconverted 8.6.1.99 +%define version_unconverted 8.6.2.25 Name: kopano -Version: 8.6.1.99 +Version: 8.6.2.25 Release: 0 Summary: Groupware server suite License: AGPL-3.0-only @@ -322,11 +322,11 @@ Group: Productivity/Networking/Email/Servers Requires: kopano-common >= %version %if 0%{?prefer_python3} -Requires: python3-flask +Requires: python3-Flask Requires: python3-kopano = %version Requires: python3-sleekxmpp %else -Requires: python-flask +Requires: python-Flask Requires: python-sleekxmpp Requires: python2-kopano = %version %endif @@ -670,19 +670,6 @@ rm -Rf "$b/%python3_sitelib/$i"* done %endif -# no flask in opensuse -rm -Rf \ - %buildroot/%_initddir/kopano-presence \ - %buildroot/%_sbindir/kopano-presence \ - %buildroot/%_prefix/lib/systemd/system/kopano-presence.service \ - %buildroot/%_docdir/kopano/example-config/presence.cfg \ -%if 0%{?with_python3} - %buildroot/%python3_sitelib/kopano_presence* \ -%endif -%if 0%{?with_python2} - %buildroot/%python_sitelib/kopano_presence* \ -%endif - %nil # distro-specifics %if 0%{?centos_version} == 600 @@ -1340,7 +1327,6 @@ %dir %_docdir/kopano/example-config %_docdir/kopano/example-config/monitor.cfg -%if 0 %files presence %defattr(-,root,root) %if 0%{?centos_version} == 600 @@ -1362,7 +1348,6 @@ %python_sitelib/kopano_presence/ %python_sitelib/kopano_presence-*.egg-info %endif -%endif %files search %defattr(-,root,root) @@ -1520,6 +1505,7 @@ %_mandir/man*/kopano-storeadm.* %dir %_libexecdir/kopano %_libexecdir/kopano/mapitime +%_libexecdir/kopano/kscriptrun %if 0%{?prefer_python3} %python3_sitelib/kopano_cli/ %python3_sitelib/kopano_cli*.egg-info ++++++ PKGBUILD ++++++ --- /var/tmp/diff_new_pack.wxeKmr/_old 2018-07-12 09:21:44.734635099 +0200 +++ /var/tmp/diff_new_pack.wxeKmr/_new 2018-07-12 09:21:44.734635099 +0200 @@ -1,5 +1,5 @@ pkgname=kopano -pkgver=8.6.1.99 +pkgver=8.6.2.25 pkgrel=0 pkgdesc='Kopano' arch=('x86_64') ++++++ _service ++++++ --- /var/tmp/diff_new_pack.wxeKmr/_old 2018-07-12 09:21:44.750635121 +0200 +++ /var/tmp/diff_new_pack.wxeKmr/_new 2018-07-12 09:21:44.750635121 +0200 @@ -3,8 +3,8 @@ <param name="scm">git</param> <param name="url">https://stash.kopano.io/scm/kc/kopanocore.git</param> <param name="revision">kc-8.6.x</param> - <param name="parent-tag">kopanocore-8.6.1</param> - <param name="versionformat">8.6.1.@TAG_OFFSET@</param> + <param name="parent-tag">kopanocore-8.6.2</param> + <param name="versionformat">8.6.2.@TAG_OFFSET@</param> <!-- Regex used to rewrite the version which is applied after versionformat [kopanocore-8.5.80] and after the implicit ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.wxeKmr/_old 2018-07-12 09:21:44.762635139 +0200 +++ /var/tmp/diff_new_pack.wxeKmr/_new 2018-07-12 09:21:44.766635144 +0200 @@ -1,4 +1,4 @@ -kopano (8.5.90.18-0) unstable; urgency=low +kopano (8.6.2.25-0) unstable; urgency=low * Current release. ++++++ kopano.dsc ++++++ --- /var/tmp/diff_new_pack.wxeKmr/_old 2018-07-12 09:21:45.334635939 +0200 +++ /var/tmp/diff_new_pack.wxeKmr/_new 2018-07-12 09:21:45.334635939 +0200 @@ -1,7 +1,7 @@ Format: 1.0 Source: kopano Architecture: any all -Version: 8.6.1.99-0 +Version: 8.6.2.25-0 DEBTRANSFORM-RELEASE: 1 Maintainer: Kopano Development <developm...@kopano.io> Homepage: https://kopano.com ++++++ kopanocore-8.6.1.99.tar.xz -> kopanocore-8.6.2.25.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/ECtools/dbadm.cpp new/kopanocore-8.6.2.25/ECtools/dbadm.cpp --- old/kopanocore-8.6.1.99/ECtools/dbadm.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/ECtools/dbadm.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -488,6 +488,8 @@ cfg->AddSetting("log_method", "file"); cfg->AddSetting("log_file", "-"); ec_log_set(CreateLogger(cfg, argv[0], "kopano-dbadm", false)); + if (!ec_log_get()->Log(EC_LOGLEVEL_INFO)) + ec_log_get()->SetLoglevel(EC_LOGLEVEL_INFO); auto db = std::make_shared<KDatabase>(); auto ret = db->Connect(cfg, true, 0, 0); if (ret != erSuccess) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/ECtools/scriptrun.cpp new/kopanocore-8.6.2.25/ECtools/scriptrun.cpp --- old/kopanocore-8.6.1.99/ECtools/scriptrun.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/kopanocore-8.6.2.25/ECtools/scriptrun.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright 2018+, Kopano and its licensors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero 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 <http://www.gnu.org/licenses/>. + */ +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <cerrno> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <sys/stat.h> +#include <dirent.h> +#include <unistd.h> +#include <kopano/platform.h> +#include <kopano/UnixUtil.h> + +static bool ignore_name(const char *n) +{ + size_t len = strlen(n); + if (len >= 1 && n[0] == '#') + return true; + if (len >= 1 && n[len-1] == '~') + return true; + if (len >= 4 && strcmp(&n[len-4], ".bak") == 0) + return true; + if (len >= 4 && strcmp(&n[len-4], ".old") == 0) + return true; + if (len >= 7 && strcmp(&n[len-7], ".rpmnew") == 0) + return true; + if (len >= 8 && strcmp(&n[len-8], ".rpmorig") == 0) + return true; + return false; +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "One or more directories need to be specified where to scan for, and execute, scripts.\n"); + return EXIT_FAILURE; + } + + std::map<std::string, std::string> scripts; /* base name -> full path */ + for (int i = 1; i < argc; ++i) { + std::unique_ptr<DIR, KC::fs_deleter> dh(opendir(argv[i])); + if (dh == nullptr) { + fprintf(stderr, "Could not process %s: %s", argv[i], strerror(errno)); + continue; + } + struct dirent *de; + while ((de = readdir(dh.get())) != nullptr) { + if (ignore_name(de->d_name)) { + printf("Ignoring \"%s/%s\"\n", argv[i], de->d_name); + continue; + } + struct stat sb; + auto ret = fstatat(dirfd(dh.get()), de->d_name, &sb, 0); + if (ret < 0) + continue; + if (S_ISREG(sb.st_mode)) + scripts[de->d_name] = argv[i] + std::string{"/"} + de->d_name; + else + scripts.erase(de->d_name); + } + } + for (const auto &pair : scripts) { + printf("Executing \"%s\"...\n", pair.second.c_str()); + auto ret = vfork(); + if (ret == 0) { + execl(pair.second.c_str(), pair.first.c_str(), nullptr); + _exit(EXIT_FAILURE); + } + wait(nullptr); + } + return EXIT_SUCCESS; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/Makefile.am new/kopanocore-8.6.2.25/Makefile.am --- old/kopanocore-8.6.1.99/Makefile.am 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/Makefile.am 2018-07-02 15:42:42.000000000 +0200 @@ -63,7 +63,7 @@ if HAVE_TIDY noinst_PROGRAMS += rosie-test endif -pkglibexec_PROGRAMS = mapitime +pkglibexec_PROGRAMS = kscriptrun mapitime # @@ -804,6 +804,7 @@ # # test programs # +kscriptrun_SOURCES = ECtools/scriptrun.cpp mapitime_SOURCES = ECtools/mapitime.cpp mapitime_LDADD = ${clock_LIBS} libmapi.la libkcmapi.la libkcutil.la \ ${curl_LIBS} ${icu_uc_LIBS} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/RELNOTES.txt new/kopanocore-8.6.2.25/RELNOTES.txt --- old/kopanocore-8.6.1.99/RELNOTES.txt 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/RELNOTES.txt 2018-07-02 15:42:42.000000000 +0200 @@ -1,14 +1,32 @@ -8.6.x +8.6.3 ===== -Includes changes until including 8.5.9. +Fixes: +* ical: hopefully cure uncaught exception on OpenBSD +* ical: handle double quotes in Content-Type header [KC-1198] +Enhancements: +* client: now emits warnings about own incomplete PR_RULES_DATA processing +* inetmapi: now emits a warning when runtime vmime is too old [KC-1124] +* server: fewer stat calls to the attachment backend [KC-1192] +Changes: +* dagent: default for log_timestamp changed to "yes" [KC-1152] + + +8.6.2 (2018-06-07) +================== +Includes changes until including 8.5.z. Fixes: * installer: remove duplicate defaults from sample config * icalmapi: allow RRULE with DTSTART having zulu-marking [KC-414, KC-811] * icalmapi: do not mark timestamp as UTC when we explicitly give a timezone [KC-920, KC-1018] * icalmapi: do not write empty fields to VCF files [KW-2503] +* scripts: follow symbolic links when running user/group/company scripts, + and run them in lexicographic order [KC-1171,KC-1172] +* common: force Unicode for internal string translations [KC-1140] +* common: remove bin2hex warning [KC-1178] Enhancements: * libicalmapi: allow some properties to be missing when serializing ADR +* kopano-dbadm: default to a loglevel so all dbadm messages get shown [KC-1167] 8.6.1 (2018-04-05) @@ -42,6 +60,12 @@ user/company [KC-795] +8.5.z +===== +Enhancements: +* spooler: allow hard termination via repeated Ctrl-C + + 8.5.9 (2018-05-16) ================== Changes: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/caldav/CalDAV.cpp new/kopanocore-8.6.2.25/caldav/CalDAV.cpp --- old/kopanocore-8.6.1.99/caldav/CalDAV.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/caldav/CalDAV.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -305,9 +305,7 @@ kc_perror("Messaging API could not be initialized", hr); goto exit; } - - if (g_bThreads) - mainthread = pthread_self(); + mainthread = pthread_self(); ec_log(EC_LOGLEVEL_ALWAYS, "Starting kopano-ical version " PROJECT_VERSION " (pid %d)", getpid()); hr = HrProcessConnections(ulListenCalDAV, ulListenCalDAVs); if (hr != hrSuccess) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/caldav/Http.cpp new/kopanocore-8.6.2.25/caldav/Http.cpp --- old/kopanocore-8.6.1.99/caldav/Http.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/caldav/Http.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -179,6 +179,36 @@ return hr; } +/* deduplicate in master */ +static std::string fix_content_type_charset(const char *in, const char *dfl) +{ + const char *cset = dfl, *cset_end = dfl + strlen(dfl); + + while (!isspace(*in) && *in != '\0') /* skip type */ + ++in; + while (*in != '\0') { + while (isspace(*in)) + ++in; /* skip possible whitespace before ';' */ + if (*in == ';') { + ++in; + while (isspace(*in)) /* skip WS after ';' */ + ++in; + } + if (strncasecmp(in, "charset=", 8) == 0) { + in += 8; + cset = in; + while (!isspace(*in) && *in != ';' && *in != '\0') + ++in; /* skip value */ + cset_end = in; + continue; + /* continue parsing for more charset= values */ + } + while (!isspace(*in) && *in != ';' && *in != '\0') + ++in; + } + return std::string(cset, cset_end - cset); +} + /** * Parse the http headers * @return HRESULT @@ -210,8 +240,8 @@ // find the content-type // Content-Type: text/xml;charset=UTF-8 hr = HrGetHeaderValue("Content-Type", &m_strCharSet); - if (hr == hrSuccess && m_strCharSet.find("charset") != std::string::npos) - m_strCharSet = m_strCharSet.substr(m_strCharSet.find("charset")+ strlen("charset") + 1, m_strCharSet.length()); + if (hr == hrSuccess) + m_strCharSet = fix_content_type_charset(m_strCharSet.c_str(), m_lpConfig->GetSetting("default_charset")); else m_strCharSet = m_lpConfig->GetSetting("default_charset"); // really should be UTF-8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/common/ECGetText.cpp new/kopanocore-8.6.2.25/common/ECGetText.cpp --- old/kopanocore-8.6.1.99/common/ECGetText.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/common/ECGetText.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -105,6 +105,16 @@ */ LPWSTR kopano_dcgettext_wide(const char *domainname, const char *msgid) { + static bool init; + if (!init) { + /* + * Avoid gettext doing the downconversion to LC_CTYPE and + * killing all the Unicode characters before we had a chance of + * seeing them. + */ + bind_textdomain_codeset("kopano", "utf-8"); + init = true; + } const char *lpsz = msgid; lpsz = dcgettext(domainname, msgid, LC_MESSAGES); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/common/include/kopano/charset/convert.h new/kopanocore-8.6.2.25/common/include/kopano/charset/convert.h --- old/kopanocore-8.6.1.99/common/include/kopano/charset/convert.h 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/common/include/kopano/charset/convert.h 2018-07-02 15:42:42.000000000 +0200 @@ -34,7 +34,7 @@ /** * @brief Exception class */ -class convert_exception : public std::runtime_error { +class _kc_export_throw convert_exception : public std::runtime_error { public: enum exception_type { eUnknownCharset, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/common/stringutil.cpp new/kopanocore-8.6.2.25/common/stringutil.cpp --- old/kopanocore-8.6.1.99/common/stringutil.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/common/stringutil.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -287,10 +287,6 @@ { if (vinput == nullptr) return ""; - if (inLength > 2048) - ec_log_warn("Unexpectedly large bin2hex call, %zu bytes", inLength); - else if (inLength > 64) - ec_log_debug("Unexpectedly large bin2hex call, %zu bytes", inLength); static constexpr const char digits[] = "0123456789ABCDEF"; auto input = static_cast<const char *>(vinput); std::string buffer; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/configure.ac new/kopanocore-8.6.2.25/configure.ac --- old/kopanocore-8.6.1.99/configure.ac 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/configure.ac 2018-07-02 15:42:42.000000000 +0200 @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT([kopano], [8.6.1], [developm...@kopano.io]) +AC_INIT([kopano], [8.6.2], [developm...@kopano.io]) dnl ABI tags are used to prevent inadvertent mixing of wildly different dnl versions of KC components without knowing it. @@ -213,6 +213,8 @@ AS_IF([test -z "$tmpfilesdir"], [tmpfilesdir='${prefix}/lib/tmpfiles.d']) ]) AC_SUBST([tmpfilesdir]) +PKGLIBEXECDIR="$libexecdir/kopano" +AC_SUBST([PKGLIBEXECDIR]) dnl Not all files will be installed to ${prefix}, so we need to cheat a bit dnl to make "distcheck" succeed. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/doc/kopano-dagent.cfg.5 new/kopanocore-8.6.2.25/doc/kopano-dagent.cfg.5 --- old/kopanocore-8.6.1.99/doc/kopano-dagent.cfg.5 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/doc/kopano-dagent.cfg.5 2018-07-02 15:42:42.000000000 +0200 @@ -164,8 +164,7 @@ .PP Specify whether to prefix each log line with a timestamp in \*(Aqfile\*(Aq logging mode. .PP -Default: -\fI1\fR +Default: \fIyes\fP .SS log_buffer_size .PP Buffer logging in what sized blocks. The special value 0 selects line buffering. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/gateway/Gateway.cpp new/kopanocore-8.6.2.25/gateway/Gateway.cpp --- old/kopanocore-8.6.1.99/gateway/Gateway.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/gateway/Gateway.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -464,10 +464,7 @@ bThreads = true; g_lpLogger->SetLogprefix(LP_TID); } - - if (bThreads) - mainthread = pthread_self(); - + mainthread = pthread_self(); if (!szPath) szPath = g_lpConfig->GetSetting("server_socket"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/inetmapi/VMIMEToMAPI.cpp new/kopanocore-8.6.2.25/inetmapi/VMIMEToMAPI.cpp --- old/kopanocore-8.6.1.99/inetmapi/VMIMEToMAPI.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/inetmapi/VMIMEToMAPI.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -2747,14 +2747,15 @@ /** * Determine character set from a possibly broken Content-Type value. * @in: string in the form of m{^text/foo\s*(;?\s*key=value)*} + * @cset: the default return value if no charset= is to be found * * Attempt to extract the character set parameter, e.g. from a HTML <meta> tag, * or from a Content-Type MIME header (though we do not use it for MIME headers * currently). */ -static std::string fix_content_type_charset(const char *in) +static std::string fix_content_type_charset(const char *in, const char *cset) { - const char *cset = im_charset_unspec, *cset_end = im_charset_unspec; + const char *cset_end = cset + strlen(cset); while (!isspace(*in) && *in != '\0') /* skip type */ ++in; @@ -2851,7 +2852,7 @@ lpValue = xmlGetProp(lpNode, (const xmlChar*)"content"); if (lpValue) { ec_log_debug("HTML4 meta tag found: charset=\"%s\"", lpValue); - charset = fix_content_type_charset(reinterpret_cast<const char *>(lpValue)); + charset = fix_content_type_charset(reinterpret_cast<const char *>(lpValue), ""); } break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/inetmapi/inetmapi.cpp new/kopanocore-8.6.2.25/inetmapi/inetmapi.cpp --- old/kopanocore-8.6.1.99/inetmapi/inetmapi.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/inetmapi/inetmapi.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -148,6 +148,17 @@ dopt.ascii_upgrade = "us-ascii"; } InitializeVMime(); + + static bool vmime_once; + if (!vmime_once) { + vmime_once = true; + vmime::mailbox mbox; + mbox.parse("=?UTF-8?Q?a=c2=a0b_=28c@d.e=29?= <f@g.h>"); + if (*mbox.getName().getWholeBuffer().c_str() == '\0') + ec_log_notice("Detected old libvmime (< 0.9.2.42). " + "Consider having it upgraded to be able to parse more broken mails (KC-1124)."); + } + // fill mapi object from buffer return VMIMEToMAPI(lpAddrBook, dopt).convertVMIMEToMAPI(input, lpMessage); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/linux/sysconfig.txt new/kopanocore-8.6.2.25/installer/linux/sysconfig.txt --- old/kopanocore-8.6.1.99/installer/linux/sysconfig.txt 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/linux/sysconfig.txt 2018-07-02 15:42:42.000000000 +0200 @@ -1,3 +1,12 @@ +# +# THESE DEFINITIONS ONLY APPLY WHEN +# kopano-server runs /etc/kopano/*scripts*. +# +# IT DOES NOT GET USED IN ANY OTHER WAY, +# ESPECIALLY NOT WHEN ISSUING kopano-storeadm FROM A SHELL. +# + + ## Path: Network/Mail/Kopano ## Description: Kopano service locale ## Type: string @@ -26,4 +35,7 @@ # and therefore affects the emitted language, e.g. folder names for new # message stores. # +# If this is empty, it defaults to the LC_MESSAGES value of kopano-server. +# (Cf. `systemctl show kopano-server`) +# KOPANO_USERSCRIPT_LOCALE="en_US.UTF-8" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/companies_common.sh new/kopanocore-8.6.2.25/installer/userscripts/companies_common.sh --- old/kopanocore-8.6.1.99/installer/userscripts/companies_common.sh 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/companies_common.sh 2018-07-02 15:42:42.000000000 +0200 @@ -21,5 +21,4 @@ echo "KOPANO_COMPANY and KOPANO_COMPANYID is not set." exit 1 fi - -find ${KOPANO_COMPANY_SCRIPTS} -maxdepth 1 -type f -perm -u=x ! -name \*~ ! -name \#\* ! -name \*.rpm\* ! -name \*.bak ! -name \*.old -exec {} \; +exec "$PKGLIBEXECDIR/kscriptrun" "$KOPANO_COMPANY_SCRIPTS" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/createcompany.in new/kopanocore-8.6.2.25/installer/userscripts/createcompany.in --- old/kopanocore-8.6.1.99/installer/userscripts/createcompany.in 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/createcompany.in 2018-07-02 15:42:42.000000000 +0200 @@ -15,6 +15,6 @@ # Used on Debian in place of sysconfig . @sysconfdir@/default/kopano fi - +PKGLIBEXECDIR=@PKGLIBEXECDIR@ KOPANO_COMPANY_SCRIPTS=@USERSCRIPTDIR@/createcompany.d . @USERSCRIPTDIR@/companies_common.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/creategroup.in new/kopanocore-8.6.2.25/installer/userscripts/creategroup.in --- old/kopanocore-8.6.1.99/installer/userscripts/creategroup.in 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/creategroup.in 2018-07-02 15:42:42.000000000 +0200 @@ -14,6 +14,6 @@ elif [ -f @sysconfdir@/default/kopano ]; then . @sysconfdir@/default/kopano fi - +PKGLIBEXECDIR=@PKGLIBEXECDIR@ KOPANO_GROUP_SCRIPTS=@USERSCRIPTDIR@/creategroup.d . @USERSCRIPTDIR@/groups_common.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/createuser.in new/kopanocore-8.6.2.25/installer/userscripts/createuser.in --- old/kopanocore-8.6.1.99/installer/userscripts/createuser.in 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/createuser.in 2018-07-02 15:42:42.000000000 +0200 @@ -14,6 +14,6 @@ elif [ -f @sysconfdir@/default/kopano ]; then . @sysconfdir@/default/kopano fi - +PKGLIBEXECDIR=@PKGLIBEXECDIR@ KOPANO_USER_SCRIPTS=@USERSCRIPTDIR@/createuser.d . @USERSCRIPTDIR@/users_common.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/deletecompany.in new/kopanocore-8.6.2.25/installer/userscripts/deletecompany.in --- old/kopanocore-8.6.1.99/installer/userscripts/deletecompany.in 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/deletecompany.in 2018-07-02 15:42:42.000000000 +0200 @@ -14,6 +14,6 @@ elif [ -f @sysconfdir@/default/kopano ]; then . @sysconfdir@/default/kopano fi - +PKGLIBEXECDIR=@PKGLIBEXECDIR@ KOPANO_COMPANY_SCRIPTS=@USERSCRIPTDIR@/deletecompany.d . @USERSCRIPTDIR@/companies_common.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/deletegroup.in new/kopanocore-8.6.2.25/installer/userscripts/deletegroup.in --- old/kopanocore-8.6.1.99/installer/userscripts/deletegroup.in 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/deletegroup.in 2018-07-02 15:42:42.000000000 +0200 @@ -14,6 +14,6 @@ elif [ -f @sysconfdir@/default/kopano ]; then . @sysconfdir@/default/kopano fi - +PKGLIBEXECDIR=@PKGLIBEXECDIR@ KOPANO_GROUP_SCRIPTS=@USERSCRIPTDIR@/deletegroup.d . @USERSCRIPTDIR@/groups_common.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/deleteuser.in new/kopanocore-8.6.2.25/installer/userscripts/deleteuser.in --- old/kopanocore-8.6.1.99/installer/userscripts/deleteuser.in 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/deleteuser.in 2018-07-02 15:42:42.000000000 +0200 @@ -14,6 +14,6 @@ elif [ -f @sysconfdir@/default/kopano ]; then . @sysconfdir@/default/kopano fi - +PKGLIBEXECDIR=@PKGLIBEXECDIR@ KOPANO_USER_SCRIPTS=@USERSCRIPTDIR@/deleteuser.d . @USERSCRIPTDIR@/users_common.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/groups_common.sh new/kopanocore-8.6.2.25/installer/userscripts/groups_common.sh --- old/kopanocore-8.6.1.99/installer/userscripts/groups_common.sh 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/groups_common.sh 2018-07-02 15:42:42.000000000 +0200 @@ -21,5 +21,4 @@ echo "KOPANO_GROUP and KOPANO_GROUPID is not set." exit 1 fi - -find ${KOPANO_GROUP_SCRIPTS} -maxdepth 1 -type f -perm -u=x ! -name \*~ ! -name \#\* ! -name \*.rpm\* ! -name \*.bak ! -name \*.old -exec {} \; +exec "$PKGLIBEXECDIR/kscriptrun" "$KOPANO_GROUP_SCRIPTS" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/installer/userscripts/users_common.sh new/kopanocore-8.6.2.25/installer/userscripts/users_common.sh --- old/kopanocore-8.6.1.99/installer/userscripts/users_common.sh 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/installer/userscripts/users_common.sh 2018-07-02 15:42:42.000000000 +0200 @@ -21,7 +21,4 @@ echo "KOPANO_USER and KOPANO_STOREGUID is not set." exit 1 fi - -# Find cannot cope with unreadable cwd -cd "$KOPANO_USER_SCRIPTS" -find "${KOPANO_USER_SCRIPTS}" -maxdepth 1 -type f -perm -u=x ! -name \*~ ! -name \#\* ! -name \*.rpm\* ! -name \*.bak ! -name \*.old -exec {} \; +exec "$PKGLIBEXECDIR/kscriptrun" "$KOPANO_USER_SCRIPTS" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/libicalmapi/vconverter.cpp new/kopanocore-8.6.2.25/libicalmapi/vconverter.cpp --- old/kopanocore-8.6.1.99/libicalmapi/vconverter.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/libicalmapi/vconverter.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -1560,7 +1560,10 @@ ittStamp = icaltime_from_timet_with_zone(tStamp, bDateOnly, icaltimezone_get_utc_timezone()); } - icalproperty_set_value(lpicProp, icalvalue_new_datetime(ittStamp)); + if (bDateOnly) + icalproperty_set_value(lpicProp, icalvalue_new_date(ittStamp)); + else + icalproperty_set_value(lpicProp, icalvalue_new_datetime(ittStamp)); // only allowed to add timezone information on non-allday events if (lpicTZinfo && !bDateOnly) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/provider/client/ECExchangeModifyTable.cpp new/kopanocore-8.6.2.25/provider/client/ECExchangeModifyTable.cpp --- old/kopanocore-8.6.1.99/provider/client/ECExchangeModifyTable.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/provider/client/ECExchangeModifyTable.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -19,6 +19,7 @@ #include <memory> #include <new> #include <utility> +#include <kopano/ECLogger.h> #include <kopano/memory.hpp> #include <kopano/scope.hpp> #include "WSUtil.h" @@ -144,8 +145,14 @@ hr = lpRulesData->Read(szXML.get(), statRulesData.cbSize.LowPart, &ulRead); if (hr != hrSuccess || ulRead == 0) goto empty; - szXML[statRulesData.cbSize.LowPart] = 0; + szXML[ulRead] = 0; + if (ulRead < statRulesData.cbSize.LowPart) + ec_log_notice("Bug: PR_RULES_DATA: read only %u/%u bytes", + ulRead, statRulesData.cbSize.LowPart); hr = HrDeserializeTable(szXML.get(), ecTable, &ulRuleId); + if (hr == MAPI_E_CORRUPT_DATA) + ec_log_debug("PR_RULES_DATA [%u/%u bytes]: rejected due to garbage or truncation", + ulRead, statRulesData.cbSize.LowPart); /* * If the data was corrupted, or imported from * Exchange, it is incompatible, so return an diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/provider/libserver/ECAttachmentStorage.cpp new/kopanocore-8.6.2.25/provider/libserver/ECAttachmentStorage.cpp --- old/kopanocore-8.6.1.99/provider/libserver/ECAttachmentStorage.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/provider/libserver/ECAttachmentStorage.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -1166,7 +1166,7 @@ ECRESULT er = erSuccess; string filename; unsigned char *lpData = NULL; - bool bCompressed = false; + bool bCompressed = m_bFileCompression; gzFile gzfp = NULL; *lpiSize = 0; @@ -1177,8 +1177,8 @@ ec_log_err("K-1561: cannot open attachment \"%s\": %s", filename.c_str(), strerror(errno)); return KCERR_NO_ACCESS; } else if (fd < 0) { - /* Not found, try gzip */ - bCompressed = true; + /* Switch between compressed↔uncompressed, and try again. */ + bCompressed = !bCompressed; filename = CreateAttachmentFilename(ulInstanceId, bCompressed); fd = open(filename.c_str(), O_RDONLY); if (fd < 0) { @@ -1187,15 +1187,8 @@ } } my_readahead(fd); - - /* - * CreateAttachmentFilename Already checked if we are working with a compressed or uncompressed file, - * no need to perform retries when our first guess (which is based on CreateAttachmentFilename) fails. - */ if (bCompressed) { unsigned char *temp = NULL; - - /* Compressed attachment */ gzfp = gzdopen(fd, "rb"); if (!gzfp) { // do not use KCERR_NOT_FOUND: the file is already open so it exists diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/spooler/DAgent.cpp new/kopanocore-8.6.2.25/spooler/DAgent.cpp --- old/kopanocore-8.6.1.99/spooler/DAgent.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/spooler/DAgent.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -3370,7 +3370,7 @@ {"log_method", "file", CONFIGSETTING_NONEMPTY}, {"log_file", "-", CONFIGSETTING_NONEMPTY}, {"log_level", "3", CONFIGSETTING_NONEMPTY | CONFIGSETTING_RELOADABLE}, - { "log_timestamp", "0" }, + {"log_timestamp", "yes"}, { "log_buffer_size", "0" }, { "server_socket", "default:" }, { "sslkey_file", "" }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/spooler/Spooler.cpp new/kopanocore-8.6.2.25/spooler/Spooler.cpp --- old/kopanocore-8.6.1.99/spooler/Spooler.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/spooler/Spooler.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -732,14 +732,13 @@ ULONG ulCount = 0, ulThreads = 0; while (ulCount < 60) { - if ((ulCount % 5) == 0) { - ulThreads = mapSendData.size(); + ulThreads = mapSendData.size(); + if (ulThreads == 0) + break; + if ((ulCount % 5) == 0) ec_log_warn("Still waiting for %d thread(s) to exit.", ulThreads); - } if (lpSpooler != nullptr) CleanFinishedMessages(lpAdminSession, lpSpooler); - if (mapSendData.size() == 0) - break; Sleep(1000); ++ulCount; @@ -783,6 +782,7 @@ bQuit = true; // Trigger condition so we force wakeup the queue thread hCondMessagesWaiting.notify_one(); + ec_log_info("User requested graceful shutdown. To force quit, reissue the request."); break; } @@ -1078,11 +1078,11 @@ act.sa_flags = SA_ONSTACK | SA_RESTART; sigemptyset(&act.sa_mask); sigaction(SIGHUP, &act, nullptr); - sigaction(SIGINT, &act, nullptr); - sigaction(SIGTERM, &act, nullptr); sigaction(SIGCHLD, &act, nullptr); sigaction(SIGUSR2, &act, nullptr); - + act.sa_flags = SA_ONSTACK | SA_RESETHAND; + sigaction(SIGINT, &act, nullptr); + sigaction(SIGTERM, &act, nullptr); } st.ss_sp = malloc(65536); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/spooler/rules.cpp new/kopanocore-8.6.2.25/spooler/rules.cpp --- old/kopanocore-8.6.1.99/spooler/rules.cpp 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/spooler/rules.cpp 2018-07-02 15:42:42.000000000 +0200 @@ -541,7 +541,7 @@ std::wstring strRuleName, strRuleType, strRuleAddress; hr = HrGetAddress(lpAdrBook, lpRuleRecipients->aEntries[i].rgPropVals, lpRuleRecipients->aEntries[i].cValues, PR_ENTRYID, - CHANGE_PROP_TYPE(PR_DISPLAY_NAME, PT_UNSPECIFIED), CHANGE_PROP_TYPE(PR_ADDRTYPE, PT_UNSPECIFIED), CHANGE_PROP_TYPE(PR_SMTP_ADDRESS, PT_UNSPECIFIED), + CHANGE_PROP_TYPE(PR_DISPLAY_NAME, PT_UNSPECIFIED), CHANGE_PROP_TYPE(PR_ADDRTYPE, PT_UNSPECIFIED), CHANGE_PROP_TYPE(PR_EMAIL_ADDRESS, PT_UNSPECIFIED), strRuleName, strRuleType, strRuleAddress); if (hr != hrSuccess) return kc_perror("Unable to get rule address", hr); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/swig/python/kopano/kopano/compat.py new/kopanocore-8.6.2.25/swig/python/kopano/kopano/compat.py --- old/kopanocore-8.6.1.99/swig/python/kopano/kopano/compat.py 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/swig/python/kopano/kopano/compat.py 2018-07-02 15:42:42.000000000 +0200 @@ -84,7 +84,7 @@ return isinstance(s, (str, unicode)) def pickle_load(f): - return pickle.loads(f) + return pickle.load(f) def pickle_loads(s): return pickle.loads(s) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/swig/python/kopano/kopano/item.py new/kopanocore-8.6.2.25/swig/python/kopano/kopano/item.py --- old/kopanocore-8.6.1.99/swig/python/kopano/kopano/item.py 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/swig/python/kopano/kopano/item.py 2018-07-02 15:42:42.000000000 +0200 @@ -35,7 +35,7 @@ ) from MAPI.Defs import ( - HrGetOneProp, CHANGE_PROP_TYPE, + HrGetOneProp, CHANGE_PROP_TYPE, bin2hex ) from MAPI.Struct import ( @@ -139,7 +139,8 @@ @functools.wraps(func) def _func(*args, **kwargs): ret = func(*args, **kwargs) - self.mapiobj.SetProps([SPropValue(self.proptag, self)]) + data = [_unicode(x) for x in self] + self.mapiobj.SetProps([SPropValue(self.proptag, data)]) self.mapiobj.SaveChanges(KEEP_OPEN_READWRITE) return ret return _func @@ -440,7 +441,8 @@ def categories(self, value): proptag = self.mapiobj.GetIDsFromNames([NAMED_PROP_CATEGORY], MAPI_CREATE)[0] proptag = CHANGE_PROP_TYPE(proptag, PT_MV_UNICODE) - self.mapiobj.SetProps([SPropValue(proptag, list(value))]) + data = [_unicode(x) for x in value] + self.mapiobj.SetProps([SPropValue(proptag, data)]) self.mapiobj.SaveChanges(KEEP_OPEN_READWRITE) @property @@ -994,7 +996,7 @@ @to.setter def to(self, addrs): if _is_str(addrs): - addrs = _unicode(addrs).split(';') + addrs = [x.strip() for x in _unicode(addrs).split(';')] elif isinstance(addrs, _user.User): addrs = [addrs] names = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/swig/python/kopano/kopano/log.py new/kopanocore-8.6.2.25/swig/python/kopano/kopano/log.py --- old/kopanocore-8.6.1.99/swig/python/kopano/kopano/log.py 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/swig/python/kopano/kopano/log.py 2018-07-02 15:42:42.000000000 +0200 @@ -67,7 +67,8 @@ ch = logging.StreamHandler(sys.stdout) ch.setLevel(log_level) ch.setFormatter(formatter) - if stdout or (options and options.foreground): + if stdout or (options and options.foreground and \ + (log_method, log_file) != ('file', '-')): logger.addHandler(ch) logger.setLevel(log_level) return logger diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kopanocore-8.6.1.99/swig/python/kopano/kopano/utils.py new/kopanocore-8.6.2.25/swig/python/kopano/kopano/utils.py --- old/kopanocore-8.6.1.99/swig/python/kopano/kopano/utils.py 2018-05-16 16:54:06.000000000 +0200 +++ new/kopanocore-8.6.2.25/swig/python/kopano/kopano/utils.py 2018-07-02 15:42:42.000000000 +0200 @@ -182,6 +182,8 @@ return 0 timezone, _, timezonedst, _, dstendmonth, dstendweek, dstendhour, _, _, _, dststartmonth, dststartweek, dststarthour, _, _ = struct.unpack('<lllllHHllHlHHlH', tz_data) + if dststartmonth == 0: + return timezone dst = _in_dst(date, dststartmonth, dststartweek, dststarthour, dstendmonth, dstendweek, dstendhour)